Java:Apache PDFbox提取突出显示的文本

我正在使用Apache PDFbox库从PDF文件中提取突出显示的文本(即黄色背景)。 我对这个库完全是新手,并且不知道它用于此目的的哪个类。 到目前为止,我已使用下面的代码从注释中提取文本。

PDDocument pddDocument = PDDocument.load(new File("test.pdf")); List allPages = pddDocument.getDocumentCatalog().getAllPages(); for (int i = 0; i < allPages.size(); i++) { int pageNum = i + 1; PDPage page = (PDPage) allPages.get(i); List la = page.getAnnotations(); if (la.size() < 1) { continue; } System.out.println("Total annotations = " + la.size()); System.out.println("\nProcess Page " + pageNum + "..."); // Just get the first annotation for testing PDAnnotation pdfAnnot = la.get(0); System.out.println("Getting text from comment = " + pdfAnnot.getContents()); 

现在我需要获得突出显示的文本,任何代码示例都将受到高度赞赏。

问题中的代码无法读取跨行突出显示的确切文本已经说明了用于从PDFBox页面上的有限内容区域提取文本的大多数概念。

在研究了这段代码后,OP仍在评论中表示:

但令我困惑的一件事是QuadPoints而不是Rect 。 正如你在评论中提到的那样。 这是什么,你可以用一些代码行或简单的词来解释它,因为我也面临同样的多行高亮问题?

通常,注释所指的区域是一个矩形:

Rect rectangle (必需)注释矩形,以默认用户空间单位定义页面上注释的位置。

(来自表164 – 所有注释词典共有的条目 – 在ISO 32000-1中)

对于某些注释类型(例如文本标记),此位置值不够,因为:

  • 标记的文本可以以某个奇数角写入,但说明书中提到的矩形类型是指边缘平行于页边的矩形; 和
  • 标记的文本可以从一行中的任何地方开始,然后在另一行中的任何地方结束,因此标记区域根本不是矩形,而是多个矩形部分的并集。

因此,为了处理这样的注释类型,PDF规范提供了一种更通用的方法来定义区域:

QuadPoints数组(必需)一个8×n数字的数组,指定默认用户空间中n个四边形的坐标。 每个四边形应包含注释背后的文本中的一个或一组连续单词。 每个四边形的坐标应按顺序给出

x 1 y 1 x 2 y 2 x 3 y 3 x 4 y 4

以逆时针顺序指定四边形的四个顶点(参见图64)。 文本应相对于连接点(x 1 ,y 1 )和(x 2 ,y 2 )的边缘定向。

(来自表179 – 特定于文本标记注释的附加条目 – 在ISO 32000-1中)

因此,而不是由给出的矩形

 PDRectangle rect = pdfAnnot.getRectangle(); 

在引用问题的代码中,您必须考虑由给定的四边形

 COSArray quadsArray = (COSArray) pdfAnnot.getDictionary().getDictionaryObject(COSName getPDFName("QuadPoints")); 

并相应地定义PDFTextStripperByArea stripper区域。 不幸的是, PDFTextStripperByArea.addRegion期望一个矩形作为参数,而不是一些通用的四边形。 由于文本通常是水平或垂直打印,因此不应造成太大问题。

PS关于QuadPoints规范的一个警告,订单可能在现实PDF中有所不同,参见 问题PDF规范与Acrobat创建(QuadPoints) 。

我希望这个答案可以帮助每个面临同样问题的人。

 // PDF32000-2008 // 12.5.2 Annotation Dictionaries // 12.5.6 Annotation Types // 12.5.6.10 Text Markup Annotations @SuppressWarnings({ "unchecked", "unused" }) public ArrayList getHighlightedText(String filePath, int pageNumber) throws IOException { ArrayList highlightedTexts = new ArrayList<>(); // this is the in-memory representation of the PDF document. // this will load a document from a file. PDDocument document = PDDocument.load(filePath); // this represents all pages in a PDF document. List allPages = document.getDocumentCatalog().getAllPages(); // this represents a single page in a PDF document. PDPage page = allPages.get(pageNumber); // get annotation dictionaries List annotations = page.getAnnotations(); for(int i=0; i 1) { str = str.concat(highlightedText); } else { str = highlightedText; } } highlightedTexts.add(str); } } document.close(); return highlightedTexts; }