如何解决CopyPagesTo 复制 Field 词典错误有修复建议或仅是错误的 PDF 输入文件的结果?
我正在处理由某个应用程序生成的 PDF 文档集合。在许多页面上都有带有一些 Javascript 代码的 PDF 小部件注释,可以在页面之间进行某种导航。我尝试将两个这样的文档与 iText 7.1.14(使用 PdfDocument.copyToPages
方法)合并,并注意到结果文件的交互性不再起作用。为了找出问题所在,我尝试用 PdfDocument.copyToPages
复制一个文档的一页,结果同样是错误的。
在对 RUPS 进行一些分析后,我注意到与 /Parent 字段字典的 /Kids 数组相关的潜在原因。 (See image of original document here) 我检查了 RUPS 使用 PdfDocument.copyPagesTo
生成的文件中的类似条目 (See image of copied document here) 在该文件中 /Kids 数组是空的,根据我对 PDF 参考 1.7 的理解不应该是(它应该指向现场父母的孩子)。
我不确定 iText7 的这种功能是 iText 的错误还是原始文件的 pdf 内容错误的结果。无论如何,我试图在 iText7 中找到处理生成该输出的代码。我找到了处理复制 /Parent 字典的 pdfpage.RebuildFormFieldParent
方法。
private void RebuildFormFieldParent(PdfDictionary field,PdfDictionary newField,PdfDocument todocument) {
if (newField.ContainsKey(PdfName.Parent)) {
return;
}
PdfDictionary oldParent = field.GetAsDictionary(PdfName.Parent);
if (oldParent != null) {
PdfDictionary newParent = oldParent.copyTo(todocument,JavaUtil.ArraysAsList(PdfName.P,PdfName.Kids,PdfName
.Parent),false);
if (newParent.IsFlushed()) {
newParent = oldParent.copyTo(todocument,PdfName.Parent),true
);
}
RebuildFormFieldParent(oldParent,newParent,todocument);
/**** ORIGINAL CODE BELOW *****/
PdfArray kids = newParent.GetAsArray(PdfName.Kids);
if (kids == null) {
newParent.Put(PdfName.Kids,new PdfArray());
}
/******************************/
newField.Put(PdfName.Parent,newParent);
}
}
经过一些分析后,我在方法末尾尝试了以下更改。
private void MyRebuildFormFieldParent(PdfDictionary field,PdfDocument todocument)
{
if (newField.ContainsKey(PdfName.Parent))
{
return;
}
PdfDictionary oldParent = field.GetAsDictionary(PdfName.Parent);
if (oldParent != null)
{
PdfDictionary newParent = oldParent.copyTo(todocument,false);
if (newParent.IsFlushed())
{
newParent = oldParent.copyTo(todocument,todocument);
/**** NEW CODE BELOW *****/
PdfArray kids = (PdfArray)(oldParent.GetAsArray(PdfName.Kids).copyTo(todocument,true));
if (kids == null)
{
newParent.Put(PdfName.Kids,new PdfArray());
}
else
{
newParent.Put(PdfName.Kids,kids);
}
/******************************/
newField.Put(PdfName.Parent,newParent);
}
更改后,我使用 PdfDocument.copyPagesTo
生成了文档副本。 RUPS 显示 expected content of /Kids array 并且交互性在复制文档中与原始文档类似。我不得不关闭 Smartcopy
模式(如果启用它会抛出 SmartModePdfObjectsSerializer.SelfReferenceException
)。对我来说,这是可以理解的,但可能是错误修复的结果。
有人可以验证 iText 中是否存在错误或 iText 运行良好但输入文件不遵循 PDF 参考吗?我也不确定(如果是错误)我的修复是否合适或仅适用于我的情况。
解决方法
我可以回答我自己的问题:问题出在输入文件中,而不是在 iText 中。
输入文件格式不正确导致pdf目录中没有/AcroForm字典。当打开原始文件时,Adobe Acrobat Reader 解释了每个页面中的字段,尽管 PDF 文件不规则,但交互仍然有效。因此,我没有怀疑有这样的问题。使用 PdfDocument.CopyPagesTo
复制格式错误的 PDF 文件后,字段字典格式不正确(/Kids 数组为空)并且交互性不再起作用。
当我以编程方式添加缺失的 /AcroForm 字典及其指向原始文件 PDF 文件中的根字段字典的 /Fields 数组并根据 PDF 参考规范制作输入文件时,PdfDocument.CopyPagesTo
正确复制了文档和原始文件的交互性已正确转移到复制的文档中。
我使用了 PdfDocument.CopyPagesTo
重载,它使用了 copier
参数引用 PdfPageFormCopier
的实例。
实际上,经过一些研究,我注意到使用这种格式错误的 PDF 文件(尽管文档中有 AcroForm 字段,但没有 /AcroForm 字典)调用 PdfDocument.CopyPagesTo
重载,copier
参数引用了 {{ 1}} 产生的结果与 if PdfPageFormCopier
重载 没有 PdfDocument.CopyPagesTo
参数将被调用以复制正确形成的输入文件。这意味着,当输入文件具有 Acrofields 时,在没有正确 copier
参数的情况下调用 CopyPagesTo
会生成不符合 PDF 参考的输出文件(它具有带有空 /Kids 数组的字段字典)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。