You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Pikepdf与Python实现无冗余磁盘读写的PDF合并

解决方案:无多余磁盘IO的PDF合并与邮件发送

核心思路

利用pikepdf支持从字节流读取PDF、以及将Pdf对象直接导出为字节的特性,全程仅保留读取磁盘static.pdf的操作,其余步骤均在内存完成:

  • 从磁盘加载static.pdf为pikepdf.Pdf对象
  • 用img2pdf生成内存中的dynamic PDF字节数据
  • 直接从字节流加载dynamic PDF为pikepdf.Pdf对象
  • 合并两个PDF的页面
  • 将合并后的PDF导出为字节,直接作为邮件附件发送

代码实现

import io
import pikepdf
import img2pdf
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

# 1. 从磁盘读取static.pdf到内存Pdf对象
static_pdf = pikepdf.open("static.pdf")

# 2. 用img2pdf动态生成内存中的dynamic.pdf字节流
# 替换为你的实际图片/参数生成逻辑
image_sources = ["user_upload_1.jpg", "user_upload_2.png"]
dynamic_pdf_bytes = img2pdf.convert(image_sources)

# 3. 从字节流加载dynamic.pdf为Pdf对象
dynamic_pdf = pikepdf.open(io.BytesIO(dynamic_pdf_bytes))

# 4. 合并页面:将dynamic的页面追加到static后方
static_pdf.pages.extend(dynamic_pdf.pages)

# 5. 将合并后的PDF导出为内存字节流
final_pdf_buffer = io.BytesIO()
static_pdf.save(final_pdf_buffer)
final_pdf_buffer.seek(0)  # 重置指针到起始位置

# 6. 作为邮件附件发送(替换为你的SMTP配置)
msg = MIMEMultipart()
msg['Subject'] = "合并完成的PDF文件"
msg['From'] = "sender@example.com"
msg['To'] = "recipient@example.com"

# 添加附件
part = MIMEBase('application', 'octet-stream')
part.set_payload(final_pdf_buffer.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment', filename="final.pdf")
msg.attach(part)

# 发送邮件
with smtplib.SMTP('smtp.example.com', 587) as server:
    server.starttls()
    server.login("your_username", "your_password")
    server.send_message(msg)

关键细节说明

  • pikepdf的open()方法支持直接接收io.BytesIO对象,无需将dynamic PDF写入磁盘即可加载
  • Pdf.save()方法可写入io.BytesIO,直接得到合并后的PDF字节,完全跳过磁盘存储步骤
  • 导出的字节与磁盘写入再读取的结果完全一致,pikepdf基于QPDF实现,保证PDF格式的标准性与正确性

内容的提问来源于stack exchange,提问作者Della

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 06:15:24