Java JAR包中无法写入Excel文件的技术求助
Apache POI读写Excel:JAR打包后无法写入的解决方案
问题根源
- JAR是只读压缩包,无法直接修改内部的Excel文件——你用
getResourceAsStream读取JAR内的文件后,不能直接写回JAR里。 - 最初的
./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
相关产品推荐
相关产品推荐

