我正在使用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<PDAnnotation> 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());
现在我需要获得突出显示的文本,任何代码示例都将受到高度赞赏。
答案 0 :(得分:6)
我希望这个答案可以帮助每个面临同样问题的人。
// PDF32000-2008
// 12.5.2 Annotation Dictionaries
// 12.5.6 Annotation Types
// 12.5.6.10 Text Markup Annotations
@SuppressWarnings({ "unchecked", "unused" })
public ArrayList<String> getHighlightedText(String filePath, int pageNumber) throws IOException {
ArrayList<String> 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<PDPage> allPages = document.getDocumentCatalog().getAllPages();
// this represents a single page in a PDF document.
PDPage page = allPages.get(pageNumber);
// get annotation dictionaries
List<PDAnnotation> annotations = page.getAnnotations();
for(int i=0; i<annotations.size(); i++) {
// check subType
if(annotations.get(i).getSubtype().equals("Highlight")) {
// extract highlighted text
PDFTextStripperByArea stripperByArea = new PDFTextStripperByArea();
COSArray quadsArray = (COSArray) annotations.get(i).getDictionary().getDictionaryObject(COSName.getPDFName("QuadPoints"));
String str = null;
for(int j=1, k=0; j<=(quadsArray.size()/8); j++) {
COSFloat ULX = (COSFloat) quadsArray.get(0+k);
COSFloat ULY = (COSFloat) quadsArray.get(1+k);
COSFloat URX = (COSFloat) quadsArray.get(2+k);
COSFloat URY = (COSFloat) quadsArray.get(3+k);
COSFloat LLX = (COSFloat) quadsArray.get(4+k);
COSFloat LLY = (COSFloat) quadsArray.get(5+k);
COSFloat LRX = (COSFloat) quadsArray.get(6+k);
COSFloat LRY = (COSFloat) quadsArray.get(7+k);
k+=8;
float ulx = ULX.floatValue() - 1; // upper left x.
float uly = ULY.floatValue(); // upper left y.
float width = URX.floatValue() - LLX.floatValue(); // calculated by upperRightX - lowerLeftX.
float height = URY.floatValue() - LLY.floatValue(); // calculated by upperRightY - lowerLeftY.
PDRectangle pageSize = page.getMediaBox();
uly = pageSize.getHeight() - uly;
Rectangle2D.Float rectangle_2 = new Rectangle2D.Float(ulx, uly, width, height);
stripperByArea.addRegion("highlightedRegion", rectangle_2);
stripperByArea.extractRegions(page);
String highlightedText = stripperByArea.getTextForRegion("highlightedRegion");
if(j > 1) {
str = str.concat(highlightedText);
} else {
str = highlightedText;
}
}
highlightedTexts.add(str);
}
}
document.close();
return highlightedTexts;
}
答案 1 :(得分:4)
问题Not able to read the exact text highlighted across the lines中的代码已经说明了用于从PDFBox页面上的有限内容区域提取文本的大多数概念。
在研究了这段代码后,OP仍在评论中表示:
但令我困惑的一件事是 QuadPoints 而不是 Rect 。正如你在评论中提到的那样。这是什么,你可以用一些代码行或用简单的词来解释它,因为我也面临着多行高亮的同样问题吗?
通常,注释引用的区域是矩形:
Rect 矩形(必填)注释矩形,以默认用户空间单位定义页面上注释的位置。
(来自表164 - 所有注释词典共有的条目 - 在ISO 32000-1中)
对于某些注释类型(例如文本标记),此位置值不够,因为:
因此,为了处理这些注释类型,PDF规范提供了一种更通用的方法来定义区域:
QuadPoints array (必需)一个8×n数字的数组,用于指定默认用户空间中n个四边形的坐标。每个四边形应包含注释背后的文本中的一个或一组连续单词。每个四边形的坐标应按顺序
给出x 1 y 1 x 2 y 2 x 3 y < sub> 3 x 4 y 4
以逆时针顺序指定四边形的四个顶点(参见图64)。文本应相对于边连接点(x 1 ,y 1 )和(x 2 ,y 2) 子>)。
(来自表179 - 特定于文本标记注释的附加条目 - 在ISO 32000-1中)
因此,而不是
给出的矩形PDRectangle rect = pdfAnnot.getRectangle();
在referenced question的代码中,您必须考虑
给出的四边形COSArray quadsArray = (COSArray) pdfAnnot.getDictionary().getDictionaryObject(COSName getPDFName("QuadPoints"));
并相应地定义PDFTextStripperByArea stripper
的区域。不幸的是PDFTextStripperByArea.addRegion
期望一个矩形作为参数,而不是一些通用的四边形。由于文本通常是水平或垂直打印,因此不会造成太大问题。
PS 有关 QuadPoints 规范的一个警告,该命令在现实PDF中可能有所不同,参见问题PDF Spec vs Acrobat creation (QuadPoints)。