部分填写后,PDF表单将不再可编辑

时间:2018-11-01 09:31:18

标签: c# itext pdf-form pdfstamper

我遇到了Web API的问题,我收到了一个PDF文档(PDF表单)作为base64编码的字符串,将其制成文件,并填写了一些字段(使用 iTextSharp {{ 1}} 类),然后将结果作为base64编码的字符串发送回去,然后再次将其制成文件。

当我随后尝试使用 Foxit Reader 打开此文件/文档时,我仍然可以编辑字段,但是当使用 Adob​​e Acrobat Reader 尝试打开这些文件/文档时,这些字段是不再可编辑。

在打开属性页并在 Foxit Reader 中查看文档的安全性属性时,它表示已允许所有操作。 但是,在 Adob​​e Acrobat Reader 中进行相同操作时,它表示不允许进行注释,填充字段和签名(将其发送到API之前)。

不幸的是,我无法确定最终用户使用的是哪种PDF阅读器,因此我需要通用。

我可以看到许多其他人都发表了有关类似问题的信息,但是我看不到我的特定问题。

有人知道这里发生了什么以及如何解决吗?

编辑:已添加代码

我正在这样做(虽然简化了一点,但还是一样):

PdfStamper

编辑:添加了示例PDF文件

示例文件只是在Internet上找到的文件,我记得它是在此处的另一篇文章中链接的。

我已尝试在此PDF表单中填写2个字段(名字和姓氏)。

第一个文件是从base64字符串创建的表单。

d94b6076-983d-47db-b496-a0ba383deda4.pdf

第二文件是填写两个字段后的输出。

d94b6076-983d-47db-b496-a0ba383deda4_filled.pdf

1 个答案:

答案 0 :(得分:1)

您的PDF包含混合的AcroForm / XFA表单定义和使用权签名。这两个事实使填表变得复杂。

使用权签名

您的PDF包含一种特殊的数字签名,即使用权签名。用这种签名签名的PDF(使用Adobe为该任务生成的私钥)向Adobe Reader发出信号,表示在处理该PDF时,应激活某些其他Adobe Reader功能。

但是,如果签名无效,则Adobe Reader不仅不会激活那些额外的功能,甚至会取消激活某些其他功能,这些功能对于未签名的文档是有效的。

您可以这样创建PdfStamper

stamp = new PdfStamper(reader, new FileStream("path to filled PDF form file", FileMode.Create));

该构造函数未在 append 模式下初始化标记。因此,加盖的PDF最终被写为新的PDF。这会使使用权签名无效,并且Adobe Reader在再次打开PDF时会限制功能。

顺便说一句,使用Adobe Reader打开PDF时,程序会告诉您:

Adobe Reader pop-up

但是,如果以追加模式标记,则使用权利签名不会无效。您可以使用其他构造函数来做到这一点:

stamp = new PdfStamper(reader, new FileStream("path to filled PDF form file", FileMode.Create), '\0', true);

最后一个true激活附加模式。

或者您可以删除使用权签名

PdfReader reader = new PdfReader("path to PDF form file");
reader.RemoveUsageRights();

结果不再具有使用权签名,尤其是没有无效的签名。因此,Adobe Reader提供了此文件的标准功能。

不幸的是,其中没有保存XFA表单,因此可以编辑PDF但不能将其保存在Adobe Reader中。这可能不是您想要的。

关于这些选项,另请参见this old answer;该答案讨论的是“启用读者功能”,这是Adobe的“应用使用权限签名”一词。

混合XFA / AcroForm表单定义

该文件包含一个双重表单定义,一个是AcroForm表单定义,它是本机PDF表单类型,另一个是XFA表单定义,它是仅将PDF用作传输容器的XML格式。

XFA表单定义提供了更多功能,但仅Adobe软件完全支持。对于混合表单,iText对将数据填充到两个表单定义中的支持有限。但是,根据XFA定义中使用的确切功能,这可能会失败。

在这种情况下,您可能要删除XFA表单定义,而仅使用AcroForm。

reader.Catalog.GetAsDict(PdfName.ACROFORM).Remove(PdfName.XFA);

有关这种方法,请阅读this answer和本iText article