使用Apache POI 3.17操作Excel遇警告及空指针异常,求解决方案
解决POI读取Excel时的空指针异常与反射警告问题
先聚焦解决导致程序崩溃的NullPointerException(这是当前核心问题),再处理那个警告提示。
一、修复NullPointerException(空指针异常)
错误提示里的java.lang.NullPointerException at poi_excel.main(poi_excel.java:16),说明代码第16行访问了null对象。结合你的代码分析,大概率是以下两种情况之一:
sheet.getRow(1)返回null:你的script工作表中索引为1的行不存在(POI中行索引从0开始,索引1对应Excel里的第2行)。row.getCell(1)返回null:该行的索引为1的单元格是空的(对应Excel里的第B列)。
解决方案步骤:
- 核对工作表名称:确认Excel文件里确实存在名为
script的工作表,POI对工作表名称区分大小写,别出现拼写或大小写错误。 - 添加空值判断逻辑:在访问行和单元格前先判断是否为
null,避免直接调用方法触发空指针;也可以用POI的MissingCellPolicy统一处理空单元格。
给你修改后的代码示例,加入了完整的空值检查:
import java.io.FileInputStream; import java.io.IOException; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.ss.usermodel.Row; public class poi_excel { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("F:\\Selenium Using Web Driver\\Plugins\\HEC_login.xlsx"); XSSFWorkbook wb = new XSSFWorkbook(fis); // 检查目标工作表是否存在 XSSFSheet sheet = wb.getSheet("script"); if (sheet == null) { System.out.println("工作表'script'不存在,请核对名称!"); wb.close(); fis.close(); return; } // 检查目标行是否存在(索引1对应Excel第2行) XSSFRow row = sheet.getRow(1); if (row == null) { System.out.println("Excel第2行不存在,请确认数据!"); wb.close(); fis.close(); return; } // 用MissingCellPolicy处理空单元格,避免返回null XSSFCell cell = row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); String value = ""; // 根据单元格类型获取对应值,避免类型不匹配报错 switch (cell.getCellType()) { case STRING: value = cell.getStringCellValue(); break; case NUMERIC: value = String.valueOf(cell.getNumericCellValue()); break; default: value = "无有效数据"; } System.out.println(value); // 关闭资源,避免内存泄漏 wb.close(); fis.close(); } }
二、消除非法反射访问警告
那个Illegal reflective access警告是因为你使用的POI 3.17版本较老,和Java 9及以上的模块化系统不兼容导致的。
解决方案:
- 优先升级POI版本:将POI升级到4.1.2或更高的稳定版本(比如最新的5.x系列),新版本已经修复了Java模块化兼容问题,还能获得更多功能和bug修复。
- 临时缓解方案(不推荐长期使用):如果暂时无法升级,运行Java程序时添加VM参数:
这个参数允许POI代码访问Java核心类的内部成员,从而消除警告,但这只是临时 workaround,还是建议尽快升级版本。--add-opens java.base/java.io=ALL-UNNAMED
内容的提问来源于stack exchange,提问作者Muhammad Atif Niaz




