Java项目本地正常运行,打包Jar后报错:无法读取Excel资源文件
问题分析与解决方案
核心问题
你遇到的FileNotFoundException是因为打包成Jar后,资源文件是Jar包内部的条目,并非文件系统上的独立文件,用File对象访问必然找不到。本地运行时文件路径指向项目目录下的资源,所以能正常读取,但Jar环境下路径逻辑完全不同。
另外还有次要问题:Log4j2提示缺少log4j-core依赖,说明打包时未将依赖库一并打进Jar。
解决方案
1. 修改资源读取逻辑,用类加载器获取输入流
将原来通过File打开文件的方式,改为用类加载器的getResourceAsStream获取Jar内部资源的输入流。修改你的readSheetsLine方法:
public static String readSheetsLine(String resourcePath, String sheetsName, String name) throws IOException { String text = ""; Workbook wb; // 用类加载器获取资源输入流,路径用正斜杠,开头不要加/ try (InputStream is = ZarządcaArkuszów.class.getClassLoader().getResourceAsStream(resourcePath)) { if (is == null) { throw new FileNotFoundException("资源文件不存在:" + resourcePath); } wb = new XSSFWorkbook(is); } catch (InvalidFormatException e) { throw new RuntimeException(e); } Sheet sheet = wb.getSheet(sheetsName); if (sheet == null) { throw new IllegalArgumentException("找不到工作表:" + sheetsName); } for(Row r : sheet){ Cell cell = r.getCell(0); if (cell == null) continue; String value = cell.getStringCellValue(); if(Objects.equals(value, name)){ for (Cell c : r){ c.setCellType(CellType.STRING); Cell headerCell = sheet.getRow(0).getCell(c.getColumnIndex()); if (headerCell == null) break; String typ = headerCell.getStringCellValue(); if (!Objects.equals(typ, "")){ text += typ + "#" + c.getStringCellValue() + "~"; } else break; } break; } if (Objects.equals(value, "")) break; } wb.close(); return text; }
调用该方法时,传入的资源路径改为"zasoby/Dane/Dane.xlsx"(用正斜杠适配跨平台),而非File对象。
2. 确保资源文件被正确打包进Jar
在IDEA中操作:
- 右键点击
zasoby目录 → Mark Directory as → Resources Root - 检查Artifact配置:进入
File → Project Structure → Artifacts,确认Jar artifact包含Resources目录下的所有文件
3. 解决Log4j2依赖缺失问题
打包时需将所有依赖库(包括log4j-core、log4j-api及Apache POI相关依赖)一并打进Jar:
- 用IDEA的Artifact:创建Jar时选择From modules with dependencies,确保所有需要的依赖都被包含
- 用Maven:添加
maven-shade-plugin插件;用Gradle:添加shadow插件,打包成Fat Jar
内容的提问来源于stack exchange,提问作者Symarfiusz Renesans
相关产品推荐
相关产品推荐

