Как добавить PDF-страницы, используя PyPDF2

Кто-нибудь имеет опыт объединения двух страниц PDF-файла в одну с использованием Python lib PyPDF2. Когда я пытаюсь page1.mergePage(page2) это приводит к наложенной странице page2. Как сделать так, чтобы добавить страницу2 внизу страницы1?

4 ответа

Когда я искал в Интернете решение для слияния python pdf, я заметил, что существует общее заблуждение о слиянии и добавлении.

Большинство людей называют добавляющееся действие слиянием, но это не так. То, что вы описываете в своем вопросе, действительно предназначено для mergePage который должен называться applyPageOnTopOfAnother но это немного долго То, что вы ищете (действительно), это добавление двух файлов / страниц в новый файл.

Добавление файлов PDF

С использованием PdfFileMerger класс и его append метод.

Идентичен merge() метод, но предполагает, что вы хотите объединить все страницы в конец файла вместо указания позиции.

Вот один из способов сделать это из pypdf. Объединение нескольких PDF-файлов в один PDF-файл:

from PyPDF2 import PdfFileMerger, PdfFileReader

# ...

merger = PdfFileMerger()

merger.append(PdfFileReader(file(filename1, 'rb')))
merger.append(PdfFileReader(file(filename2, 'rb')))

merger.write("document-output.pdf")

Добавление определенных страниц PDF

И чтобы добавить определенные страницы различных файлов PDF, используйте PdfFileWriter класс с addPage метод.

Добавляет страницу в этот файл PDF. Страница обычно получается из PdfFileReader пример.

file1 = PdfFileReader(file(filename1, "rb"))
file2 = PdfFileReader(file(filename2, "rb"))

output = PdfFileWriter()

output.addPage(file1.getPage(specificPageIndex))
output.addPage(file2.getPage(specificPageIndex))

outputStream = file("document-output.pdf", "wb")
output.write(outputStream)
outputStream.close()

Объединение двух страниц в одну страницу

С помощью mergePage

Объединяет потоки контента двух страниц в одну. Ссылки на ресурсы (т.е. шрифты) поддерживаются с обеих страниц. Mediabox/cropbox/etc этой страницы не изменены. Поток содержимого страницы параметров будет добавлен в конец потока содержимого этой страницы, что означает, что он будет нарисован после или "поверх" этой страницы.

file1 = PdfFileReader(file(filename1, "rb"))
file2 = PdfFileReader(file(filename2, "rb"))

output = PdfFileWriter()

page = file1.getPage(specificPageIndex)
page.mergePage(file2.getPage(specificPageIndex))

output.addPage(page)

outputStream = file("document-output.pdf", "wb")
output.write(outputStream)
outputStream.close()

Если 2 PDF-файла не существуют на вашем локальном компьютере, и вместо этого к ним обычно обращаются / скачивают через URL-адрес (т http://foo/bar.pdf & http://bar/foo.pdf), мы можем получить оба PDF- файла из удаленных мест и объединить их в памяти одним махом.

Это исключает предполагаемый шаг загрузки PDF для начала и позволяет обобщить не только простой случай, когда оба PDF-файла существуют на диске. В частности, он обобщает решение для любого HTTP-доступного PDF.

Пример:

    from PyPDF2 import PdfFileMerger, PdfFileReader

    pdf_content_1 = requests.get('http://foo/bar.pdf').content
    pdf_content_2 = requests.get('http://bar/foo.pdf').content

    # Write to in-memory file-like buffers        
    pdf_buffer_1 = StringIO.StringIO().write(pdf_content_1)
    pdf_buffer_2 = StringIO.StringIO().write(pdf_content_2)
    pdf_merged_buffer = StringIO.StringIO()

    merger = PdfFileMerger()
    merger.append(PdfFileReader(pdf_buffer_1))
    merger.append(PdfFileReader(pdf_buffer_2))
    merger.write(pdf_merged_buffer)

    # Option 1:
    # Return the content of the buffer in an HTTP response (Flask example below)
    response = make_response(pdf_merged_buffer.getvalue())
    # Set headers so web-browser knows to render results as PDF
    response.headers['Content-Type'] = 'application/pdf'
    response.headers['Content-Disposition'] = \ 
        'attachment; filename=%s.pdf' % 'Merged PDF'
    return response 
    # Option 2: Write to disk
    with open("merged_pdf.pdf", "w") as fp:
        fp.write(pdf_merged_buffer.getvalue())

Сделал это так:

reader = PyPDF2.PdfFileReader(open("input.pdf",'rb'))

NUM_OF_PAGES = reader.getNumPages()

page0 = reader.getPage(0)
h = page0.mediaBox.getHeight()
w = page0.mediaBox.getWidth()

newpdf_page = PyPDF2.pdf.PageObject.createBlankPage(None, w, h*NUM_OF_PAGES)
for i in range(NUM_OF_PAGES):
    next_page = reader.getPage(i)
    newpdf_page.mergeScaledTranslatedPage(next_page, 1, 0, h*(NUM_OF_PAGES-i-1))

writer = PdfFileWriter()
writer.addPage(newpdf_page)

with open('output.pdf', 'wb') as f:
    writer.write(f)

Это работает, когда все страницы имеют одинаковую высоту и ширину. В противном случае потребуются некоторые модификации.

Возможно, решение Эмиля Бержерона лучше. Не пробовал.

Библиотека pdfrw может сделать это. В каталоге примеров есть пример 4up, который размещает 4 входные страницы на каждой выходной странице, и пример буклета, который принимает входные данные 8.5x11 и создает выходные данные 11x17. Отказ от ответственности - я автор pdfrw.

Код, размещенный в этой следующей ссылке, достиг вашей цели.

Использование PyPDF2 для объединения файлов в несколько выходных файлов

Я считаю, что хитрость заключается в следующем:

merger.append (вход)

Другие вопросы по тегам