2013-03-02 4 views
3

Я хотел бы объединить несколько PDF-файлов в один PDF-документ. Как оказалось, входные файлы не полностью соответствуют стандарту. EOF маркер сопровождается некоторой дополнительной информации:Объединить нестандартные PDF-файлы с pyPdf

>> 
startxref 
1994481 
%%EOF 

%%PPIRoute: 4 

Очевидно, что это приводит к pyPdf giving me an exception:

pyPdf.utils.PdfReadError: EOF marker not found 

Теперь вопрос: Что я должен делать? Я мог бы, вероятно, открыть каждый файл, удалить последние две строки и сохранить его, прежде чем бросать их в pyPdf. Однако мне не очень нравится эта идея. Может быть, есть лучший вариант?

+0

Выведите подкласс 'PdfFileReader', который делает то, что вы хотите в своей' read() '. В качестве альтернативы создайте свой собственный интеллектуальный объект 'stream' и передайте его существующему методу' read() '. – martineau

+0

Изменяет 'pdf.py' вариант? Похоже, что было бы легко изменить его, чтобы справиться с этой проблемой (при условии, что это нормально, чтобы удалить/игнорировать дополнительную информацию в файле (файлах)). – martineau

ответ

2

Я предлагаю изменение начало read() метода в PdfFileReader класса в 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 

На мой взгляд исходный код не очень выполняя то, что подразумевается в разделе 3.4.4 «Файл трейлер» (стр. 628) в документе Adobe PDF 1.3 Reference, где говорится (курсив мой):

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

Другими словами, это нормально для того, чтобы существовал другой материал до физического конца файла после маркера "%%EOF". Изменения, которые я предлагаю попытаться приспособить к этому, и заставить его игнорировать все остальное, которое, возможно, было привязано к концу файла после маркера, а не к созданию исключения (однако он не требует, чтобы "%%EOF" находился в последних 1 Кбайтах, спецификация говорит, хотя проверка на это может быть добавлена). Это также означает, что файлы, которые вы пытаетесь объединить, могут, по сути, соответствовать спецификации.

Update:

Вот версия, которая также требует "%%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

+0

Пока нет, так как это небольшой проект, который я не изучал некоторое время. Благодарим вас за ваш ответ, я буду прокомментировать/проголосовать, как только я попробую ваше предлагаемое решение. – cyroxx

+0

Эй, @cyroxx, что случилось? – martineau

Смежные вопросы