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

使用POI读取Excel时cellIterator.hasNext()遇空单元格返回false如何解决

问题原因

Apache POI 中Row.cellIterator()默认仅会迭代已被初始化(包含值、格式等属性)的单元格,完全未创建的空单元格不会被纳入迭代范围,因此会出现空单元格无法触发迭代的问题。

实现方案

不要使用单元格迭代器,改为根据固定列数手动遍历列索引,同时指定空单元格的处理策略即可:

  1. 先读取表头行的总列数作为遍历的统一列数基准,避免不同行有效列数不一致
  2. 使用Row.getCell(int index, Row.MissingCellPolicy)重载方法获取单元格,通过MissingCellPolicy.CREATE_NULL_AS_BLANK策略将未初始化的空单元格自动转为空白单元格返回
修改后的完整代码
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

// 业务代码部分
InputStream inputStream = new BufferedInputStream(multipartFile.getInputStream());
XSSFWorkbook myWorkBook = new XSSFWorkbook(inputStream);
List<String> cellList = new ArrayList<>();
XSSFSheet mySheet = myWorkBook.getSheetAt(0);

// 先获取表头总列数,作为统一遍历列数
int totalColumn = mySheet.getRow(0).getLastCellNum();

Iterator<Row> rowIterator = mySheet.iterator();
rowIterator.next(); // 跳过表头

while (rowIterator.hasNext()) {
    Row row = rowIterator.next();
    cellList.clear();
    // 遍历所有列,而非用迭代器
    for (int i = 0; i < totalColumn; i++) {
        // 空单元格自动创建为BLANK类型,不会返回null
        Cell cell = row.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
        // 通用方法处理不同类型的单元格值,避免类型转换报错
        cellList.add(getCellValue(cell));
    }
}

// 通用单元格值读取方法
private String getCellValue(Cell cell) {
    if (cell == null) {
        return "";
    }
    switch (cell.getCellType()) {
        case STRING:
            return cell.getStringCellValue().trim();
        case NUMERIC:
            if (DateUtil.isCellDateFormatted(cell)) {
                return new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
            } else {
                // 处理数字转字符串避免科学计数法可自行补充格式化逻辑
                return String.valueOf(cell.getNumericCellValue());
            }
        case BOOLEAN:
            return String.valueOf(cell.getBooleanCellValue());
        case BLANK:
            return "";
        case FORMULA:
            return cell.getCellFormula();
        default:
            return "";
    }
}
注意事项
  • 如果不需要全局统一列数,也可以每行单独取row.getLastCellNum()作为当前行的遍历上限,可根据业务需求选择
  • 不要直接调用getStringCellValue(),否则数字、日期、布尔类型的单元格会抛出类型转换异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:27:02