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

使用POI读取Excel空单元格问题:空单元格被填充为上一单元格内容

Apache POI 4.1.2读取Excel时空单元格被填充为上一行内容的问题及解决

问题现象

  • Excel文件中部分行的月份列存在空单元格,但读取后存入数据库时,这些空单元格被自动填充为上一行对应列的内容
  • 数据库存储结果显示原本为空的单元格被上一行的数值覆盖

使用的Apache POI依赖

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>

问题代码

@RequestMapping("/mng/mngSaupExcelUpload14.do")
public ModelAndView mngBizApplyExcelUpload14(MultipartHttpServletRequest request, HttpServletResponse response,
        HttpSession session, INDEYearVO attach) throws IOException, ParseException {
    
    Iterator<String> iterator = request.getFileNames();
    int actResult = 0;
    ModelAndView mav = new ModelAndView();
    response.setContentType("text/html");
    response.setCharacterEncoding("UTF-8");
    PrintWriter out = response.getWriter();
    
    MultipartFile mFile = null;
    while (iterator.hasNext()) {
        String uploadFileName = iterator.next();
        mFile = request.getFile(uploadFileName);
    }
    
    XSSFWorkbook workbook = new XSSFWorkbook(mFile.getInputStream());
    
    for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
        XSSFSheet sheet = workbook.getSheetAt(sheetNum);
        int rows = sheet.getPhysicalNumberOfRows();
        int rowindex = 0;
        int columnindex = 0;
        
        if (sheetNum == 0) {
            for (rowindex = 1; rowindex < rows; rowindex++) {
                sheet = workbook.getSheetAt(0);
                XSSFRow row = sheet.getRow(rowindex);
                if (row != null) {
                    int cells = row.getPhysicalNumberOfCells();
                    for (columnindex = 0; columnindex <= cells; columnindex++) {
                        XSSFCell cell = row.getCell(columnindex);
                        String value = "";
                        
                        if (cell == null) {
                            continue;
                        } else {
                            switch (cell.getCellType()) {
                                case FORMULA:
                                    value = cell.getCellFormula();
                                    break;
                                case NUMERIC:
                                    double cellValue = cell.getNumericCellValue();
                                    if (cellValue == Math.rint(cellValue)) {
                                        value = String.valueOf((int) cellValue);
                                    } else {
                                        value = String.valueOf(cellValue);
                                    }
                                    break;
                                case STRING:
                                    value = cell.getStringCellValue() + "";
                                    break;
                                case BLANK:
                                    value = null;
                                    break;
                                case ERROR:
                                    value = cell.getErrorCellValue() + "";
                                    break;
                                default:
                            }
                            if (columnindex == 0) {
                                attach.setSn(Integer.parseInt(value));
                            } else if (columnindex == 1) {
                                attach.setYear(Integer.parseInt(value));
                            } else if (columnindex == 2) {
                                attach.setSigngu(value);
                            } else if (columnindex == 3) {
                                attach.setJan(Integer.parseInt(value));
                            } else if (columnindex == 4) {
                                attach.setFeb(Integer.parseInt(value));                                 
                            } else if (columnindex == 5) {
                                attach.setMar(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 6) {
                                attach.setApr(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 7) {
                                attach.setMay(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 8) {
                                attach.setJne(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 9) {
                                attach.setJly(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 10) {
                                attach.setAug(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 11) {
                                attach.setSep(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 12) {
                                attach.setOct(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 13) {
                                attach.setNov(Integer.parseInt(value));                                                                     
                            } else if (columnindex == 14) {
                                if ("false".equals(value) || "".equals(value) || "0".equals(value) || value == null ) {
                                    attach.setDec(Integer.parseInt(""));
                                } else {
                                    attach.setDec(Integer.parseInt(value));                                                                     
                                }
                            } 
                        }
                    }
                    actResult = attachFileService.fileInsertActForExcel14(attach);
                }
            }
        }
    }
    if (actResult > 0) {
        out.println("<script>");
        out.println("alert('등록에 성공 하였습니다.');");
        out.println("location.replace('" + request.getContextPath() + "attachFile.do');");
        out.println("</script>");
        out.flush();
        out.close();
        return null;
    } else {
        out.println("<script>");
        out.println("alert('등록 중 오류가 발생했습니다.');");
        out.println("location.replace('" + request.getContextPath() + "attachFile.do');");
        out.println("</script>");
        out.flush();
        out.close();
        return null;
    }
}

问题原因

  1. 复用VO对象:方法参数传入的INDEYearVO attach被所有行复用,每一行处理时如果某个单元格为空(或未被遍历到),该属性会保留上一行设置的值,导致存入数据库时出现上一行的内容。
  2. 单元格遍历逻辑缺陷:row.getPhysicalNumberOfCells()仅返回当前行中有实际数据的单元格数量,对于空单元格(未被创建的cell)会直接跳过,没有对对应的VO属性进行清空操作。
  3. 空单元格处理不完善:当cell为null时直接continue,没有处理对应的VO属性;BLANK类型设置value为null,但部分属性赋值时没有处理null情况,导致旧值残留。

解决办法

1. 每行创建新的VO实例

在处理每一行数据前,创建新的INDEYearVO对象,避免复用旧对象的属性值。

2. 遍历所有需要处理的列

固定遍历0到14列(对应业务中的所有字段),而不是仅遍历存在数据的单元格,确保每一列都被处理,包括空单元格。

3. 完善空单元格的赋值逻辑

对于空单元格(cell为null或BLANK类型),明确设置对应的VO属性为null或默认值,避免旧值残留。

修改后的核心代码示例

if (sheetNum == 0) {
    for (rowindex = 1; rowindex < rows; rowindex++) {
        // 每行创建新的VO实例
        INDEYearVO attach = new INDEYearVO();
        XSSFRow row = sheet.getRow(rowindex);
        if (row != null) {
            // 遍历所有需要处理的列(0到14)
            for (columnindex = 0; columnindex <= 14; columnindex++) {
                XSSFCell cell = row.getCell(columnindex);
                String value = "";
                
                if (cell == null || cell.getCellType() == CellType.BLANK) {
                    // 空单元格设置value为null
                    value = null;
                } else {
                    switch (cell.getCellType()) {
                        case FORMULA:
                            value = cell.getCellFormula();
                            break;
                        case NUMERIC:
                            double cellValue = cell.getNumericCellValue();
                            if (cellValue == Math.rint(cellValue)) {
                                value = String.valueOf((int) cellValue);
                            } else {
                                value = String.valueOf(cellValue);
                            }
                            break;
                        case STRING:
                            value = cell.getStringCellValue().trim();
                            break;
                        case ERROR:
                            value = String.valueOf(cell.getErrorCellValue());
                            break;
                        default:
                            value = null;
                    }
                }
                
                // 根据列索引设置VO属性,处理null情况
                if (columnindex == 0) {
                    attach.setSn(value != null ? Integer.parseInt(value) : null);
                } else if (columnindex == 1) {
                    attach.setYear(value != null ? Integer.parseInt(value) : null);
                } else if (columnindex == 2) {
                    attach.setSigngu(value);
                } else if (columnindex == 3) {
                    attach.setJan(value != null ? Integer.parseInt(value) : null);
                } else if (columnindex == 4) {
                    attach.setFeb(value != null ? Integer.parseInt(value) : null);                                 
                } else if (columnindex == 5) {
                    attach.setMar(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 6) {
                    attach.setApr(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 7) {
                    attach.setMay(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 8) {
                    attach.setJne(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 9) {
                    attach.setJly(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 10) {
                    attach.setAug(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 11) {
                    attach.setSep(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 12) {
                    attach.setOct(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 13) {
                    attach.setNov(value != null ? Integer.parseInt(value) : null);                                                                     
                } else if (columnindex == 14) {
                    if (value == null || "false".equals(value) || "".equals(value) || "0".equals(value)) {
                        attach.setDec(null);
                    } else {
                        attach.setDec(Integer.parseInt(value));                                                                     
                    }
                } 
            }
            actResult = attachFileService.fileInsertActForExcel14(attach);
        }
    }
}

额外注意事项

  • 确保INDEYearVO的属性支持null值(对应数据库字段允许为空),否则需要设置默认值(如0)。
  • 处理Integer.parseInt时,要确保value不为null且是有效数字,避免抛出NumberFormatException,可以添加异常捕获或提前校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:40:39