Как добавить 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 (вход)