读取.xlsx文件触发Java空指针异常,请求代码排查与修复
排查并解决Java读取Excel时的NullPointerException问题
你遇到的NullPointerException是几个典型的代码疏漏导致的,我帮你逐一拆解并给出修复方案:
核心问题拆解
- 数组未初始化:你只声明了
user[],pass[],result[]三个数组,但没有为它们分配内存空间(比如new String[行数]),直接通过user[rowindex]赋值时,数组本身还是null,必然抛出空指针异常。 - Workbook提前关闭:你在获取
Sheet后立刻调用了workbook.close(),后续操作Sheet、Row、Cell时,这些对象已经依赖于被关闭的Workbook,会引发异常。 - 行索引管理混乱:
rowindex仅初始化为0,但没有在每处理完一行后递增,也没有提前获取Excel的有效行数来匹配数组长度。 - 单元格值读取不规范:直接用
cell.toString()可能导致格式错误(比如数字单元格会被转成带小数点的字符串),应该根据单元格类型针对性读取。
修正后的完整代码
import org.apache.poi.ss.usermodel.*; import java.io.File; import java.io.IOException; public class ExcelDataReader { public static void main(String[] args) { String pathFile = "你的Excel文件路径.xlsx"; // 替换为实际文件路径 String[] user = null; String[] pass = null; String[] result = null; Workbook workbook = null; try { workbook = WorkbookFactory.create(new File(pathFile)); Sheet sheet = workbook.getSheetAt(0); if (sheet != null) { // 第一步:统计有效数据行数(跳过表头行) int lastRowNum = sheet.getLastRowNum(); int validRowCount = 0; for (int i = sheet.getFirstRowNum() + 1; i <= lastRowNum; i++) { Row row = sheet.getRow(i); // 假设name列(索引1)不为空即为有效行 if (row != null && row.getCell(1) != null) { validRowCount++; } } // 第二步:用有效行数初始化数组 user = new String[validRowCount]; pass = new String[validRowCount]; result = new String[validRowCount]; // 第三步:逐行读取数据 int rowIndex = 0; for (int i = sheet.getFirstRowNum() + 1; i <= lastRowNum; i++) { Row row = sheet.getRow(i); if (row == null) continue; // 读取name列(索引1) Cell nameCell = row.getCell(1); if (nameCell != null) { user[rowIndex] = getCellValue(nameCell); } // 读取pass列(索引2) Cell passCell = row.getCell(2); if (passCell != null) { pass[rowIndex] = getCellValue(passCell); } // 读取result列(索引4) Cell resultCell = row.getCell(4); if (resultCell != null) { result[rowIndex] = getCellValue(resultCell); } rowIndex++; } // 这里将数据传入testweb // testweb.processUserData(user, pass, result); } } catch (IOException e) { e.printStackTrace(); } finally { // 最后统一关闭Workbook,确保资源释放 if (workbook != null) { try { workbook.close(); } catch (IOException e) { e.printStackTrace(); } } } } // 工具方法:根据单元格类型获取正确值 private static String getCellValue(Cell cell) { if (cell == null) return ""; switch (cell.getCellType()) { case STRING: return cell.getStringCellValue(); case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { return cell.getDateCellValue().toString(); } else { // 处理数字,避免多余小数点或科学计数法 return String.valueOf((long) cell.getNumericCellValue()); } case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); default: return ""; } } }
关键修复说明
- 数组初始化逻辑:先统计有效数据行数,再用这个长度初始化数组,避免数组越界或空指针。
- Workbook关闭时机:将关闭操作放在
finally块中,确保所有Excel读取操作完成后再释放资源。 - 空值防护:对
Row和Cell都增加了空值判断,避免因空行或空单元格触发异常。 - 单元格值标准化:新增
getCellValue方法,根据单元格类型读取对应的值,避免格式错误。
内容的提问来源于stack exchange,提问作者Quang Dao Van
相关产品推荐
相关产品推荐

