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

使用TestNG@DataProvider从xlsx取数时路径正确却报FileNotFoundException异常

问题描述

我的Excel文件共有3个工作表,我尝试使用TestNG的@DataProvider注解读取文件中的数据,在getTestData()方法中传入目标工作表名称,通过FileInputStream读取文件路径,打印输出的文件路径完全正确,路径为:C:\Users\Gaurav Pratap Singh\eclipse-workspace\SampleTestFrameworkGPS\src\main\java\com\crm\qa\testData\FreeCRMTestData.xlsx。我曾怀疑问题出在目录名称中的空格,但同目录下的config.properties文件可以正常被读取,不存在该问题。相关实现代码如下:

package com.crm.qa.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import com.crm.qa.base.TestBase;

public class TestUtil extends TestBase {

    public static String TESTDATA_SHEET_PATH = System.getProperty("user.dir")
    + "\\src\\main\\java\\com\\crm\\qa\\testData\\FreeCRMTestData.xlsx";
    
    public static Workbook book;
    public static Sheet sheet;

    public static Object[][] getTestData(String sheetName){
        FileInputStream fis = null;

        try {
            fis = new FileInputStream(new File(TESTDATA_SHEET_PATH));
            // File Path printing perfectly
            System.out.println("Sheet path " + TESTDATA_SHEET_PATH);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
        System.out.println("Sheet path " + TESTDATA_SHEET_PATH);

        try {
            book = WorkbookFactory.create(fis);
        } catch (EncryptedDocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        sheet = book.getSheet(sheetName);

        Object[][] data = new Object[sheet.getLastRowNum()][sheet.getRow(0).getLastCellNum()];

        for (int i = 0; i < sheet.getLastRowNum(); i++) {
            for (int k = 0; k < sheet.getRow(0).getLastCellNum(); k++) {
                data[i][k] = sheet.getRow(i + 1).getCell(k).toString();
            }
        }
        return data;

    }

}
排查修复方案
  • 工作表名称匹配校验
    传入的sheetName参数必须和Excel中实际的工作表名称完全一致,注意区分大小写、去除前后多余空格,这是最常见的出错原因。如果工作表不存在,book.getSheet(sheetName)会返回null,后续调用sheet相关方法就会抛出空指针异常,可以加非空判断提前抛出明确的错误提示。
  • 空行空单元格兼容处理
    原代码默认Excel第一行是表头且所有行、单元格都有值,实际使用中如果表头行为空、某行数据为空或者某个单元格为空,都会触发空指针异常。可以增加如下兼容逻辑:
    // 读取工作表后先判断是否为空
    if(sheet == null) {
        throw new RuntimeException("未找到名称为" + sheetName + "的工作表");
    }
    // 表头行判空
    if(sheet.getRow(0) == null) {
        throw new RuntimeException("工作表" + sheetName + "表头行为空");
    }
    int rowCount = sheet.getLastRowNum();
    int cellCount = sheet.getRow(0).getLastCellNum();
    Object[][] data = new Object[rowCount][cellCount];
    // 循环读取时增加单元格判空
    for (int i = 0; i < rowCount; i++) {
        for (int k = 0; k < cellCount; k++) {
            data[i][k] = sheet.getRow(i + 1).getCell(k) == null ? "" : sheet.getRow(i + 1).getCell(k).toString();
        }
    }
    
  • 资源自动释放优化
    原代码中FileInputStream和Workbook使用后没有主动关闭,容易造成文件占用锁,导致后续读取文件失败。建议使用try-with-resources语法自动释放资源,优化后的代码如下:
    public static Object[][] getTestData(String sheetName){
        try (FileInputStream fis = new FileInputStream(new File(TESTDATA_SHEET_PATH));
            Workbook book = WorkbookFactory.create(fis)) {
            Sheet sheet = book.getSheet(sheetName);
            if(sheet == null) {
                throw new RuntimeException("未找到名称为" + sheetName + "的工作表");
            }
            if(sheet.getRow(0) == null) {
                throw new RuntimeException("工作表" + sheetName + "表头行为空");
            }
            int rowCount = sheet.getLastRowNum();
            int cellCount = sheet.getRow(0).getLastCellNum();
            Object[][] data = new Object[rowCount][cellCount];
            for (int i = 0; i < rowCount; i++) {
                for (int k = 0; k < cellCount; k++) {
                    data[i][k] = sheet.getRow(i + 1).getCell(k) == null ? "" : sheet.getRow(i + 1).getCell(k).toString();
                }
            }
            return data;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("测试数据文件未找到", e);
        } catch (EncryptedDocumentException | IOException e) {
            e.printStackTrace();
            throw new RuntimeException("测试数据文件读取失败", e);
        }
    }
    
  • POI依赖校验
    确认项目中引入的Apache POI依赖版本统一,且支持你使用的Excel格式:如果是.xlsx格式,需要同时引入poi和poi-ooxml两个依赖,版本号必须一致,避免依赖冲突导致读取失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:54:04