CSV读取后写入Excel报错排查及修复请求(附代码片段)
嘿,我来帮你排查这个CSV转Excel的问题!你说已经搞定了CSV读取,但用List数组写Excel的时候报错,结合常见的坑,我整理了可能的原因、修复方法,还有完整的示例代码,你可以参考下:
问题排查:CSV转Excel时List数组写入错误
问题回顾
你已经成功读取CSV文件到List数组,但写入Excel对应列时出现错误,你的代码开头如下:
package testmaven.testmv; import java.io.BufferedReader; import java.io.File; import ...
可能的错误原因
我先列几个最常见的坑,你可以对照自己的代码检查:
- 索引搞混了:Apache POI里的行、列索引都是从
0开始的,但很多新手会误以为是从1开始,比如要写第一列却用了1当索引,直接导致空指针或写入位置错误。 - 数据类型不兼容:List里存的是String,但写入Excel时直接强转成数字类型,或者单元格格式没设置对,比如把字符串写进数字格式的单元格,就会报错。
- 行/列对象没初始化:比如要写入第5行,但没先创建这一行,直接拿
sheet.getRow(4)会得到null,调用createCell就会空指针。 - 资源没正确关闭:Excel文件流没关闭,导致写入不完整或者文件损坏,也会抛出IO异常。
针对性修复方案
对应上面的问题,给你逐个解决:
- 确认索引规则:所有行、列操作都用0-based索引,比如第一行是
rowIndex=0,第一列是colIndex=0。 - 统一数据类型处理:写入单元格时先判断数据类型,字符串直接写,数字转成对应类型再写:
// 字符串写入 cell.setCellValue(list.get(colIndex)); // 数字写入(先做格式校验) try { cell.setCellValue(Double.parseDouble(list.get(colIndex))); } catch (NumberFormatException e) { cell.setCellValue(list.get(colIndex)); } - 正确初始化行对象:创建行之前先判断是否存在,不存在再创建:
Row row = sheet.getRow(rowIndex); if (row == null) { row = sheet.createRow(rowIndex); } - 用try-with-resources管理流:自动关闭Workbook和FileOutputStream,避免资源泄漏:
try (Workbook workbook = new XSSFWorkbook(); FileOutputStream fos = new FileOutputStream(excelFile)) { // 写入逻辑 workbook.write(fos); } catch (IOException e) { e.printStackTrace(); }
完整示例代码
下面是一个可以直接运行的完整代码,包含CSV读取和Excel写入的全流程,用的是Apache POI 5.2.5版本:
首先如果是Maven项目,需要添加依赖:
<dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.5</version> </dependency> </dependencies>
然后Java代码:
package testmaven.testmv; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class CsvToExcelConverter { public static void main(String[] args) { String csvFilePath = "input.csv"; // 你的CSV文件路径 String excelFilePath = "output.xlsx"; // 输出Excel路径 // 读取CSV数据 List<List<String>> csvData = readCsv(csvFilePath); if (csvData.isEmpty()) { System.out.println("CSV文件为空或读取失败"); return; } // 写入Excel writeToExcel(csvData, excelFilePath); System.out.println("Excel写入完成!"); } // 读取CSV到List<List<String>> private static List<List<String>> readCsv(String filePath) { List<List<String>> data = new ArrayList<>(); try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { String line; while ((line = br.readLine()) != null) { // 处理CSV分隔符,这里假设是逗号,若字段含逗号需用引号包裹,代码里做了简单处理 String[] fields = line.split(","); List<String> row = new ArrayList<>(); for (String field : fields) { // 去掉字段前后的引号(如果有) row.add(field.replaceAll("^\"|\"$", "")); } data.add(row); } } catch (IOException e) { e.printStackTrace(); } return data; } // 将List数据写入Excel private static void writeToExcel(List<List<String>> csvData, String filePath) { try (Workbook workbook = new XSSFWorkbook(); FileOutputStream fos = new FileOutputStream(new File(filePath))) { Sheet sheet = workbook.createSheet("CSV导出数据"); sheet.setDefaultColumnWidth(18); // 设置默认列宽,方便查看 // 遍历每一行数据 for (int rowIdx = 0; rowIdx < csvData.size(); rowIdx++) { List<String> rowData = csvData.get(rowIdx); Row row = sheet.createRow(rowIdx); // 遍历每一列数据 for (int colIdx = 0; colIdx < rowData.size(); colIdx++) { Cell cell = row.createCell(colIdx); String value = rowData.get(colIdx); // 自动判断数据类型,数字转成数值型,否则存字符串 try { double num = Double.parseDouble(value); cell.setCellValue(num); } catch (NumberFormatException e) { cell.setCellValue(value); } } } workbook.write(fos); } catch (IOException e) { e.printStackTrace(); } } }
你可以把自己的代码和这个示例对比,看看哪里没做到位,应该就能解决问题啦!
内容的提问来源于stack exchange,提问作者xyz
相关产品推荐
相关产品推荐

