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

使用Apache POI通过正则匹配获取对应右侧单元格的值

用Apache POI实现Excel标签匹配取值(Python转Java)

我来帮你梳理下如何用Apache POI实现你要的功能——完全对应你原Python代码的逻辑,同时适配Excel单元格的各种类型问题。

首先明确你的核心需求:不依赖固定单元格位置,遍历Excel的行,检查每行E列(也就是每行的第一个单元格)的标签文本(忽略大小写),匹配到目标标签后,获取右侧F列(该行第二个单元格)的值赋值给对应变量。

先纠正下你伪代码里的小问题

你的伪代码里有两处小疏漏:

  • Iterator<Cell> = row.cellIterator(); 缺少变量名,应该是Iterator<Cell> cellIterator = row.cellIterator();
  • Apache POI的Cell类没有直接的matches()方法,需要先把单元格值转成字符串再做匹配

完整实现思路与代码

下面是可直接运行的Java代码,包含了单元格类型处理、空值防护、模糊匹配等关键细节:

import org.apache.poi.ss.usermodel.*;
import java.io.FileInputStream;
import java.io.IOException;

public class ExcelLabelExtractor {
    public static void main(String[] args) {
        String excelPath = "your-excel-file.xlsx"; // 替换成你的文件路径
        String invoiceNumber = null;
        String issueDate = null;
        Double amountDue = null;

        try (FileInputStream inputStream = new FileInputStream(excelPath);
             Workbook workbook = WorkbookFactory.create(inputStream)) {

            // 处理第一个工作表,你可以根据需要改成指定名称的sheet:workbook.getSheet("Sheet1")
            Sheet sheet = workbook.getSheetAt(0);
            Iterator<Row> rowIterator = sheet.iterator();

            while (rowIterator.hasNext()) {
                Row currentRow = rowIterator.next();
                
                // 跳过没有足够单元格的空行,避免索引越界
                if (currentRow.getPhysicalNumberOfCells() < 2) {
                    continue;
                }

                // 获取E列的标签单元格(索引0),空单元格转为空白处理
                Cell labelCell = currentRow.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                String labelText = getCellContentAsString(labelCell).trim().toLowerCase();

                // 匹配标签,获取右侧F列(索引1)的值
                if (labelText.contains("invoice number")) {
                    invoiceNumber = getCellContentAsString(currentRow.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                } else if (labelText.contains("issue date")) {
                    issueDate = getCellContentAsString(currentRow.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                } else if (labelText.contains("amount due")) {
                    // 金额可能是数字类型,单独处理避免转字符串时的精度问题
                    Cell valueCell = currentRow.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
                    if (valueCell.getCellType() == CellType.NUMERIC) {
                        amountDue = valueCell.getNumericCellValue();
                    } else {
                        // 兼容文本格式的金额
                        amountDue = Double.parseDouble(getCellContentAsString(valueCell));
                    }
                }
            }

            // 打印结果测试
            System.out.println("Invoice Number: " + invoiceNumber);
            System.out.println("Issue Date: " + issueDate);
            System.out.println("Amount Due: " + amountDue);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 统一处理不同类型的单元格,转为字符串返回
     * 支持文本、数字、日期、公式等类型
     */
    private static String getCellContentAsString(Cell cell) {
        if (cell == null) {
            return "";
        }

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    // 日期类型用DataFormatter转成Excel显示的格式
                    DataFormatter formatter = new DataFormatter();
                    return formatter.formatCellValue(cell);
                } else {
                    // 数字类型直接转字符串,避免科学计数法
                    return String.valueOf(cell.getNumericCellValue());
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                // 公式单元格计算出结果再处理
                FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
                return getCellContentAsString(evaluator.evaluateInCell(cell));
            default:
                return "";
        }
    }
}

关键细节说明

  1. 空值与异常防护:使用Row.MissingCellPolicy.CREATE_NULL_AS_BLANK把空单元格转为空白,避免空指针异常;同时跳过单元格数量不足的行,防止索引越界。
  2. 标签匹配逻辑:用toLowerCase()统一转小写后再用contains()匹配,和你原Python代码的lower().find()逻辑完全一致;如果需要更严格的正则匹配(比如允许标签间有多个空格),可以改成labelText.matches(".*invoice\\s+number.*")。
  3. 多类型单元格处理:封装了getCellContentAsString()方法,统一处理文本、数字、日期、公式等各种单元格类型,避免取值错误。
  4. 金额特殊处理:因为金额可能是数字类型,单独处理可以避免转字符串时出现精度问题,同时兼容文本格式的金额。

依赖配置(Maven为例)

确保你的项目引入了Apache POI的最新稳定版依赖:

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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:06:36