Java调用Apache POI的sheet.getRow()缺失未操作空列是否为Bug?
问题根因
Apache POI 读取Excel文件时,sheet.getRow() 方法默认只会加载底层文件中实际存储了值或样式的单元格。新建文件时从未操作过的空白列,不会被写入Excel的文件结构里,POI不会主动为这些不存在的列生成单元格对象,所以遍历行内单元格时会直接跳过这类列。
测试时点击单元格、设置填充色的操作,本质是给这些列的单元格写入了样式/占位信息,文件里有了对应存储记录,POI读取时自然就能拿到这些空单元格。
解决方案
不需要修改POI全局配置,不要直接遍历行对象自带的单元格集合,按列索引主动获取单元格,搭配POI内置的MissingCellPolicy策略即可自动补全缺失的空白列,代码实现如下:
import org.apache.poi.ss.usermodel.*; import static org.apache.poi.ss.usermodel.Row.MissingCellPolicy; // 读取指定行数据的逻辑 Row row = sheet.getRow(i); // 处理整行完全不存在的极端场景 if (row == null) { row = sheet.createRow(i); } // 确定读取的列范围:如果要读取到当前行有数据的最后一列,用getLastCellNum();如果要固定读到某列(比如H列)直接写对应列数即可,H列对应索引7,列数为8 int totalCols = row.getLastCellNum(); // 缺失单元格策略:不存在的单元格自动创建为BLANK类型的空单元格返回,不会返回null MissingCellPolicy cellPolicy = MissingCellPolicy.CREATE_NULL_AS_BLANK; DataFormatter dataFormatter = new DataFormatter(); for (int colIndex = 0; colIndex < totalCols; colIndex++) { // 按列索引逐个取单元格,未操作过的空白列不会被跳过 Cell cell = row.getCell(colIndex, cellPolicy); // 统一格式化单元格值,空白单元格会返回空字符串,不需要额外判断空指针 String value = dataFormatter.formatCellValue(cell); // 这里写你的业务处理逻辑 }
策略参数说明
MissingCellPolicy提供3种可选规则,可根据业务场景选择:
CREATE_NULL_AS_BLANK:如果单元格不存在,自动创建一个BLANK类型的空单元格返回,永远不会返回null,最适配需要读取全列的场景RETURN_NULL_AND_BLANK:不存在的单元格返回null,已经创建但无值的空白单元格返回BLANK类型对象RETURN_BLANK_AS_NULL:不存在的单元格、已创建但无值的空白单元格都返回null
内容的提问来源于stack exchange,提问作者Nqt Bean
相关产品推荐
相关产品推荐

