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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 18:24:06