适用于Java的高级PDF解析器

时间:2011-03-27 14:36:51

标签: java parsing pdf

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

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

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

  • 文档元标记,如标题,描述或作者
  • 仅标题
  • 如果文档包含表单
  • ,则输入元素

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

更新

好的,我试过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

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

  • 链接
  • 文档元标记,如标题,描述或作者
  • 仅标题
  • 如果文档包含表单
  • ,则输入元素

5 个答案:

答案 0 :(得分:16)

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<String> dests = new ArrayList<String>();
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 Spec here

  
      
  • 输入元素
  •   

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

AcroFields fields = myReader.getAcroFields();

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

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

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

非常琐碎。是。

Map<String, String> info = myPdfReader.getInfo();
System.out.println( info );

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

  
      
  • 仅标题
  •   

TextRenderFilter可以根据您希望的标准忽略文字。字体大小根据您的评论发出正确的声音。

答案 1 :(得分:5)

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

  

阅读PDFS

     

iText不是PDF查看器,iText不能   将PDF转换为图像,也不能将iText转换为图像   用于打印PDF,但是   PdfReader类可以为您提供访问权限   形成PDF文档的对象   以及每个的内容流   页。这个内容流可以   解析,如果内容没有添加   作为栅格化文本,您可以转换为   页面到纯文本。请注意iText   不做OCR。

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

答案 4 :(得分:0)

大多数情况下你也可以使用our PDF Library extended edition

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

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