如何使用PyPDF2合并PDF页面

15 投票
5 回答
51188 浏览
提问于 2025-04-18 00:54

有没有人用Python库PyPDF2合并两个PDF页面的经验?我尝试使用page1.mergePage(page2),结果是页面2覆盖在页面1上。请问怎么才能把页面2添加到页面1的底部呢?

5 个回答

-2

下面这个链接里的代码可以帮你实现你的目标。

使用 PyPDF2 将文件合并成多个输出文件

我觉得关键在于:

merger.append(input)

2

pdfrw这个库可以做到这一点。在它的示例文件夹里,有一个4up的例子,能把4个输入页面放在每个输出页面上,还有一个小册子的例子,可以把8.5x11的输入变成11x17的输出。声明一下——我是pdfrw的作者。

3

我这样做了:

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)

当每个页面的高度和宽度都一样时,这个方法有效。不过,如果页面的大小不一样,就需要做一些调整。

也许Emile Bergeron的解决方案更好,但我还没试过。

4

如果这两个PDF文件不在你的电脑上,而是通常通过网址访问或下载的(比如 http://foo/bar.pdfhttp://bar/foo.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())
31

在我搜索关于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等)不会被改变。参数页面的内容流会被添加到这一页的内容流末尾,也就是说它会在这一页的内容上面绘制。

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()

撰写回答