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

Java JAR包中无法写入Excel文件的技术求助

Apache POI读写Excel:JAR打包后无法写入的解决方案

问题根源

  1. JAR是只读压缩包,无法直接修改内部的Excel文件——你用getResourceAsStream读取JAR内的文件后,不能直接写回JAR里。
  2. 最初的./src/Pick4list.xlsx路径仅在IDE环境有效,打包后JAR中没有src目录,导致读取失败。

解决思路

把JAR里的Excel模板复制到外部可读写的目录(比如程序运行目录、用户专属文件夹),后续所有读写操作都针对这个外部文件,这样跨电脑运行时修改也能保存。

完整修改代码

if ("add".equals(addordel)) {
    // 定义外部存储路径:程序运行目录下的data文件夹
    File externalDataDir = new File(System.getProperty("user.dir") + "/data");
    File externalExcelFile = new File(externalDataDir, "Pick4list.xlsx");

    Workbook workbook = null;
    FileOutputStream out = null;

    try {
        // 创建外部目录(不存在则新建)
        if (!externalDataDir.exists()) {
            externalDataDir.mkdirs();
        }

        // 外部文件不存在时,从JAR复制模板
        if (!externalExcelFile.exists()) {
            try (InputStream jarInputStream = getClass().getResourceAsStream("/data/Pick4list.xlsx")) {
                if (jarInputStream == null) {
                    throw new FileNotFoundException("JAR内未找到模板文件:/data/Pick4list.xlsx");
                }
                try (FileOutputStream copyOut = new FileOutputStream(externalExcelFile)) {
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = jarInputStream.read(buffer)) != -1) {
                        copyOut.write(buffer, 0, bytesRead);
                    }
                }
            }
        }

        // 读取外部Excel文件进行编辑
        workbook = new XSSFWorkbook(new FileInputStream(externalExcelFile));
        Sheet sheet = workbook.getSheetAt(0);
        int rowNum = -1;

        // 查找目标行,增加非空和类型判断避免空指针
        for (Row row : sheet) {
            Cell cell0 = row.getCell(0);
            if (cell0 != null && cell0.getCellType() == CellType.STRING && cell0.getStringCellValue().equals(datenum)) {
                rowNum = row.getRowNum();
                break;
            }
        }

        if (rowNum >= 0) {
            for (int i = 1; i < 10000; i++) {
                Cell cell = sheet.getRow(rowNum).getCell(i);
                if (cell == null || cell.getCellType() == CellType.BLANK) {
                    if (i - 1 < dateslist.size()) {
                        String dateStr = dateslist.get(i - 1);
                        cell = sheet.getRow(rowNum).createCell(i);
                        cell.setCellValue(dateStr);
                    } else {
                        break;
                    }
                }
            }
        }

        // 将修改写入外部文件
        out = new FileOutputStream(externalExcelFile);
        workbook.write(out);

    } catch (FileNotFoundException ex) {
        Logger.getLogger(Pick4gen.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(Pick4gen.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        // 确保资源关闭,防止泄漏
        try {
            if (out != null) out.close();
            if (workbook != null) workbook.close();
        } catch (IOException ex) {
            Logger.getLogger(Pick4gen.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

可选优化

  • 如果不想让Excel文件出现在程序运行目录,可以改用用户主目录下的专属文件夹:System.getProperty("user.home") + "/.Pick4App/data",避免文件被误删。
  • 可以添加日志提示,告知用户文件存储位置,方便查找。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 23:30:35