【问题标题】:Advanced PDF parser for JavaJava的高级PDF解析器
【发布时间】:2011-07-23 22:08:33
【问题描述】:

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

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

是不是也可以得到以下?

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

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

更新

好的,我试过 PDFBox:

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

但输出为空。不过,“摘要”字段是可以的。

下一个 sn-p 工作正常。

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

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

更新 2

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

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

【问题讨论】:

  • 结帐 iText itextpdf.com
  • 感谢巴拉的建议。创建者自己说“iText 的主要目的是创建和操作 PDF 文档。”。你确定它提供了我需要的功能吗?
  • 我之前使用过 iText,它是一个非常强大的产品。它应该能够处理您的所有任务。不过请注意许可证。上次我检查它是 GPL/ALGO,恕我直言,这不是一个超级好的许可证。

标签: java parsing pdf


【解决方案1】:

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 );

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

  • 仅标题

TextRenderFilter 可以根据您希望的任何标准忽略文本。根据您的评论,字体大小听起来很合适。

【讨论】:

  • 感谢您的回答。 “输入元素”在我的列表中意外出现了两次,它们之间没有区别。我看了一下 PDFBox,我想现在是测试 iText 的时候了。对于“仅标题”,我的意思是过滤掉 HTML 中的

    标签,如果有可能的话。

  • 有点,是的。 com.itextpdf.text.pdf.parser.FilteredRenderListener 可以按字体大小(和/或颜色、字体等)过滤。
  • 您好 Mark Storer,我已经使用您上面描述的方法来检索注释(内部锚点和嵌入式链接)。但在“subType”中没有得到任何价值。 :(
  • 它在子类型中返回空值:(
  • 如何应用文本大小过滤器?如何从 pdf 中获取现有内容的文本大小。我需要帮助。 @MarkStorer
【解决方案2】:
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    您也可以使用our PDF Library extended edition 完成大部分操作。

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

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

    【讨论】:

      【解决方案5】:

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

      阅读 PDF

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-15
        • 2011-05-14
        • 2021-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多