栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何知道某个字段是否在特定页面上?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何知道某个字段是否在特定页面上?

PDFbox内容流是按页面完成的,但是字段来自于来自目录的表单,该目录来自pdf doc本身。所以我不确定哪些字段在哪些页面上

其原因是PDF包含定义表单的全局对象结构。此结构中的表单字段在0、1或更多实际PDF页面上可能具有0、1或更多可视化效果。此外,在仅一个可视化的情况下,允许将现场对象和可视化对象合并。

PDFBox 1.8.x

不幸的是,PDFBox中的

PDAcroForm
PDField
对象仅表示此对象结构,无法轻松访问相关页面。但是,通过访问基础结构,您可以建立连接。

以下代码应明确说明如何执行此操作:

@SuppressWarnings("unchecked")public void printFormFields(PDdocument pdfDoc) throws IOException {    PDdocumentCatalog docCatalog = pdfDoc.getdocumentCatalog();    List<PDPage> pages = docCatalog.getAllPages();    Map<COSDictionary, Integer> pageNrByAnnotDict = new HashMap<COSDictionary, Integer>();    for (int i = 0; i < pages.size(); i++) {        PDPage page = pages.get(i);        for (PDAnnotation annotation : page.getAnnotations()) pageNrByAnnotDict.put(annotation.getDictionary(), i + 1);    }    PDAcroForm acroForm = docCatalog.getAcroForm();    for (PDField field : (List<PDField>)acroForm.getFields()) {        COSDictionary fieldDict = field.getDictionary();        List<Integer> annotationPages = new ArrayList<Integer>();        List<COSObjectable> kids = field.getKids();        if (kids != null) { for (COSObjectable kid : kids) {     COSbase kidObject = kid.getCOSObject();     if (kidObject instanceof COSDictionary)         annotationPages.add(pageNrByAnnotDict.get(kidObject)); }        }        Integer mergedPage = pageNrByAnnotDict.get(fieldDict);        if (mergedPage == null) if (annotationPages.isEmpty())     System.out.printf("i Field '%s' not referenced (invisible).n", field.getFullyQualifiedName()); else     System.out.printf("a Field '%s' referenced by separate annotation on %s.n", field.getFullyQualifiedName(), annotationPages);        else if (annotationPages.isEmpty())     System.out.printf("m Field '%s' referenced as merged on %s.n", field.getFullyQualifiedName(), mergedPage); else     System.out.printf("x Field '%s' referenced as merged on %s and by separate annotation on %s. (Not allowed!)n", field.getFullyQualifiedName(), mergedPage, annotationPages);    }}

当心 ,PDFBox

PDAcroForm
表单字段处理中有两个缺点:

  1. PDF规范允许定义表单的全局对象结构为一棵深树,即,实际字段不必是根的直接子代,而可以通过内部树节点来组织。PDFBox会忽略这一点,并希望这些字段是根的直接子代。

  2. 某些原始的PDF(最早的PDF)不包含域树,而仅通过可视化的窗口小部件注释引用页面中的域对象。PDFBox在其

    PDAcroForm.getFields
    列表中看不到这些字段。

PS:
@mikhailvs在他的答案中正确显示,您可以使用来从字段窗口小部件检索页面对象,

PDField.getWidget().getPage()
并使用确定其页码
catalog.getAllPages().indexOf
。这种
getPage()
方法虽然速度很快,但有一个缺点:它从小部件注释字典的
可选
条目中检索页面引用。因此,如果您处理的PDF是由填充该条目的软件创建的,那么一切都很好,但是,如果PDF创建者尚未填充该条目,那么您得到的只是一个
null
页面。

PDFBox 2.0.x

在2.0.x中,用于访问有问题的元素的某些方法已更改,但整体情况没有改变,要安全地检索小部件的页面,您仍然必须遍历页面并找到引用注释的页面。

安全方法:

int determineSafe(PDdocument document, PDAnnotationWidget widget) throws IOException{    COSDictionary widgetObject = widget.getCOSObject();    PDPageTree pages = document.getPages();    for (int i = 0; i < pages.getCount(); i++)    {        for (PDAnnotation annotation : pages.get(i).getAnnotations())        { COSDictionary annotationObject = annotation.getCOSObject(); if (annotationObject.equals(widgetObject))     return i;        }    }    return -1;}

快速方法

int determineFast(PDdocument document, PDAnnotationWidget widget){    PDPage page = widget.getPage();    return page != null ? document.getPages().indexOf(page) : -1;}

用法:

PDAcroForm acroForm = document.getdocumentCatalog().getAcroForm();if (acroForm != null){    for (PDField field : acroForm.getFieldTree())    {        System.out.println(field.getFullyQualifiedName());        for (PDAnnotationWidget widget : field.getWidgets())        { System.out.print(widget.getAnnotationName() != null ? widget.getAnnotationName() : "(NN)"); System.out.printf(" - fast: %s", determineFast(document, widget)); System.out.printf(" - safe: %sn", determineSafe(document, widget));        }    }}

( 确定小部件页面.java)

(与1.8.x代码相反,这里的安全方法只是搜索单个字段的页面。如果在代码中必须确定许多小部件的页面,则应

Map
像在1.8.x情况下那样创建查找。 )

示例文件

快速方法失败的文档:aFieldTwice.pdf

快速方法适用的文档:test_duplicate_field2.pdf



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/496184.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号