iText 使用相同的代码生成不同的 pdf

Posted

技术标签:

【中文标题】iText 使用相同的代码生成不同的 pdf【英文标题】:iText generates different pdfs with the same code 【发布时间】:2018-07-31 20:55:27 【问题描述】:

我正在尝试使用 iText 为我的 pdf 生成代码编写单元测试。但我发现 iText 生成的文件在二进制文件中略有不同。我猜这是由于元数据(例如创建时间)。

我想知道我的猜测是否正确。还有如何手动设置元数据。非常感谢。

【问题讨论】:

你的猜测只是部分正确。内存中的一些数据结构是非确定性的,但如果您只是发布这种二进制差异的示例,则更容易为您提供答案。 【参考方案1】:

如果您将创建时间添加到 PDF 的元数据中,则在不同时间使用相同代码创建的两个 PDF 之间会存在差异,因为创建时间会不同。这就是 PDF 不同的原因之一。

元数据是可选的,因此您可以选择省略所有元数据(这对 iText 来说很难做到,因为 iText 总是会添加元数据)。但是,即使在那种情况下,也会有差异。

自 PDF 2.0 起,一个区别是强制性的。在早期版本的 PDF 规范中,已经引入了每个 PDF 唯一 ID 的概念。此唯一 ID 包含两个值的数组,当从头开始创建 PDF 时,这两个值是相同的。如果对 PDF 进行操作,则 ID 的第一个值保持不变,而第二部分会发生变化。在 PDF 2.0 之前,此 ID 对是可选的,尽管许多 PDF 创建者会添加它。从 PDF 2.0 开始,这样的 ID 对是强制性的,不应使用相同的 ID 创建两个不同的 PDF。在实践中,这种 ID 对的值是通过创建不同参数的消息摘要来创建的,通常包括当前时间,以确保在不同时间创建的两个 PDF 的 ID 不同。

还使用时间戳,例如当您创建数字签名时。另一个差异可能取决于您用于创建 PDF 的技术或编程语言。例如:在创建 PDF 期间,一些散列集填充了对象列表。然后将这些对象以可能不同的顺序写入 PDF 文件,因为顺序在哈希集中并不重要。从哈希集中接收对象的顺序取决于很多因素,而且通常很难预测(请参阅 Java 中 ArrayListTreeSetHashSet 之间的区别)。

例如:如果您有一个包含对象“apple”、“pear”、“banana”的无序列表,并且将此无序列表写入文件,则这些对象可以在文件中出现 6 种不同的顺序:

    苹果、梨、香蕉 苹果、香蕉、梨 梨、苹果、香蕉 梨、香蕉、苹果 香蕉、苹果、梨 香蕉、梨、苹果

假设这些对象不是水果,而是 PDF 中的对象,那么 6 种不同顺序中的任何一种都会产生有效的 PDF 语法。

【讨论】:

除了元数据中的时间戳之外,实际上还可以有其他时间戳,例如如果是签名的 PDF 或带有文件附件的 PDF...

以上是关于iText 使用相同的代码生成不同的 pdf的主要内容,如果未能解决你的问题,请参考以下文章

iText7高级教程之html2pdf——2.使用CSS定义样式

基于相同日期的 iText PDF 替代行颜色

使用 iText 合并不同宽度的 pdf 文档

itext - pdf复选框填充不同

iText7高级教程之html2pdf——2.使用CSS定义样式

使用最新版本的 iText XML 到 PDF