使用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
相关产品推荐
相关产品推荐

