【问题标题】:Why is my PDF's Acroform checkbox annotation not rendering in Acrobat Reader?为什么我的 PDF 的 Acroform 复选框注释未在 Acrobat Reader 中呈现?
【发布时间】:2020-06-03 22:05:07
【问题描述】:

我正在编写一些生成 PDF 文档的代码。我正在为可编辑的 PDF 表单生成 Acroform 复选框注释,这些注释在我正在测试的大多数 PDF 阅读器中表现得非常好:Chrome、Firefox、Mac Preview 和 PDF Element 6。但是,我真的很挣扎在 Acrobat Reader 中正确呈现这些内容。

我一直在制作一个最小的示例 PDF,它只包含一个复选框,没有其他内容。

当我悬停/单击复选框时,损坏的 PDF 在 Acrobat Reader 中的外观如下:

默认情况下复选框是不可见的。当我将鼠标悬停在复选框上时,会显示边框。但是当我点击复选框时,该值不是持久的,再次点击它不会做任何事情。

它应该是这样的(来自 Adob​​e Acrobat 的工作 PDF):

以下是 PDF 的一些链接:

我已使用veraPDF 验证了这两个 PDF。两个 PDF 都有少量类似的验证错误,所以这并没有帮助我找出差异。

我什至尝试直接从工作 PDF 中复制 XObject 流,如果您查看 /AP => /N => /Yes 流,您应该会发现它们几乎相同:

1 g
0 0 36.029 36.029 re
f
0.5 0.5 35.029 35.029 re
s
q
1 1 34.029 34.029 re
W
n
0 g
BT
/ZaDb 33.4305 Tf
2.853 6.3838 Td
32.8405 TL
0 0 Td
(4) Tj
ET
Q

(这是一个非常简单的流,仅使用 ZapfDingbats 字体显示复选标记。)

很遗憾,我无法分享任何具体的代码示例。我正在使用 Ruby 和 Prawn,但我也有很多低级专有代码(Prawn 实际上并不支持 Acroform 注释。)我只需要了解这些 PDF 之间的主要区别并找出其中的原因在另一个正确渲染时被破坏,然后我将能够在我的代码中进行更改。

如果您熟悉 PDF 规范,那么如果您能查看我在上面发布的 PDF 文件,我将不胜感激。感谢您的帮助!

【问题讨论】:

  • 您尚未为复选框生成“外观”流。 Acrobat 将自动添加外观,但如果您希望 Reader 执行此操作,您需要在 PDF AcroForm 字典中设置需要外观标志。在 AcroForm 中创建一个名为“NeedAppearances”的新布尔值并将其设置为 true。或者您可以自己创建外观。我没有验证这一点,所以我没有输入它作为答案。
  • 嗨@joelgeraci,感谢您的评论! PDF 确实包含复选框的外观流,不幸的是,添加“NeedAppearances”标志并不能解决问题。
  • 我(后来)看到了,但它们似乎构造错误。 “是”外观呈现为圆点,而不是我在 Acrobat 中看到的检查。尝试添加 NeedsAppearances 标志,但不在文件中创建外观。

标签: ruby pdf pdf-generation prawn


【解决方案1】:

我终于找到了解决方案!我花了很多时间来精简每个 PDF,直到找到导致 Acrobat Reader 中出现此渲染错误的最小更改。 (提示:使用pdftk original.pdf output original-uncompressed.pdf uncompress解压缩PDF流,然后您可以在文本编辑器中编辑PDF。)

我终于在/Root => /AcroForm => /DA下找到了罪魁祸首。工作 PDF 包含:

/DA (/Helv 0 Tf 0 g)

损坏的 PDF 有:

/DA <feff002f00480065006c0076002000300020005400660020003000200067>

这是一个十六进制编码的字符串,具有相同的解码值:/Helv 0 Tf 0 g

大多数 PDF 阅读器会自动解码此字符串而不会出现任何问题(Chrome、Firefox、Mac Preview),但 Acrobat Reader 出于某种原因不支持此功能。 (特别是/AcroForm 中的/DA 属性。它可以完美地解码任何其他编码字符串。)

我真的很难发现这个问题,因为许多 PDF 调试工具(例如 iText RUPS)会自动解码这些字符串并隐藏它们被编码的事实。

我正在用 Ruby 编写一些 PDF 生成代码(使用 Prawn 和 pdf-core gem),所以修复非常简单。

之前:

self[:DA] = '/Helv 0 Tf 0 g'

之后:

self[:DA] = PDF::Core::LiteralString.new('/Helv 0 Tf 0 g')

使用PDF::Core::LiteralString 类可以防止Prawn 对字符串进行编码。

进行此更改后,复选框在 Acrobat Reader 中正常工作:

【讨论】:

  • 哇。我使用 Adob​​e 内部的工具,它也对字符串进行解码。我怀疑 Acrobat 也是如此……只是不是 Reader。我可以在报告错误时与 Adob​​e 共享这些文件吗?
  • 是的,请随时分享这些文件,感谢您报告错误!
猜你喜欢
  • 1970-01-01
  • 2017-04-29
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
相关资源
最近更新 更多