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

SpringBoot使用Apache POI导出嵌套Map结构为Excel时数据填充异常排查

问题根因

  • cellnum变量定义在表头循环内部,每次循环都会被重置为0,所有表头都被写入同一个单元格,最终仅保留最后一个表头值
  • 表头仅需在每个Sheet的第一行创建一次,原代码在遍历每一条数据时都会重复创建表头
  • 缺少数据行填充逻辑,仅写入了表头未写入对应的数据值
  • 代码存在笔误:wb.crateSheet应为wb.createSheet

核心修改点

  1. 提取表头创建逻辑,每个Sheet仅在首行生成一次表头
  2. 将单元格序号变量移到循环外部,避免重复重置导致单元格覆盖
  3. 新增数据行填充逻辑,表头生成完成后遍历写入对应数据值
  4. 修正方法名拼写错误,新增空值校验避免空指针异常

修改后完整代码

// 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 16:36:03