适用于Java的高级PDF解析器

我想从Java中提取PDF文件中的不同内容:

  • 完整的可见文字
  • 图片
  • 链接

是否也可以得到以下内容?

  • 文档元标记,如标题,描述或作者
  • 只是头条新闻
  • 如果文档包含表单,则输入元素

我不需要操纵或渲染PDF文件。 哪个库最适合这种用途?

UPDATE

好的,我试过PDFBox:

Document luceneDocument = LucenePDFDocument.getDocument(new File(path)); Field contents = luceneDocument.getField("contents"); System.out.println(contents.stringValue()); 

但输出为空。 虽然字段“摘要”是可以的。

下一个片段工作正常。

 PDDocument doc = PDDocument.load(path); PDFTextStripper stripper = new PDFTextStripper(); String text = stripper.getText(doc); System.out.println(text); doc.close(); 

但是,我不知道如何提取图像,链接等。

更新2

我找到了一个如何提取图像的例子,但我仍然没有得到如何提取的答案:

  • 链接
  • 文档元标记,如标题,描述或作者
  • 只是头条新闻
  • 如果文档包含表单,则输入元素

iText是我最近选择的PDF工具。

  • 完整的可见文字

“可见”是一个艰难的。 您可以使用com.itextpdf.text.pdf.parse包的类解析所有可解析的文本…但这些类不了解CLIPPING。 您可以轻松地将解析器限制为页面大小。

 // all text on the page, regardless of position PdfTextExtractor.getTextFromPage(reader, pageNum); 

您实际上需要采用TextExtractionStrategy的过滤,即过滤策略。 它很快就会变得有趣,但我认为你可以在这里“开箱即用”。

  • 图片

是的,通过相同的包类。 图像侦听器不像文本侦听器那样受支持,但确实存在。

  • 链接

是。 链接是各种PDF页面的“注释”。 找到它们只需循环遍历每个页面的“注释数组”并选择链接注释即可。

 PdfDictionary pageDict = myReader.getPageN(1); PdfArray annots = pageDict.getAsArray(PdfName.ANNOTS); ArrayList dests = new ArrayList(); if (annots != null) { for (int i = 0; i < annots.size(); ++i) { PdfDictionary annotDict = annots.getAsDict(i); PdfName subType = annotDict.getAsName(PdfName.SUBTYPE); if (subType != null && PdfName.LINK.equals(subType)) { PdfDictionary action = annotDict.getAsDict(PdfName.A); if (action != null && PdfName.URI.equals(action.getAsName(PdfName.S)) { dests.add(action.getAsString(PdfName.URI).toString()); } // else { its an internal link, meh } } } } 

您可以在此处找到PDF规范 。

  • 输入元素

当然。 对于XFA(LiveCycle Designer)或旧技术“AcroForm”表单,iText可以找到所有字段及其值。

 AcroFields fields = myReader.getAcroFields(); Set fieldNames = fields.getFields().keySet(); for (String fldName : fieldNames) { System.out.println( fldName + ": " + fields.getField( fldName ) ); } 

Mutli-select列表不能很好地处理。 对于空文本字段和按钮,冒号后面会有一个空格。 没有太多信息......但这会让你开始。

  • 文档元标记,如标题,描述或作者

很琐碎。 是。

 Map info = myPdfReader.getInfo(); System.out.println( info ); 

除了基本作者/标题/等之外,您还可以通过reader.getMetadata()访问相当复杂的XML模式。

  • 只是头条新闻

TextRenderFilter可以根据您希望的任何条件忽略文本。 字体大小根据您的评论发出正确的声音。

阿帕奇再一次来救援。

您还可以将JPedal用于所有这些提取任务。

是的Alp, iText确实提供了您提到的function。

阅读PDF

iText不是PDF查看器,iText不能将PDF转换为图像,iText也不能用于打印PDF,但PdfReader类可以让您访问构成PDF文档和内容流的对象每页。 可以解析此内容流,如果内容未添加为光栅化文本,则可以将页面转换为纯文本。 请注意,iText不执行OCR。

使用com.itextpdf.text.pdf.PdfReader; 类。

大多数情况下,您也可以使用我们的PDF库扩展版 。

无论您采用哪种解决方案,请记住,对于某些PDF文档,由于构建PDF的方式,文本提取是不可能的(页面上的字形有时不具有与之相关的任何语义含义)。

检查此问题的快速方法是在Acrobat中打开文档并尝试复制/粘贴文本。 如果它在那里出现乱码,那么它可能会在任何其他PDF提取器中变成乱码。