Apache POI处理Excel空行问题:读取行数异常导致上传应用报错的解决方案咨询
解决Excel空行导致的导入错误问题
你遇到的核心问题是POI的getPhysicalNumberOfRows()方法会统计所有被创建过的行(哪怕这些行后来被清空或没有实际数据),而非仅包含有效数据的行。这就是为什么明明只有3行数据,却返回了26306行,遍历过程中碰到空行后触发了Invalid product category的报错。
下面是几个针对性的解决方案:
1. 遍历前过滤所有空行
先添加一个工具方法判断某一行是否为无有效数据的空行,再在遍历工作表时跳过这些行:
// 判断行是否为空(所有单元格均无有效数据) private boolean isRowEmpty(Row row) { if (row == null) { return true; } DataFormatter formatter = new DataFormatter(); for (Cell cell : row) { String cellValue = formatter.formatCellValue(cell).trim(); if (!cellValue.isEmpty()) { return false; } } return true; }
修改locationDetails方法,加入空行过滤逻辑:
private List<NewLocationFile> locationDetails(Sheet worksheet, String traceId) { List<NewLocationFile> newLocationList = new ArrayList<>(); int j = 0; for (Row row : worksheet) { // 跳过空行,只处理有有效数据的行 if (isRowEmpty(row)) { continue; } j++; int excelSheetRow = j + 1; // 对应原Excel的实际行号(已移除表头) newLocationList.add(returnLocations(row, excelSheetRow, userBrn, traceId)); } String converToString = CommonUtil.convertToString(newLocationList); return newLocationList; }
2. 优化returnLocations方法的前置校验
在处理单元格数据前,先判断目标单元格是否存在且有值,避免空指针或无效值报错:
private NewLocationFile returnLocations(Row row, int excelSheetRow, String traceId) { NewLocationFile newLocation = new NewLocationFile(); // 记得实例化对象 String productCategory = null; DataFormatter formatter = new DataFormatter(); // 先判断目标单元格是否存在 Cell categoryCell = row.getCell(13); if (categoryCell == null) { throw new PostSaleModificationException(ErrorCode.INVALID_PRODUCT_TYPE, "Invalid product category in row :" + excelSheetRow); } String categoryValue = formatter.formatCellValue(categoryCell).trim(); if (categoryValue.length() > 0) { productCategory = categoryValue.toUpperCase(); } else { throw new PostSaleModificationException(ErrorCode.INVALID_PRODUCT_TYPE, "Invalid product category in row :" + excelSheetRow); } // 其他字段赋值逻辑... newLocation.setProductCategory(productCategory); return newLocation; }
3. 替换空表判断逻辑
原代码依赖getPhysicalNumberOfRows()判断空表,但这个值不准确,改成过滤后判断有效数据的行数:
// 在主方法中修改空表判断 newLocationList.addAll(locationDetails(worksheet, traceId)); if (newLocationList.isEmpty()) { throw new PSException(ErrorCode.INVALID_INPUT_PROVIDED, "Empty excel sheet "); }
问题根源补充
这类情况通常是因为Excel文件残留了无效行的元数据——比如用户误点击过靠后的行、插入行后又删除,Excel会保留这些行的记录,导致POI读取时认为它们存在,但实际无数据。通过空行过滤就能彻底解决这类问题。
内容的提问来源于stack exchange,提问作者Nisha
相关产品推荐
相关产品推荐

