You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Apache CSV Parser读取Excel(.xlsx) Multipartfile?现有方案失效

问题根因

你对CSVFormat.EXCEL的作用存在误解:Apache Commons CSV 库的CSVParser仅支持解析纯文本格式的分隔符文件,CSVFormat.EXCEL是用来适配Excel导出的CSV格式纯文本文件的分隔规则,根本无法解析原生.xlsx格式的二进制OXML文件。你直接用字符流读取二进制xlsx文件会拿到乱码内容,自然无法正常解析出记录。

修复方案

要同时兼容CSV和XLSX格式的文件解析,需要针对两种格式分别使用对应的解析组件,XLSX格式用Apache POI库处理,CSV格式继续用Commons CSV处理,最后将解析结果统一为相同的数据结构返回即可。

第一步:引入所需依赖

Maven依赖配置参考如下:

<!-- 处理XLSX格式的Apache POI -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.5</version>
</dependency>
<!-- 原有处理CSV的Commons CSV -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.10.0</version>
</dependency>

第二步:修改解析逻辑

示例代码如下:

// 统一返回格式用List<Map<String, String>>,和CSVParser返回的结构逻辑一致
public List<Map<String, String>> parseFile(MultipartFile file) throws IOException {
    String extension = StringUtils.getFilenameExtension(file.getOriginalFilename());
    logger.info("Extension Detected : {}", extension);
    
    if (extension == null) {
        throw new InvalidRequestException(Collections.singletonList(INVALID_EXTENSION));
    }
    // 处理xlsx格式
    if (extension.equals("xlsx")) {
        List<Map<String, String>> result = new ArrayList<>();
        try (XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream())) {
            XSSFSheet sheet = workbook.getSheetAt(0);
            // 读取表头
            XSSFRow headerRow = sheet.getRow(0);
            List<String> headers = new ArrayList<>();
            for (Cell cell : headerRow) {
                headers.add(cell.getStringCellValue().trim());
            }
            // 遍历数据行
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                XSSFRow row = sheet.getRow(i);
                if (row == null) continue;
                Map<String, String> rowMap = new HashMap<>();
                for (int j = 0; j < headers.size(); j++) {
                    Cell cell = row.getCell(j);
                    String cellValue = cell == null ? "" : cell.getStringCellValue().trim();
                    rowMap.put(headers.get(j), cellValue);
                }
                result.add(rowMap);
            }
        }
        logger.info("Records parsed successfully for file : {}", file.getOriginalFilename());
        return result;
    } 
    // 处理csv格式
    else if (extension.equals("csv")) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8));
             CSVParser parser = new CSVParser(reader, CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim())) {
            List<Map<String, String>> result = parser.getRecords().stream()
                    .map(CSVRecord::toMap)
                    .collect(Collectors.toList());
            logger.info("Records parsed successfully for file : {}", file.getOriginalFilename());
            return result;
        }
    } else {
        throw new InvalidRequestException(Collections.singletonList(INVALID_EXTENSION));
    }
}

内容的提问来源于stack exchange,提问作者Deepanshu Rathi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 22:57:04