指定路径文件存在仍报java.lang.NullPointerException问题求助
问题分析与解决方案
异常原因
getCellCount方法未初始化row变量
在getCellCount方法中,获取工作表后直接调用row.getLastCellNum(),但row是类的静态成员变量,此时未通过ws.getRow(row_num)赋值,直接调用方法触发NullPointerException。静态成员变量引发的线程安全与状态混乱问题
ExcelUtils中的fis、wb、ws、row、cell均为静态变量,在TestNG多线程执行测试时,这些变量会被多个线程共享覆盖,导致对象引用变为null或者数据错乱。未处理行/单元格为
null的场景
当Excel中指定行不存在(ws.getRow(row_num)返回null)或指定单元格不存在(row.getCell(column)返回null)时,直接调用对象方法会触发空指针异常。
解决方案
1. 修复getCellCount方法的空指针问题
在方法内先通过ws.getRow(row_num)获取目标行,再调用单元格数量方法,同时处理行不存在的情况。
2. 将静态成员变量改为方法局部变量
避免多线程下的资源共享冲突,每个方法独立创建流、工作簿、工作表等对象,使用try-with-resources自动关闭资源,避免泄漏。
3. 处理行/单元格为null的场景
当获取的行或单元格为null时,做兜底处理(比如创建新行/单元格,或返回空字符串)。
修复后的ExcelUtils代码
package utils; import org.apache.poi.ss.usermodel.DataFormatter; 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 java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class ExcelUtils { public static int getRowCount(String xlFile, String xlSheet) throws IOException { try (FileInputStream fis = new FileInputStream(xlFile); XSSFWorkbook wb = new XSSFWorkbook(fis)) { XSSFSheet ws = wb.getSheet(xlSheet); if (ws == null) { return 0; } return ws.getLastRowNum(); } } public static int getCellCount(String xlFile, String xlSheet, int row_num) throws IOException { try (FileInputStream fis = new FileInputStream(xlFile); XSSFWorkbook wb = new XSSFWorkbook(fis)) { XSSFSheet ws = wb.getSheet(xlSheet); if (ws == null) { return 0; } XSSFRow row = ws.getRow(row_num); if (row == null) { return 0; } return row.getLastCellNum(); } } public static String getCellData(String xlFile, String xlSheet, int row_num, int column) throws IOException { try (FileInputStream fis = new FileInputStream(xlFile); XSSFWorkbook wb = new XSSFWorkbook(fis)) { XSSFSheet ws = wb.getSheet(xlSheet); if (ws == null) { return ""; } XSSFRow row = ws.getRow(row_num); if (row == null) { return ""; } XSSFCell cell = row.getCell(column); if (cell == null) { return ""; } DataFormatter formatter = new DataFormatter(); return formatter.formatCellValue(cell); } catch (Exception e) { return ""; } } public static void setCellData(String xlFile, String xlSheet, int row_num, int column, String data) throws IOException { try (FileInputStream fis = new FileInputStream(xlFile); XSSFWorkbook wb = new XSSFWorkbook(fis)) { XSSFSheet ws = wb.getSheet(xlSheet); if (ws == null) { ws = wb.createSheet(xlSheet); } XSSFRow row = ws.getRow(row_num); if (row == null) { row = ws.createRow(row_num); } XSSFCell cell = row.getCell(column); if (cell == null) { cell = row.createCell(column); } cell.setCellValue(data); try (FileOutputStream fos = new FileOutputStream(xlFile)) { wb.write(fos); } } } }
其他注意事项
- 确认
users.xlsx文件路径正确:./src/test/testdata/users.xlsx需确保文件存在,若为Maven项目,建议将测试数据放在src/test/resources下,调整路径为./src/test/resources/testdata/users.xlsx。 - TestNG的
DataProvider中,循环从第1行开始(跳过表头)的逻辑是正确的,但需确保Excel中第1行(索引1)确实存在数据。
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

