iTextSharp比较2个PDF是否相等

时间:2014-02-24 14:13:36

标签: itextsharp

我正在数据库中生成和存储PDF。

使用Convert.ToBase64String(pdf.ByteArray)将pdf数据存储在文本字段中

如果我生成数据库中已存在的完全相同的PDF,并比较2个base64字符串,则它们不相同。很大一部分是相同的,但每次出现约5-10%的文本是不同的。

如果两个pdf都是使用相同的方法生成的,那么会有什么不同?

这是一个问题,因为我无法判断PDF是否因为上次保存到数据库而被修改。

编辑:在查看实际的pdf时,2个pdf在视觉上看起来完全相同,但字节的base64string是不同的

1 个答案:

答案 0 :(得分:4)

两个PDF 看起来 100%相同的视觉效果可能完全不同。 PDF制作程序可以自由地将单词“hello”写成单个单词或以任何顺序书写的五个单独的单词。他们也可以自由地绘制表格的行,然后是单元格内容,或者首先是单元格内容,或者是这些单元格的任意组合,例如一次一个单元格。

如果您实际上是以编程方式创建PDF并使用完全相同的代码创建两个PDF,则 仍然 将无法获得100%相同的文件。这有几个原因,最明显的是PDF支持创建和修改日期。这些显然会根据它们的创建时间而改变。您可以使用以下内容覆盖这些(并混淆其他所有人,因此我不建议这样做):

var info = writer.Info;
info.Put(PdfName.CREATIONDATE, new PdfDate(new DateTime(2001,01,01)));
info.Put(PdfName.MODDATE, new PdfDate(new DateTime(2001,01,01)));

但是,PDF还支持预告片/ID条目中的唯一标识符。据我所知,iText不支持覆盖此参数。您可以复制PDF,手动更改,然后计算差异,您可能会更接近比较。

然后是字体。在对字体进行子集化时,生成器会根据原始名称和任意选择的六个大写ASCII字母创建唯一的内部名称。因此,对于字体Calibri,字体的名称可以是JLXWHD+Calibri一次,SDGDJT+Calibri另一次。 iText不支持覆盖这一点,因为你可能弊大于利。这些内部名称用于避免字体子集冲突。

所以简短的回答是,除非您要比较两个彼此物理重复的文件,否则无法对其二进制内容进行直接比较。很长的答案是,您可以调整一些PDF条目以删除唯一的部分仅用于比较,但您可能要做的工作多于将文件重新存储在数据库中所需的工作量