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

Eclipse中POI XSSF生成损坏Workbook问题求助

问题分析与修复方案

核心问题定位

你的Excel文件损坏主要来自POI工作簿复用错误、ResultSet遍历逻辑混乱,以及OneDrive同步的潜在干扰,和SSH隧道本身无关(只是时间点巧合重合)。

具体修复步骤

1. 修复POI工作簿的复用逻辑

POI的Workbook对象在调用write()后,XSSF实现会关闭内部资源包,后续复用该对象写入会导致文件损坏。你当前的流程是"打开文件→删除旧sheet→写入文件→再往同一workbook加新sheet→再次写入",这是错误的。

正确流程:

  • 打开文件加载workbook
  • 删除旧sheet(如果存在)
  • 直接在当前workbook中创建新sheet并填充数据
  • 最后只执行一次写入操作,覆盖原文件

修改后的关键代码片段:

try {
    // 打开文件加载工作簿并及时关闭输入流
    FileInputStream inputstream = new FileInputStream("D://OneDrive//ABSEC//ATC_Reporting//expdata.xlsx");
    Workbook workbook = WorkbookFactory.create(inputstream);
    inputstream.close();

    // 删除旧sheet(如果存在)
    XSSFSheet sheet0 = (XSSFSheet) workbook.getSheet("Security_Completions");
    if (sheet0 != null) {
        int index0 = workbook.getSheetIndex(sheet0);
        workbook.removeSheetAt(index0);
    }

    // 连接数据库执行查询
    Class.forName("com.mysql.cj.jdbc.Driver");
    Connection connection = DriverManager.getConnection(
            "jdbc:mysql://127.0.0.1:3307/wp_dashort", "dashort",
            "gt9wkk6r1TPnkgrY");

    String mark_complete = "SELECT DISTINCT wpgc.user_id, wpgc.timestamp\r\n"
            + "FROM wp_grassblade_completions as wpgc \r\n" + "  INNER JOIN \r\n"
            + "wp_usermeta ON wpgc.user_id = wp_usermeta.user_id\r\n"
            + "WHERE wpgc.user_id NOT IN (SELECT atc_reporting.user_id FROM atc_reporting WHERE course = 'SECURITY') AND wpgc.timestamp BETWEEN (CURRENT_DATE -INTERVAL 30 DAY) AND DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY) AND content_id IN (1575, 642, 1580) \r\n"
            + "GROUP BY wpgc.user_id\r\n" + "order BY wpgc.timestamp, wp_usermeta.user_id";

    PreparedStatement ps = connection.prepareStatement(mark_complete);
    ResultSet rs = ps.executeQuery();

    // 创建新sheet并填充数据
    Sheet sheet = workbook.createSheet("Security_Completions");
    Row rowhead = sheet.createRow(0);
    rowhead.createCell(0).setCellValue("Column 1");
    rowhead.createCell(1).setCellValue("Column 2");

    int rowIndex = 1; // 从第2行开始写入数据
    while (rs.next()) {
        Row row = sheet.createRow(rowIndex++);
        row.createCell(0).setCellValue(rs.getString(1));
        row.createCell(1).setCellValue(StringUtils.left(rs.getString(2), 16));
    }

    // 一次性写入文件并按顺序关闭所有资源
    FileOutputStream fileOut = new FileOutputStream("D://OneDrive//ABSEC//ATC_Reporting//expdata.xlsx");
    workbook.write(fileOut);
    fileOut.close();
    workbook.close();
    rs.close();
    ps.close();
    connection.close();

    System.out.println("Data is saved in excel file.");
} catch (Exception ex) {
    ex.printStackTrace(); // 必须捕获异常,否则中断写入会导致文件损坏
}

2. 修复ResultSet遍历逻辑错误

你原代码中多次调用rs.next(),导致大量数据被跳过,甚至可能因异常中断写入流程:

rs.next(); // 跳过第一行
while (rs.next()) {
    // ...
    for (int i = 0; i < 1; ++i) {
        rs.next(); // 再次跳过一行
    }
}

上面的修复代码已修正为直接用while(rs.next())遍历所有行,避免数据丢失和异常。

3. 修复字符串比较Bug

if (realm == "Security")是错误的字符串比较方式,应改为:

if ("Security".equals(realm)) { // 常量放前面避免空指针
    // ...
}

4. 规避OneDrive同步干扰

OneDrive实时同步可能在文件写入时锁定文件导致损坏,可采取:

  • 先将文件写入OneDrive外的临时目录,完成后再移动到目标目录
  • 暂时关闭OneDrive实时同步,验证是否还出现损坏问题

额外注意事项

  • 必须添加异常捕获逻辑,未捕获的异常会导致文件写入不完整
  • 所有资源(流、数据库连接、ResultSet等)必须按顺序关闭,避免资源泄漏

内容的提问来源于stack exchange,提问作者David S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:40:31