我想将几个PDF文件合并为一个PDF文档。事实证明,输入文件不完全符合标准。 EOF标记后面是一些其他信息:
>>
startxref
1994481
%%EOF
%%PPIRoute: 4
显然,这会导致pyPdf giving me an exception:
pyPdf.utils.PdfReadError: EOF marker not found
现在的问题是:我该怎么办?我可能可以打开每个文件,剥离最后两行并保存,然后再将它们放入pyPdf中。但是,我不太喜欢这个主意。也许那里有更好的选择?
最佳答案
我建议将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页)所隐含的含义(斜体字):
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