SpringBoot使用Apache POI导出嵌套Map结构为Excel时数据填充异常排查
问题根因
cellnum变量定义在表头循环内部,每次循环都会被重置为0,所有表头都被写入同一个单元格,最终仅保留最后一个表头值- 表头仅需在每个Sheet的第一行创建一次,原代码在遍历每一条数据时都会重复创建表头
- 缺少数据行填充逻辑,仅写入了表头未写入对应的数据值
- 代码存在笔误:
wb.crateSheet应为wb.createSheet
核心修改点
- 提取表头创建逻辑,每个Sheet仅在首行生成一次表头
- 将单元格序号变量移到循环外部,避免重复重置导致单元格覆盖
- 新增数据行填充逻辑,表头生成完成后遍历写入对应数据值
- 修正方法名拼写错误,新增空值校验避免空指针异常
修改后完整代码
// code to create excel sheet Map<String, List<Map<String, Object>>> data = info.getData(); // 从数据库获取数据 XSSFWorkbook wb = new XSSFWorkbook(); FileOutputStream out = new FileOutputStream(new File("C:...路径" + "data.xlsx")); Set<String> keyset = data.keySet(); for (String key : keyset) { XSSFSheet sheet = wb.createSheet(key); // 修正拼写错误 int rowNo = 0; List<Map<String, Object>> list = data.get(key); // 空数据直接跳过当前Sheet if (list.isEmpty()) { continue; } // 创建表头行(仅执行一次) XSSFRow headerRow = sheet.createRow(rowNo++); Set<String> headerKeyset = list.get(0).keySet(); int cellNum = 0; for (String keyHeader : headerKeyset) { XSSFCell cell = headerRow.createCell(cellNum++); cell.setCellValue(keyHeader); } // 填充数据行 for (Map<String, Object> value : list) { XSSFRow dataRow = sheet.createRow(rowNo++); cellNum = 0; for (String keyHeader : headerKeyset) { XSSFCell cell = dataRow.createCell(cellNum++); Object val = value.get(keyHeader); cell.setCellValue(val == null ? "" : val.toString()); } } } wb.write(out); out.close(); // 建议补充工作簿关闭逻辑 wb.close(); 避免资源泄漏
可选优化:如果需要固定表头顺序,可以将存储数据的
HashMap替换为LinkedHashMap,保证表头遍历顺序和定义顺序一致。
内容的提问来源于stack exchange,提问作者Nithya shree
相关产品推荐
相关产品推荐

