Apache POI写入Excel仅保留最后一条记录问题咨询
嘿,这个问题我之前帮不少开发者排查过,大概率是你在遍历POJO列表写Excel的时候,行的处理逻辑出了问题——要么每次循环都在覆盖同一行,要么行索引没正确递增。下面给你拆解几个常见的坑和对应的解决方法:
常见问题排查与解决方法
1. 行索引未正确递增(最常见原因)
很多人会犯的错是:在循环里固定用同一个行索引(比如一直写row = sheet.createRow(1)),这样每次循环都会覆盖第2行(POI的行索引从0开始计数),最后自然只剩最后一条数据。
正确做法:初始化一个行索引变量,每次循环后自动递增。示例代码如下:
// 假设从第2行开始写数据(第1行用来放表头) int rowIndex = 1; for (YourPOJO pojo : pojoList) { // 每次循环创建新的行,索引自增 Row row = sheet.createRow(rowIndex++); // 逐个写入POJO的字段到单元格 row.createCell(0).setCellValue(pojo.getId()); row.createCell(1).setCellValue(pojo.getName()); // ... 其他字段的写入逻辑 }
2. 重复创建Workbook/Sheet导致覆盖
如果你的循环里不小心重复创建了Workbook或者Sheet对象,那每次循环都会生成一个全新的空工作表,之前写入的内容会被完全覆盖,最后自然只剩最后一次循环的数据。
检查要点:确保Workbook和Sheet的创建代码放在循环外面,示例如下:
// 先创建工作簿和工作表,这一步只做一次 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("数据列表"); // 可选:先写入表头 Row headerRow = sheet.createRow(0); headerRow.createCell(0).setCellValue("ID"); headerRow.createCell(1).setCellValue("名称"); // 再遍历POJO列表写入数据 int rowIndex = 1; for (YourPOJO pojo : pojoList) { Row row = sheet.createRow(rowIndex++); // 写入单元格数据... }
3. 流处理逻辑错误
如果是用文件流写入Excel,一定要注意:
- 必须在所有数据写完之后再调用
workbook.write(out),不要在循环里重复写入 - 要确保流的关闭顺序正确,避免数据未完全写入就关闭流
正确的流处理示例:
try (FileOutputStream out = new FileOutputStream("output.xlsx")) { // 先完成所有行的写入逻辑 // ... 循环写数据的代码 ... // 最后统一将工作簿写入文件 workbook.write(out); } catch (IOException e) { e.printStackTrace(); } finally { try { // 最后关闭工作簿释放资源 workbook.close(); } catch (IOException e) { e.printStackTrace(); } }
4. 误用getRow导致的问题
如果你的代码里用了sheet.getRow(rowIndex),而该行之前不存在,会返回null,后续的单元格写入操作就会失效;如果重复调用getRow获取已存在的行并覆盖数据,也会导致之前的记录被清空。
建议:如果是要创建新行,直接使用createRow(rowIndex)——它会自动创建不存在的行;如果是要修改已存在的行,先判断getRow的返回值是否为null,再做处理。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

