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

基于PDFBox的PDFTextStripper:如何提取指定关键词后的文本?

实现PDFBox精准提取触发词后的文本

当然可以做到!作为经常用PDFBox处理这类文本提取需求的开发者,我给你分享一个直接可行的方案——通过自定义PDFTextStripper子类来实现精准的文本过滤,完全符合你要的「仅提取QUANTITY之后文本、仅命中后行加入列表」的需求。

核心思路

PDFTextStripper本身是按文本块(通常对应视觉上的行)来处理PDF内容的,我们可以通过继承它,添加一个开关变量来控制何时开始收集文本:

  • 初始化一个布尔标记startExtracting,默认关闭
  • 重写文本处理方法,每处理一段文本就检查是否包含触发词QUANTITY
  • 一旦检测到触发词,打开开关;之后所有的文本块(行)都加入结果列表

具体代码实现

下面是完整的可运行示例代码,你可以直接调整后使用:

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class QuantityFilteredStripper extends PDFTextStripper {
    // 触发开关,默认未激活
    private boolean startExtracting = false;
    // 存储提取到的目标行
    private final List<String> targetLines = new ArrayList<>();
    // 定义要匹配的触发字符串
    private static final String TRIGGER = "QUANTITY";

    public QuantityFilteredStripper() throws IOException {
        super();
        // 开启按视觉位置排序,避免PDF文本乱序
        setSortByPosition(true);
    }

    @Override
    protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
        // 检查当前行是否包含触发词
        if (text.contains(TRIGGER)) {
            startExtracting = true;
            // 如果不需要包含QUANTITY所在行,直接return;需要的话就取消下面的注释
            // targetLines.add(text.trim());
            return;
        }

        // 开关激活后,收集当前行文本
        if (startExtracting) {
            targetLines.add(text.trim());
        }

        // 调用父类方法完成默认处理
        super.writeString(text, textPositions);
    }

    // 获取最终提取的文本列表
    public List<String> getTargetLines() {
        return targetLines;
    }

    // 测试入口
    public static void main(String[] args) {
        try (PDDocument doc = PDDocument.load(new File("your-pdf-file.pdf"))) {
            QuantityFilteredStripper stripper = new QuantityFilteredStripper();
            // 触发文本处理(这里不需要接收返回值,我们直接取targetLines)
            stripper.getText(doc);
            // 输出结果
            for (String line : stripper.getTargetLines()) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

注意事项

  • 文本块与行的对应:大部分情况下writeString处理的是视觉上的一行,但某些复杂PDF可能会把一行拆成多个文本块。如果遇到这种情况,可以考虑重写processTextPosition方法逐字符跟踪,或者先确保setSortByPosition(true)开启,保证文本顺序正确。
  • 触发词跨块的情况:如果QUANTITY被拆成了多个文本块(比如Q在一个块,UANTITY在另一个),需要额外做字符累计匹配,这种场景比较少见,但可以通过在子类中维护一个临时字符串来解决。
  • 依赖版本:确保使用最新稳定版的PDFBox,避免兼容性问题。如果用Maven,依赖配置如下:
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.32</version> <!-- 替换为最新稳定版 -->
</dependency>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 12:33:15