如何通过Pikepdf和Python连接PDF,而无需不必要的磁盘读写?

f0brbegy  于 2023-04-19  发布在  Python
关注(0)|答案(1)|浏览(130)

当前技术栈

  • 2019 - 04 - 04 01:04:04
  • pikepdf==7.1.2
  • Python 3.10
  • Ubuntu 22.04
    要求

一个pdf文件(我们称之为static.pdf)存在于磁盘中。另一个pdf(我们称之为dynamic.pdf)正在使用img 2 pdf库在 memory 中动态生成,这取决于一些用户输入参数。
任务是将这两个pdf连接为一个(static.pdf,然后dynamic.pdf),并通过SMTP库将其作为电子邮件附件发送。

我正在使用的当前解决方案

这是基于pikepdf文档。

  • dynamic.pdf转储到磁盘中
  • 使用pikepdf从磁盘读取static.pdf
  • 使用pikepdf从磁盘读取dynamic.pdf
  • 将它们与pikepdf提供的列表式API连接起来,我们称之为final.pdf
  • 使用pikepdf API将final.pdf转储到磁盘上
  • 从磁盘读取,以open(file='final.pdf', mode='rb')为字节
  • 将字节附加到电子邮件
    我想要的

当内存中已经有dynamic.pdf时,删除所有不必要的磁盘I/O,最终结果需要以字节的形式附加到电子邮件中(不需要在磁盘上持久化)。因此,理想情况下,唯一的磁盘操作应该是阅读static.pdf
但是我在pikepdf网站上找不到太多关于内存连接的信息。此外,我也不确定pikepdf.Pdf对象是否可以暴露 * 完全相同的字节 *,如果我将pdf转储到磁盘上,然后使用python原生open函数读取它。
因此,任何关于这方面的想法都将是有帮助的,即使有其他库也允许此功能。

  • 与我的技术栈(Python,Ubuntu,也需要在Windows上运行)一起使用
  • FOSS,而且足够值得信赖
r3i60tvu

r3i60tvu1#

根据pikepdf.Pdf的文档,Pdf.openPdf.save方法接受类似文件的对象,而不是文件名,因此您可以在这里使用io.BytesIO
比如说

import io
import img2pdf
from pikepdf import Pdf

def pdf_from_bytes(data):
    return Pdf.open(io.BytesIO(data))

def add_png_to_end(static_pdf_path, png_file_path):
    # Adds a PNG to the end of an existing PDF document and returns the bytes.
    static_pdf = Pdf.open(static_pdf_path)
    png_pdf = pdf_from_bytes(img2pdf.convert(png_file_path))
    new_pdf = Pdf.new()
    new_pdf.pages.extend(static_pdf.pages)
    new_pdf.pages.extend(png_pdf.pages)
    res = io.BytesIO()
    new_pdf.save(res)
    return res.getvalue()

相关问题