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

Apache POI读取Excel报NullPointerException:sheet为null问题求助

问题分析与解决方案

核心问题拆解

  • 依赖版本冲突:混用POI 5.2.2核心包与4.1.0的poi-ooxml-schemas,版本不兼容会导致工作簿初始化失败,直接返回null。
  • 异常处理缺失:代码捕获异常仅打印堆栈,后续仍执行workbook.getSheet(sheetName),workbook为null时直接触发空指针。
  • 工作表匹配问题:传入的sheetName与Excel内工作表名称(大小写敏感)不一致时,getSheet()返回null,后续调用sheet.getLastRowNum()报错。
  • 路径可靠性不足:硬编码路径或相对路径可能因环境差异导致文件找不到,进而工作簿初始化失败。

分步修复方案

1. 统一POI依赖版本

删除poi-ooxml-schemas 4.1.0,POI 5.x版本无需单独引入该包,poi-ooxml已包含所需schemas。

Maven依赖示例:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.2</version>
</dependency>

Gradle依赖示例:

implementation 'org.apache.poi:poi:5.2.2'
implementation 'org.apache.poi:poi-ooxml:5.2.2'

2. 完善空值校验与异常处理

在使用workbook和sheet前必须做非空校验,同时改进异常处理逻辑,避免静默失败:

public static Object[][] getTestDataFromExcel(String sheetName) {
    // 用相对路径结合项目根目录,适配不同环境
    File excelFile = new File(System.getProperty("user.dir") 
            + "/src/main/java/com/seleniumHybridFrameworkProject/qa/testdata/seleniumHybridFrameworkProjectTestData.xlsx");
    
    // 先校验文件是否存在
    if (!excelFile.exists()) {
        throw new RuntimeException("Excel文件不存在:" + excelFile.getAbsolutePath());
    }

    XSSFWorkbook workbook = null;
    // 用try-with-resources自动关闭输入流,避免资源泄漏
    try (FileInputStream fisExcel = new FileInputStream(excelFile)) {
        workbook = new XSSFWorkbook(fisExcel);
    } catch (IOException e) {
        throw new RuntimeException("加载Excel文件失败", e); // 抛出异常终止执行,避免后续空指针
    }

    // 校验工作簿初始化结果
    if (workbook == null) {
        throw new RuntimeException("无法初始化Excel工作簿");
    }

    XSSFSheet sheet = workbook.getSheet(sheetName);
    // 校验工作表是否存在,同时打印所有工作表名称辅助排查
    if (sheet == null) {
        System.out.println("Excel中存在的工作表:");
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            System.out.println("- " + workbook.getSheetName(i));
        }
        throw new RuntimeException("指定的工作表不存在:" + sheetName);
    }

    int rows = sheet.getLastRowNum();
    if (rows < 0) {
        throw new RuntimeException("工作表" + sheetName + "中无数据行");
    }
    XSSFRow headerRow = sheet.getRow(0);
    if (headerRow == null) {
        throw new RuntimeException("工作表" + sheetName + "表头行不存在");
    }
    int cols = headerRow.getLastCellNum();

    Object[][] data1 = new Object[rows][cols];

    for (int i = 0; i < rows; i++) {
        XSSFRow row = sheet.getRow(i + 1);
        if (row == null) { // 跳过空行
            continue;
        }
        for (int j = 0; j < cols; j++) {
            XSSFCell cell = row.getCell(j);
            if (cell == null) { // 空单元格设为空字符串
                data1[i][j] = "";
                continue;
            }
            CellType cellType = cell.getCellType();

            switch (cellType) {
                case STRING:
                    data1[i][j] = cell.getStringCellValue();
                    break;
                case NUMERIC:
                    // 区分数值与日期类型
                    if (DateUtil.isCellDateFormatted(cell)) {
                        data1[i][j] = cell.getDateCellValue();
                    } else {
                        data1[i][j] = Integer.toString((int) cell.getNumericCellValue());
                    }
                    break;
                case BOOLEAN:
                    data1[i][j] = cell.getBooleanCellValue();
                    break;
                default:
                    data1[i][j] = "";
            }
        }
    }
    // 关闭工作簿释放资源
    try {
        workbook.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return data1;
}

3. 验证路径与工作表名称

  • 打印文件绝对路径确认:通过System.out.println(excelFile.getAbsolutePath())输出实际路径,手动检查文件是否存在。
  • 核对工作表名称:getSheet()方法大小写敏感,例如传入"Sheet1"但Excel内是"sheet1"会返回null,可通过代码中打印的工作表列表排查。

额外优化建议

  • 将Excel文件移至src/main/resources目录,通过类加载器获取资源,彻底避免路径硬编码:
InputStream is = YourClassName.class.getClassLoader().getResourceAsStream("testdata/seleniumHybridFrameworkProjectTestData.xlsx");
workbook = new XSSFWorkbook(is);
  • 始终用try-with-resources管理流和工作簿,防止资源泄漏。

内容的提问来源于stack exchange,提问作者Abhishek Giri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:42:49