如何使用 PyPDF2 附加 PDF 页面

Posted

技术标签:

【中文标题】如何使用 PyPDF2 附加 PDF 页面【英文标题】:How to append PDF pages using PyPDF2 【发布时间】:2014-05-12 18:29:32 【问题描述】:

是否有人有使用 python lib PyPDF2 将两页 PDF 文件合并为一页的经验。 当我尝试page1.mergePage(page2) 时,它的结果是 page2 覆盖了 page1。如何使其将page2添加到page1的底部?

【问题讨论】:

作者大概在找这样的东西:pdfdu.com/pdf-pages-merge.aspx 【参考方案1】:

以下链接中发布的代码实现了您的目标。

Using PyPDF2 to merge files into multiple output files

我相信诀窍是:

merger.append(输入)

【讨论】:

请提供一个完整的答案,而不仅仅是一个链接,而且,链接中的代码(以及您的答案)不完整,不提供任何帮助。【参考方案2】:

当我在网上搜索 python pdf 合并解决方案时,我注意到合并与附加存在一个普遍的误解。

大多数人将附加操作称为合并,但事实并非如此。您在问题中描述的实际上是 mergePage 的预期用途 应该称为 applyPageOnTopOfAnother 但这有点长。您(正在)寻找的实际上是附加两个文件/pages 到一个新文件中。

附加 PDF 文件

使用PdfFileMerger 类及其append method。

merge() 方法相同,但假设您要连接 所有页面都放在文件末尾,而不是指定位置。

这是一种取自pypdf Merging multiple pdf files into one 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 method。

向此 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

将两个页面的内容流合并为一个。资源参考 (即字体)由两个页面维护。媒体框/裁剪框/等 此页面的内容未更改。参数页面的内容流将 被添加到此页面内容流的末尾,这意味着它 将绘制在此页面之后或“顶部”

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 页合并为一个,一个在另一个之下。 你真的应该在你的问题中澄清这一点。你的意思是,上半部分是第 1 页,下半部分是第 2 页? @ValentinMelnikov 尽管如此,它并没有合并,而是将两个页面的内容附加到一个新页面上。 但是,这个答案对我来说非常有用:)(我的任务是结合前景+背景并获得输出) "Append" 在谈论 PDF 时具有特殊含义。鉴于 PDF 允许通过在文档末尾为新版本编写新树来附加字节来更改文档的内容和表示。当试图通过增量更新来保持文档的过去版本进行数字签名时,这是特别强制执行的。检查此文档“PDF 中的数字签名 - Adob​​e”(adobe.com/devnet-docs/acrobatetk/tools/DigSig/…),在图 #5 中。【参考方案3】:

pdfrw 库可以做到这一点。在示例目录中有一个 4up 示例,它在每个输出页面上放置 4 个输入页面,还有一个小册子示例,它采用 8.5x11 输入并创建 11x17 输出。免责声明——我是pdfrw作者。

【讨论】:

【参考方案4】:

如果这两个 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())

【讨论】:

这对于手头的问题并没有带来任何新的东西,其余的都超出了这里的范围。 是的,这里的答案是解决比OP更具体的问题的具体方法。作为 OP 的替代方法,它仍然具有相关性。如果您认为此答案没有增加价值,请投反对票或举报,而不是留下固执己见的 cmets。 这个问题是关于如何用python合并/追加PDF文件。从互联网下载文件是无关紧要的。这不是一种替代方法,因为您使用的是相同的 PdfFileMerger 技术。 这使用相同的方法 (PdfFileMerger),但不假定两个 PDF 在您的本地磁盘上都可用,而是推广到使用远程 PDF。同样,请投反对票或举报,而不是在 *** 上发起自以为是的评论战。【参考方案5】:

这样做的:

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 解决方案更好。没试过。

【讨论】:

以上是关于如何使用 PyPDF2 附加 PDF 页面的主要内容,如果未能解决你的问题,请参考以下文章

PyPDF2如何实现按照PDF页码提取后并另存为PDF格式文件?

如何使用 python 更改 pdf 中的超链接?

如何使用 Python 获取 PDF 文件元数据“页面大小”?

Python 不使用 pyPDF2 打印 PDF

使用 pypdf2 和电子邮件合并多个 PDf

未找到 EOF 标记 - 如何在 PyPDF 和 PyPDF2 中修复?