2014-02-24 62 views
1

我正在生成PDF并将其存储在数据库中。iTextSharp比较2个PDF的相等性

PDF格式的数据存储在使用Convert.ToBase64String(pdf.ByteArray)的文本字段

如果我生成已经存在于数据库中,并比较2个base64strings完全相同的PDF,他们不是相同。大部分是相同的,但每次出现大约5-10%的文本是不同的。

如果两个pdf文件都使用相同的方法生成,那么会导致2个pdf文件不同?

这是一个问题,因为我无法分辨PDF自上次保存到数据库以来是否被修改过。

编辑:2页的PDF查看实际PDF时在视觉上出现完全一样的,但字节base64string不同

回答

3

两个的PDF该 100%相同的视觉可以是下完全不同的封面。 PDF制作程序可以自由地将单词“hello”写成单个单词或以任意顺序书写五个单独的字母。他们也可以自由地绘制表格的行首先跟着单元格的内容,或者单元格的内容,或者它们的任意组合,例如一次一个单元格。

如果你实际上是在编程方式创建的PDF和您在使用完全相同的代码,你仍然不会得到是100%相同的文件创建两个PDF文件。这有几个原因,最明显的是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条目来删除独特的部分仅作比较但你可能会做更多的工作,而不是仅仅重新存储在数据库中的文件。

+0

很好的答案。每种PDF都是唯一的文件格式是固有的,即使它是使用相同的源代码创建的。阅读我的答案以下问题关于测试的更多信息,您应该比较PDFs的方式:http://stackoverflow.com/questions/21944424/itext-unit-testing-and-automated-testing-questions –

+0

优秀的响应。我认为一些隐藏的信息(时间戳)是差异的原因。最终,我找到了一种方法从pdf中提取文本,并以这种方式执行比较。可能不是最有效的方法,但它有效。 – mrb398