如何使用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
相关产品推荐
相关产品推荐

