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

Java实现Excel指定列过滤特定值时遇数字格式异常问题

解决Excel过滤时的NumberFormatException问题

问题原因

你遇到的NumberFormatException是因为:

  • 原代码仅判断单元格类型为CELL_TYPE_STRING,但Excel中部分单元格可能实际存储类型为数字/日期,但显示为文本,POI会识别为NUMERIC类型;
  • 当代码尝试对NUMERIC类型单元格调用getRichStringCellValue()时,会直接抛出该异常,因为该方法仅适用于字符串类型单元格。

另外原代码还存在两个潜在问题:

  1. findRow方法参数为HSSFSheet,但调用时传入的是XSSFSheet,会导致编译错误;
  2. 使用无泛型的原始List,代码规范性差,易引发类型转换问题。

解决方案

修改思路:

  1. 使用POI通用接口(Workbook/Sheet/Row)替代具体实现类,兼容不同Excel格式,避免类型不匹配;
  2. 新增工具方法统一处理所有单元格类型,将单元格内容转为字符串后再进行比较;
  3. 处理公式单元格,先计算实际值再转换;
  4. 使用泛型集合,规范代码逻辑。

修改后的完整代码

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class ExcelFilter {
    public static void main(String[] args) throws Exception {
        String fileName = "filepath";
        String cellContent = "Automation";
        int targetCol = 0; // 需要提取数据的目标列索引

        // 使用try-with-resources自动关闭资源,避免泄漏
        try (InputStream input = new FileInputStream(fileName);
             Workbook wb = new XSSFWorkbook(input)) {
            Sheet sheet = wb.getSheetAt(0);
            List<String> filteredResults = findMatchingRows(sheet, cellContent, targetCol);

            if (!filteredResults.isEmpty()) {
                for (String result : filteredResults) {
                    System.out.println(result);
                }
            }
        }
    }

    private static List<String> findMatchingRows(Sheet sheet, String targetContent, int targetCol) {
        List<String> results = new ArrayList<>();
        FormulaEvaluator evaluator = sheet.getWorkbook().getCreationHelper().createFormulaEvaluator();

        for (Row row : sheet) {
            for (Cell cell : row) {
                String cellValue = getCellStringValue(cell, evaluator);
                // 匹配目标内容时,提取目标列的单元格值
                if (cellValue.equals(targetContent)) {
                    Row targetRow = sheet.getRow(row.getRowNum());
                    if (targetRow != null) {
                        Cell targetCell = targetRow.getCell(targetCol);
                        results.add(getCellStringValue(targetCell, evaluator));
                    }
                }
            }
        }
        return results;
    }

    // 统一处理所有单元格类型,转为字符串
    private static String getCellStringValue(Cell cell, FormulaEvaluator evaluator) {
        if (cell == null) {
            return "";
        }

        // 先处理公式单元格,计算实际值
        if (cell.getCellType() == CellType.FORMULA) {
            Cell evaluatedCell = evaluator.evaluateInCell(cell);
            return getCellStringValue(evaluatedCell, evaluator);
        }

        switch (cell.getCellType()) {
            case STRING:
                return cell.getRichStringCellValue().getString().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    // 处理数字,避免科学计数法
                    double numValue = cell.getNumericCellValue();
                    return numValue == (long) numValue ? String.valueOf((long) numValue) : String.valueOf(numValue);
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue()).trim();
            case BLANK:
                return "";
            default:
                return "";
        }
    }
}

关键修改说明

  • 通用接口替换:用Workbook/Sheet替代XSSFWorkbook/XSSFSheet,同时兼容.xls和.xlsx格式,解决类型不匹配问题;
  • 单元格统一转换:getCellStringValue方法覆盖所有单元格类型(字符串、数字、日期、公式、布尔值),将内容转为字符串后再比较,彻底避免类型相关异常;
  • 资源自动管理:使用try-with-resources语法,自动关闭输入流和Workbook,无需手动处理资源释放;
  • 泛型集合:使用List<String>存储结果,代码更规范,避免后续输出时的类型转换问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:18:20