2013-03-02 46 views
3

我想將幾個PDF文件合併到一個PDF文檔中。事實證明,輸入文件並不完全符合標準。該EOF標記其次是一些附加信息:用pyPdf合併非標準PDF文件

>> 
startxref 
1994481 
%%EOF 

%%PPIRoute: 4 

很顯然,這會導致pyPdf giving me an exception

pyPdf.utils.PdfReadError: EOF marker not found 

現在的問題是:我該怎麼辦?我可能會打開每個文件,剝掉最後兩行並將其保存到pyPdf之前。但是,我不太喜歡這個想法。也許有更好的選擇呢?

+0

派生的'PdfFileReader'一個子類,做你想要什麼的' read()'方法。或者,創建自己的智能'流'對象並將其傳遞給現有的'read()'方法。 – martineau 2013-03-02 19:04:05

+0

正在改變'pdf.py'選項?它看起來很容易修改它處理問題(假設可以刪除/忽略文件中的附加信息)。 – martineau 2013-03-02 19:24:31

回答

2

我建議從改變PdfFileReader類的read()方法開始在pdf.py腳本:

def read(self, stream): 
     # start at the end: 
     stream.seek(-1, 2) 
     line = '' 
     while not line: 
      line = self.readNextEndLine(stream) 
     if line[:5] != "%%EOF": 
      raise utils.PdfReadError, "EOF marker not found" 

    ... etc 

到:

def read(self, stream): 
     # start at the end: 
     stream.seek(-1, 2) 
     line = '' 
     # read stream backwards while watching for end-of-file marker 
     while line[:5] != "%%EOF": 
      line = self.readNextEndLine(stream) 

    ... etc 

在我看來,原來的代碼是不是真的按照Adobe的PDF 1.3 Reference文檔中的第3.4.4節「文件預告」(第628頁)所述進行操作(italics mine):

Acrobat viewers require only that the %%EOF marker appear somewhere within the last 1024 bytes of the file.

換句話說,在"%%EOF"標記後面的文件物理結束之前還有其他內容是可以的。我提議的更改嘗試適應這種情況,並忽略可能已添加到文件末尾的任何其他內容,而不是引發異常(但它不要求"%%EOF"最後1K字節爲規範說,雖然可以添加一個檢查)。這也意味着你試圖合併的文件實際上可能符合規範。

更新:

這裏有一個版本,也需要"%%EOF"標記是最後1024個字節內:

def read(self, stream): 
    # start at the end 
    stream.seek(-1, os.SEEK_END) 
    last1K = stream.tell() - 1024 + 1 # offset of last 1024 bytes of stream 

    # read stream backwards while watching for end-of-file marker 
    line = '' 
    while line[:5] != "%%EOF": 
     line = self.readNextEndLine(stream) 
     if stream.tell() < last1K: 
      raise utils.PdfReadError, "EOF marker not found" 

    ... etc 
+0

cyroxx:你有沒有試過我的答案? – martineau 2013-06-11 17:03:13

+0

還沒有,因爲這是一個小項目,我還沒有看過一段時間。非常感謝您的回答,只要我嘗試了您的建議解決方案,我會盡快發表評論/投票。 – cyroxx 2013-09-05 12:46:18

+0

嘿@cyroxx,怎麼了? – martineau 2013-10-23 15:12:09