使用pyPdf合并非标准PDF

时间:2013-03-02 17:54:45

标签: python pdf python-2.6 pypdf

我想将几个PDF文件合并到一个PDF文档中。事实证明,输入文件并不完全符合标准。 EOF标记后面是一些其他信息:

>>
startxref
1994481
%%EOF

%%PPIRoute: 4

显然,这导致了pyPdf giving me an exception

pyPdf.utils.PdfReadError: EOF marker not found

现在的问题是:我该怎么办?我可以打开每个文件,删除最后两行并保存它然后再将它们放入pyPdf。但是,我不太喜欢这个想法。也许那里有更好的选择?

1 个答案:

答案 0 :(得分:3)

我建议从以下位置更改pdf.py脚本中read()类的PdfFileReader方法的开头:

    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查看器只需要 ,%% EOF标记出现在某处   在文件的最后1024个字节内。

换句话说,在"%%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