PDFBOX 2.0.18 - 如何遍历 PDF 页面并检索特定字段

Posted

技术标签:

【中文标题】PDFBOX 2.0.18 - 如何遍历 PDF 页面并检索特定字段【英文标题】:PDFBOX 2.0.18 - How to iterates through pages of a PDF and retrieve specific fields 【发布时间】:2020-06-25 20:40:09 【问题描述】:

我正在使用 PDFBox 读取 pdf 文档中的特定字段。实际上,我可以通过仅包含一页的 pdf 获得我想要的所有信息。 PDF 包含具有特定名称的字段,我可以获取所有字段并将其插入数据库。

我将此代码与 AccroForm 一起使用来访问字段

InputStream document = item.getInputStream();
pdf = PDDocument.load(new RandomAccessBufferedFileInputStream(document));
pdCatalog = pdf.getDocumentCatalog();
pdAcroForm = pdCatalog.getAcroForm();

String dateRapport = pdAcroForm.getField("import_Date01").getValueAsString();
String radioReason = pdAcroForm.getField("NoFlight").getValueAsString();
boolean hasdata = false;

if(radioRaison.length() > 0 && !radioRaison.equals("Off")) 
    if(radioRaison.equals("NR")) 
        rvhi.setRaison(obtenirRaison(raisons, "NR"));
    else if(radioRaison.equals("WX")) 
        rvhi.setRaison(obtenirRaison(raisons, "ME"));
    else if(radioRaison.equals("US")) 
        rvhi.setRaison(obtenirRaison(raisons, "BR"));
    

if(pdAcroForm.getField("import_Hmn0"+indexEnString).getValueAsString().length() > 0) 

    hasdata = true


pdf.close();

return hasdata;

现在,我的问题是对包含多个具有相同字段名称但字段数据不同的相同页面的 pdf 执行相同的操作。我想遍历每个页面并调用相同的方法并检索每个页面上的字段数据。

我使用下面的代码来遍历 pdf 的页面,但我不知道如何获取当前页面上的字段...我不知道如何从 PDPage 对象中获取 acroform 字段?

PDPageTree nbPages = pdf.getPages();

if(nbPages.getCount() > 1) 
    for(PDPage page : nbPages) 
        ???? how to get fields Acroform from PDPage page ???
    

提前感谢您的回复!

【问题讨论】:

【参考方案1】:

当前页面没有PDField 对象列表之类的东西; AcroForm 是文档范围的。因此,您问题的第一部分已经获得了文档中的完整字段列表。 (Adobe 的 PDF 规范中的 12.7.1)

字段可以具有相同的完全限定名称,但它们的值也必须相同。 (PDF 规范中的 12.7.3.2)

您的文档中可能发生的情况是字段的部分名称相同,但完全限定名称不同。完全限定名称由字段名称和祖先对象名称连接而成,如"parent partial name"."child partial name"

因此,基本上您必须使用完全限定名称来查找字段,或者您需要遍历字段列表以查找文档中的所有字段。

您可以找到显示特定字段的页面,因为字段使用注释(小部件注释)在页面上显示自己。这些注释确实存在于页面级别的Annots 数组中。 pdfbox中是否有方便的功能可以轻松做到这一点,我不知道。

【讨论】:

field.getWidgets() 获取小部件注释,widget.getPage() 获取页面。 PDPage.getAnnotations() 获取页面上的注释。您可以通过 getCOSObject() 在 COS 级别执行此操作来比较页面是否相同。 "widget.getPage() 获取页面" - widget.getPage() 返回的条目值是可选的。 还可以将页面注解的COSObject与widget注解的COSObeject进行比较。【参考方案2】:

抱歉回复晚了... 谢谢@DavidvanDriessche。为了找到 fullQualifiedName 的组成,我使用了一个小函数来列出所有字段及其子节点(如果有的话)。事实证明,对于文档的第二页,页码被指定为父部分名称。例如,第一页有“fieldNameExample.fieldNameExmaple”作为完全限定名,第二页有“1.fieldNameExample”作为完全限定名。所以我可以假设对于每个后续页面,它将是页码。fieldNameExample 作为完全限定名称。

感谢大家的帮助!

【讨论】:

以上是关于PDFBOX 2.0.18 - 如何遍历 PDF 页面并检索特定字段的主要内容,如果未能解决你的问题,请参考以下文章

使用 pdfbox 编辑 pdf 页面

使用 pdfBox 禁用 pdf 文本搜索

PDFBOX 生成非常大的 PDF/A 文件

java中使用pdfbox对pdf文件进行操作时,如何实现插入文本的自动换行操作?

使用 PDFBox 从 PDF 文档中读取特定页面

如何使用 PDFBox 使文本居中