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

使用Apache POI读取Excel时遭遇NullPointerException问题求助

解决Apache POI读取Excel时的NullPointerException问题

看起来你的NullPointerException(NPE)主要来自两个关键问题:错误的列索引递增逻辑和未处理单元格为null的情况,另外单元格类型的判断方式也有问题,咱们一步步拆解解决:

1. 核心问题:列索引i的递增逻辑错误

你代码里的i在每次循环行的时候都会i++,这意味着:

  • 第一次循环行时,你取的是第0列(nextRow.getCell(i))和第1列(nextRow.getCell(i+1))
  • 第二次循环行时,i变成1,取的是第1列和第2列
  • 第三次循环行时,i变成2,取的是第2列和第3列
  • ...以此类推

但Excel里的每行数据大概率是固定列数的(比如邮政编码在第0列,城市在第1列,州在第2列),当循环到后面的行时,nextRow.getCell(i)或者nextRow.getCell(i+1)就会返回null(因为该行没有这么多列),调用toString()或getCellType()自然就触发NPE了。

2. 次要问题:单元格类型判断方式错误

Apache POI的getCellType()返回的是CellType枚举类型,不是字符串,你用equals("NUMERIC")的比较方式永远不会成立,而且如果单元格是null的话,调用getCellType()直接就NPE了。

3. 修正后的代码实现

假设你的Excel表中:

  • 第0列是邮政编码(可能是数字或字符串类型)
  • 第1列是城市
  • 第2列是州

下面是修正后的代码,同时兼顾了NPE处理、正确的类型判断,以及你需要的「邮政编码 - 城市 - 州」格式输出:

FileInputStream inputStream = new FileInputStream("C:/Users/student/eclipse-workspace/Weather2/bin/resources/uszips.xlsx");
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet firstSheet = workbook.getSheetAt(0);
Iterator<Row> iterator = firstSheet.iterator();

// 跳过表头(如果你的Excel第一行是表头的话)
if (iterator.hasNext()) {
    iterator.next();
}

while (iterator.hasNext()) {
    Row nextRow = iterator.next();
    
    // 用固定列索引获取单元格,同时处理单元格不存在的情况
    Cell zipCodeCell = nextRow.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
    Cell cityCell = nextRow.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
    Cell stateCell = nextRow.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
    
    // 处理邮政编码:如果是数字类型,转成字符串避免丢失前导零;如果是字符串直接取
    String zipCode = "";
    if (zipCodeCell.getCellType() == CellType.NUMERIC) {
        // 转成整数再转字符串,避免出现小数(比如12345.0)
        zipCode = String.valueOf((long) zipCodeCell.getNumericCellValue());
    } else if (zipCodeCell.getCellType() == CellType.STRING) {
        zipCode = zipCodeCell.getStringCellValue().trim();
    }
    
    // 处理城市和州
    String city = cityCell.getStringCellValue().trim();
    String state = stateCell.getStringCellValue().trim();
    
    // 按要求格式输出
    if (zipCode.length() == 5) { // 验证邮政编码格式
        System.out.printf("%s - %s - %s%n", zipCode, city, state);
    }
}

workbook.close();
inputStream.close();

关键改进点说明

  • 固定列索引:不再用递增的i,而是直接指定邮政编码、城市、州对应的列号(根据你的实际Excel调整)
  • 处理null单元格:用Row.MissingCellPolicy.CREATE_NULL_AS_BLANK把不存在的单元格转为空白单元格,避免NPE
  • 正确的类型判断:用CellType枚举值比较,而不是字符串
  • 邮政编码格式处理:将数字类型的邮政编码转成整数再转字符串,避免出现12345.0这种格式,同时保留字符串类型的邮政编码(比如带前导零的)
  • 跳过表头:如果你的Excel第一行是表头(比如"邮政编码"、"城市"、"州"),记得先跳过第一行

额外提示

如果你的Excel中有些行的邮政编码列确实为空,上面的代码会自动跳过(因为zipCode为空字符串,长度不等于5),不会触发异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 11:09:09