pypdf2 在 python 3.11 中仍可合并 pdf,但推荐使用 pdfmerger(pdffilemerger 已弃用),需以二进制模式打开文件,支持 strict=false 处理损坏 pdf,书签默认保留但页码需手动映射,交互式元素如表单、注释会丢失。

PyPDF2 在 Python 3.11 中仍可正常合并 PDF,但默认不支持加密 PDF、无法处理某些新版 PDF 结构(如含对象流或 AES-256 加密),且 PdfMerger 是当前推荐方式,PdfFileMerger 已弃用。
用 PdfMerger 合并多个 PDF 文件(最简可靠路径)
这是 Python 3.11 + PyPDF2 3.0+ 的标准做法,底层更健壮,内存管理更好,且自动处理页码偏移和书签继承(若源 PDF 有)。
常见错误:直接用 PdfFileReader + addPage 手动拼页——容易丢元数据、崩溃于空页或损坏的 /Kids 节点。
- 必须用
with open(..., "rb")模式打开每个输入文件,PyPDF2 不接受文本模式 - 合并顺序严格按
append()或merge()调用顺序,merge(page_number, pdf_reader)可插入到指定位置 - 若某 PDF 有密码,需先调用
reader.decrypt("password"),否则append()会抛NotImplementedError
from PyPDF2 import PdfMerger
<p>merger = PdfMerger()
for pdf_path in ["a.pdf", "b.pdf", "c.pdf"]:
with open(pdf_path, "rb") as f:
merger.append(f) # 自动检测并跳过加密/损坏文件(抛异常,需 try)
merger.write("merged.pdf")
merger.close()
</p>
处理“PdfReadError: Invalid object identifier”类错误
这类报错多见于从网页下载、微信导出或扫描 App 生成的 PDF,它们常含非标准交叉引用表或损坏的 trailer 字段。PyPDF2 默认校验严格,一遇到就中断。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
解决思路不是绕过校验,而是预清理或降级兼容:
- 加
strict=False参数初始化PdfReader(仅用于append()前手动读取):merger.append(PdfReader(f, strict=False)) - 避免用
fitz(PyMuPDF)混用——它写入的 PDF 可能含 PyPDF2 不识别的结构(如 /ObjStm) - 若仍失败,用命令行工具预修复:
qpdf --replace-input --flatten input.pdf(需提前安装 qpdf)
合并后书签丢失或层级错乱
PdfMerger 默认保留各源 PDF 的顶层书签,但不会重映射目标页码;若你在中间插入 PDF,原有书签可能指向错误页码。
关键控制点:
- 用
merge(position, fileobj, outline_item=True)可显式开启书签继承(outline_item默认为True) - 若要统一书签前缀(如“第1份:XXX”),得手动遍历
merger.outline并修改Title字符串——该属性是可写的 - 注意:书签目标页码是绝对页码(从 0 开始计),合并后总页数变化不影响已存 outline 对象,但新添加的 outline 必须用
add_outline_item(title, page_number)显式指定
真正麻烦的是跨文档的交互式元素(表单域、注释、图层)——PyPDF2 完全不处理它们,合并后会丢失。如果业务依赖这些,就得换 pypdf(PyPDF2 的继任者,v8+ 支持表单合并)或直接切到 fitz。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










