Apache POI从字符串单元格读NUMERIC值报错及行跳过、断言不匹配问题
问题根因定位
读取Excel阶段报错与内容错乱原因
- switch分支缺失
break导致全流程穿透:处理任意类型单元格时,执行完当前case的读取逻辑后,未终止分支流程,会依次执行后续所有case的代码- 对字符串类型单元格,会直接落入数值处理分支,调用
getNumericCellValue()触发Cannot get a NUMERIC value from a string cell报错 - 就算未触发报错,每个单元格的值也会被重复叠加到结果列表中,导致列内容完全错乱,无法匹配预期的测试值
- 对字符串类型单元格,会直接落入数值处理分支,调用
- 代码块大括号配对错位:原
case NUMERIC块的日期判断逻辑边界混乱,进一步放大了代码块执行的逻辑错误
写入Excel阶段跳行、测试断言不匹配原因
- 数据行索引错误:原代码创建人员数据行时使用
sheet.createRow(2),对应行索引2(Excel界面显示的第3行),跳过了索引1的位置,生成的Excel中表头和数据中间存在一整行空白 - POI迭代特性影响:
for (Row row : sheet)仅遍历已被显式创建的行对象,未创建的空白行不会进入迭代流程,配合读阶段的分支穿透报错,导致断言逻辑无法正常执行
分步修复方案
1. 修复readExcel方法的逻辑错误
- 给每个
case分支补全break语句,阻断分支穿透 - 修正大括号配对,将类型判断逻辑严格限制在对应case块内
- 适配POI版本的废弃方法:POI 4.0+版本中
getCellTypeEnum()已被废弃,替换为getCellType()即可,核心读取逻辑保持一致
修复后的核心读取逻辑示例:
for (Row row : sheet) { data.put(i, new ArrayList<String>()); for (Cell cell : row) { switch (cell.getCellType()) { // 替换废弃的getCellTypeEnum() case STRING: data.get(i).add(cell.getRichStringCellValue().getString()); break; // 阻断分支穿透 case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { data.get(i).add(cell.getDateCellValue().toString()); } else { data.get(i).add(String.valueOf(cell.getNumericCellValue())); } break; // 阻断分支穿透 case BOOLEAN: data.get(i).add(String.valueOf(cell.getBooleanCellValue())); break; // 阻断分支穿透 case FORMULA: data.get(i).add(cell.getCellFormula()); break; // 阻断分支穿透 default: data.get(i).add(" "); } } i++; }
注:原代码中case NUMERIC块结尾的错位分号、手动new Integer(i)的冗余写法可在整理代码时一并修正,不影响核心功能
2. 修复writeExcel方法的行索引错位
- 将原代码中创建数据行的
sheet.createRow(2)修改为sheet.createRow(1),与表头行(索引0)紧挨着摆放,实现“表头下一行直接写入数据”的预期 - 修正后Excel的实际行结构:
- 行索引0(Excel第1行):表头(Name/Age)
- 行索引1(Excel第2行):人员数据(John Smith/20)
- 不存在中间的空白隔行
修复后的写数据片段:
// 原代码为sheet.createRow(2),修改为紧邻表头的下一行 Row row = sheet.createRow(1); Cell cell = row.createCell(0); cell.setCellValue("John Smith"); cell.setCellStyle(style); cell = row.createCell(1); cell.setCellValue(20); cell.setCellStyle(style);
3. 适配测试逻辑
- 行索引修正后,读取流程会按顺序拿到行0(表头)、行1(人员数据),返回的map中键0对应表头值、键1对应人员数据,与原测试代码的断言预期完全匹配,无需修改测试逻辑
- 保持文件路径拼接逻辑一致,避免出现文件找不到的问题
内容的提问来源于stack exchange,提问作者micah kam
相关产品推荐
相关产品推荐

