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

使用iText提取PDF高亮文本失败,求问题排查与方案建议

问题分析

你的代码无法提取高亮文本的核心原因有几个:

  1. 错误依赖CONTENTS字段:PDF的高亮注释中,CONTENTS字段通常存储注释备注文字,而非被高亮的页面文本,多数情况下这个字段为空。真正要通过注释的QuadPoints定位页面高亮区域,再提取对应文本。
  2. 未处理间接引用:注释数组(ANNOTS)中的元素可能是PdfIndirectReference类型,直接转PdfDictionary会失败,需先解析引用。
  3. 返回值未拼接结果:代码中highlightedText始终为空,没有将提取到的文本拼接进去。
更优实现方式(iText 7版本)

以下是修正后的代码,通过解析高亮注释的QuadPoints定位文本区域,再提取对应内容:

import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.kernel.pdf.canvas.parser.PdfTextExtractor;
import com.itextpdf.kernel.pdf.canvas.parser.filter.TextRegionEventFilter;
import com.itextpdf.kernel.pdf.canvas.parser.listener.FilteredTextEventListener;
import com.itextpdf.kernel.pdf.canvas.parser.listener.LocationTextExtractionStrategy;

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

public String getHighlightedText() {
    StringBuilder highlightedText = new StringBuilder();
    String pdfFilePath = "test.pdf";

    try (PdfReader reader = new PdfReader(pdfFilePath);
         PdfDocument pdfDoc = new PdfDocument(reader)) {

        for (int pageNum = 1; pageNum <= pdfDoc.getNumberOfPages(); pageNum++) {
            PdfPage page = pdfDoc.getPage(pageNum);
            PdfArray annotsArray = page.getPdfObject().getAsArray(PdfName.ANNOTS);

            if (annotsArray == null) {
                continue;
            }

            for (int i = 0; i < annotsArray.size(); i++) {
                PdfObject annotObj = annotsArray.get(i);
                // 处理间接引用
                if (annotObj instanceof PdfIndirectReference) {
                    annotObj = ((PdfIndirectReference) annotObj).getRefersTo();
                }
                if (!(annotObj instanceof PdfDictionary)) {
                    continue;
                }

                PdfDictionary annotDict = (PdfDictionary) annotObj;
                if (PdfName.HIGHLIGHT.equals(annotDict.getAsName(PdfName.SUBTYPE))) {
                    // 获取QuadPoints,每个高亮区域由8个数值组成(x1,y1,x2,y2,x3,y3,x4,y4)
                    PdfArray quadPoints = annotDict.getAsArray(PdfName.QuadPoints);
                    if (quadPoints == null) {
                        continue;
                    }

                    // 将QuadPoints转换为文本提取的过滤区域
                    List<Rectangle> rectangles = new ArrayList<>();
                    for (int j = 0; j < quadPoints.size(); j += 8) {
                        float x1 = quadPoints.getAsNumber(j).floatValue();
                        float y1 = quadPoints.getAsNumber(j + 1).floatValue();
                        float x3 = quadPoints.getAsNumber(j + 4).floatValue();
                        float y3 = quadPoints.getAsNumber(j + 5).floatValue();
                        // 构建矩形区域(取对角点即可)
                        rectangles.add(new Rectangle(Math.min(x1, x3), Math.min(y1, y3), Math.abs(x3 - x1), Math.abs(y3 - y1)));
                    }

                    // 提取指定区域的文本
                    TextRegionEventFilter filter = new TextRegionEventFilter(rectangles);
                    LocationTextExtractionStrategy strategy = new LocationTextExtractionStrategy();
                    FilteredTextEventListener filteredListener = new FilteredTextEventListener(strategy, filter);
                    String extractedText = PdfTextExtractor.getTextFromPage(page, filteredListener);

                    if (!extractedText.isEmpty()) {
                        highlightedText.append(extractedText).append("\n");
                    }
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return highlightedText.toString().trim();
}

说明:

  • 用QuadPoints定位高亮区域,这是PDF标准中存储高亮位置的字段。
  • 处理了注释的间接引用,避免类型转换失败。
  • 通过TextRegionEventFilter过滤指定区域文本,确保提取的是高亮内容。
  • 用StringBuilder高效拼接结果,减少内存浪费。
可用替代库
  • Apache PDFBox:Apache开源PDF处理库,API直观,支持注释解析和区域文本提取,是iText的主流替代方案。
  • PDFClown:跨平台PDF操作库,提供面向对象的API,支持注释和文本提取功能。
  • Aspose.PDF for Java:商业库,功能全面,对复杂PDF兼容性较好,但需付费授权。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 06:55:23