2014-02-24 109 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