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

Apache POI XSSF导出JTable数据至Excel时行空白问题求助

解决Apache POI拆分Excel工作表时出现空白行的问题

你猜的没错!问题确实出在XSSFRow row = sheet_Mark.createRow(i);这一行——你直接使用了原JTable的行索引i来创建目标工作表的行,这就会把原表中前面不属于当前用户的记录位置留成空白行。比如你的例子里,Mark的第一条记录在原表是第4条(循环索引i=3),你直接在sheet_Mark里创建第3行,那前3行自然是空的。

核心解决方案:为每个工作表单独维护行计数器

我们需要给每个目标工作表单独设置一个行计数器,而不是复用原表的索引。计数器初始为0,每往工作表里添加一条记录,计数器就自增1,这样就能保证每行都是连续创建的,不会跳过行产生空白。

修改后的代码示例

// 创建工作表
XSSFSheet sheet_Mark = workbook.createSheet("Mark");
XSSFSheet sheet_John = workbook.createSheet("John");

// 为每个工作表初始化行计数器
int markRowCounter = 0;
int johnRowCounter = 0;

for(int i = 0; i < jTable1.getRowCount(); i++){
    Integer id_Values = (int) jTable1.getValueAt(i,0);
    String name_Values = (String) jTable1.getValueAt(i, 1);
    Integer age_Values = (int) jTable1.getValueAt(i,2);
    
    if(name_Values.equals("Mark")){
        // 使用Mark专属的计数器创建行
        XSSFRow row = sheet_Mark.createRow(markRowCounter);
        row.createCell(0).setCellValue(id_Values);
        row.createCell(1).setCellValue(name_Values);
        row.createCell(2).setCellValue(age_Values);
        // 添加完成后计数器加1,准备下一行
        markRowCounter++;
    } else if(name_Values.equals("John")){
        // 使用John专属的计数器创建行
        XSSFRow row = sheet_John.createRow(johnRowCounter);
        row.createCell(0).setCellValue(id_Values);
        row.createCell(1).setCellValue(name_Values);
        row.createCell(2).setCellValue(age_Values);
        // 添加完成后计数器加1
        johnRowCounter++;
    }
}

扩展性优化(可选)

如果以后需要支持更多名字,用Map来存储工作表和对应的计数器会更灵活,不用每次加名字都修改循环里的条件:

// 提前初始化工作表和行计数器的映射
Map<String, XSSFSheet> sheetMap = new HashMap<>();
Map<String, Integer> rowCounterMap = new HashMap<>();

sheetMap.put("Mark", workbook.createSheet("Mark"));
sheetMap.put("John", workbook.createSheet("John"));
rowCounterMap.put("Mark", 0);
rowCounterMap.put("John", 0);

for(int i = 0; i < jTable1.getRowCount(); i++){
    Integer id_Values = (int) jTable1.getValueAt(i,0);
    String name_Values = (String) jTable1.getValueAt(i, 1);
    Integer age_Values = (int) jTable1.getValueAt(i,2);
    
    // 检查当前名字是否有对应的工作表
    if(sheetMap.containsKey(name_Values)){
        XSSFSheet targetSheet = sheetMap.get(name_Values);
        int currentRow = rowCounterMap.get(name_Values);
        
        XSSFRow row = targetSheet.createRow(currentRow);
        row.createCell(0).setCellValue(id_Values);
        row.createCell(1).setCellValue(name_Values);
        row.createCell(2).setCellValue(age_Values);
        
        // 更新计数器
        rowCounterMap.put(name_Values, currentRow + 1);
    }
}

这样修改后,你的两个工作表都会从第1行开始连续填充数据,不会再出现空白行啦!

内容的提问来源于stack exchange,提问作者Maibhalsych

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:58:15