夜雨聆风学习资料网

ARTICLE · 1136559

PDF批量合并,用Python一键搞定!再也不用逐个复制了

PDF批量合并,用Python一键搞定!再也不用逐个复制了

工作中经常要把几十个PDF合并成一个?手动拖拽太慢,在线工具又担心隐私。今天教你用Python批量合并,几十行代码,安全高效,还能自动加书签。

今天聊一个很实用的小技能:PDF批量合并。

比如:

  • 每个月的发票PDF要合成一个;

  • 一个项目的几十份资料要按顺序合并;

  • 每个子文件夹里的PDF要分别合并成一个文件;

  • 合并后还想自动生成书签目录。

这些用 Python 都能轻松搞定。


一、准备工作

只需要一个库:pypdf。

它是纯 Python 库,安装简单,跨平台。

打开终端或命令行,输入:

pip install pypdf

如果你还没装 Python,先去官网下载安装:https://www.python.org/

安装时记得勾选 Add Python to PATH。


二、基础版:合并一个文件夹下所有PDF

先来看最小可运行版本。

from pathlib import Pathfrom pypdf import PdfWriter, PdfReaderimport redef natural_key(path):    """自然排序:file2.pdf 排在 file10.pdf 前面"""    return [int(t) if t.isdigit() else t.lower()            for t in re.split(r'(\d+)', path.name)]def merge_pdfs(input_dir, output_file):    input_path = Path(input_dir)    pdf_files = sorted(input_path.glob("*.pdf"), key=natural_key)    if not pdf_files:        print("没有找到PDF文件")        return    writer = PdfWriter()    for pdf in pdf_files:        reader = PdfReader(str(pdf))        for page in reader.pages:            writer.add_page(page)        print(f"已添加:{pdf.name}")    with open(output_file, "wb") as f:        writer.write(f)    print(f"合并完成:{output_file},共 {len(pdf_files)} 个文件")if __name__ == "__main__":    merge_pdfs("./pdfs", "./合并结果.pdf")
把要合并的 PDF 放到 pdfs 文件夹里,然后运行:
python merge_pdf.py

就会生成一个 合并结果.pdf。

注意这里用了自然排序,否则 file10.pdf 可能会排在 file2.pdf 前面。


三、进阶版:批量合并多个子文件夹

如果你有这样的目录结构:

pdfs/├── 项目A/│   ├── 01.pdf│   ├── 02.pdf│   └── 03.pdf├── 项目B/│   ├── 01.pdf│   └── 02.pdf└── 项目C/    └── 01.pdf
希望每个子文件夹分别合并成一个PDF,可以这样写:
from pathlib import Pathfrom pypdf import PdfWriter, PdfReaderimport redef natural_key(path):    return [int(t) if t.isdigit() else t.lower()            for t in re.split(r'(\d+)', path.name)]def merge_folder(folder, output_file):    pdf_files = sorted(folder.glob("*.pdf"), key=natural_key)    if not pdf_files:        return    writer = PdfWriter()    for pdf in pdf_files:        reader = PdfReader(str(pdf))        for page in reader.pages:            writer.add_page(page)    with open(output_file, "wb") as f:        writer.write(f)    print(f"合并完成:{output_file}")def merge_subfolders(root_dir, output_dir):    root = Path(root_dir)    out = Path(output_dir)    out.mkdir(parents=True, exist_ok=True)    for folder in sorted(root.iterdir(), key=natural_key):        if folder.is_dir():            output_file = out / f"{folder.name}.pdf"            merge_folder(folder, output_file)if __name__ == "__main__":    merge_subfolders("./pdfs", "./output")
运行后,output 文件夹里会生成:
output/├── 项目A.pdf├── 项目B.pdf└── 项目C.pdf

每个子文件夹一个合并文件,互不干扰。


四、给合并后的PDF加书签

合并几十个文件后,如果没有书签,找内容很痛苦。

pypdf 支持添加大纲书签:

writer = PdfWriter()for pdf in pdf_files:    reader = PdfReader(str(pdf))    start_page = len(writer.pages)    for page in reader.pages:        writer.add_page(page)    # 添加书签,标题用文件名    writer.add_outline_item(pdf.stem, start_page)

这样合并后的PDF左侧会有一个目录,点击就能跳到对应文件的第一页。


五、完整脚本:直接复制就能用

下面这个版本整合了:

  • 自然排序

  • 自动加书签

  • 加密PDF跳过

  • 单个文件夹合并

  • 多个子文件夹批量合并

  • 异常处理

# -*- coding: utf-8 -*-"""PDF批量合并工具功能:1. 合并指定文件夹下所有PDF2. 批量合并多个子文件夹,每个子文件夹生成一个PDF3. 自动按文件名自然排序4. 为每个源文件添加书签"""from pathlib import Pathfrom pypdf import PdfWriter, PdfReaderimport redef natural_key(path):    """自然排序:file2.pdf 排在 file10.pdf 前面"""    return [int(t) if t.isdigit() else t.lower()            for t in re.split(r'(\d+)', path.name)]def merge_pdf_files(pdf_files, output_file, add_bookmark=True):    """合并PDF文件列表"""    writer = PdfWriter()    for pdf in pdf_files:        try:            reader = PdfReader(str(pdf))            # 尝试处理加密PDF(空密码)            if reader.is_encrypted:                try:                    reader.decrypt("")                except Exception:                    print(f"跳过加密文件:{pdf.name}")                    continue            start_page = len(writer.pages)            for page in reader.pages:                writer.add_page(page)            if add_bookmark:                writer.add_outline_item(pdf.stem, start_page)            print(f"已添加:{pdf.name}({len(reader.pages)}页)")        except Exception as e:            print(f"处理失败:{pdf.name},原因:{e}")    if len(writer.pages) == 0:        print("没有可合并的页面")        return    output_file = Path(output_file)    output_file.parent.mkdir(parents=True, exist_ok=True)    with open(output_file, "wb") as f:        writer.write(f)    print(f"✅ 合并完成:{output_file},总页数:{len(writer.pages)}")def merge_folder(input_dir, output_file, add_bookmark=True):    """合并一个文件夹下的所有PDF"""    input_dir = Path(input_dir)    pdf_files = sorted(input_dir.glob("*.pdf"), key=natural_key)    if not pdf_files:        print(f"文件夹中没有PDF:{input_dir}")        return    merge_pdf_files(pdf_files, output_file, add_bookmark)def merge_subfolders(root_dir, output_dir, add_bookmark=True):    """每个子文件夹合并成一个PDF"""    root_dir = Path(root_dir)    output_dir = Path(output_dir)    output_dir.mkdir(parents=True, exist_ok=True)    for folder in sorted(root_dir.iterdir(), key=natural_key):        if folder.is_dir():            pdf_files = sorted(folder.glob("*.pdf"), key=natural_key)            if pdf_files:                output_file = output_dir / f"{folder.name}.pdf"                print(f"\n📂 处理文件夹:{folder.name}")                merge_pdf_files(pdf_files, output_file, add_bookmark)if __name__ == "__main__":    # ====== 修改这里 ======    MODE = "subfolders"   # "single" 合并单个文件夹;"subfolders" 批量合并子文件夹    INPUT_DIR = "./pdfs"  # 输入目录    OUTPUT = "./output"   # 输出目录    if MODE == "single":        merge_folder(INPUT_DIR, Path(OUTPUT) / "合并结果.pdf")    else:        merge_subfolders(INPUT_DIR, OUTPUT)

使用步骤:

  1. 安装 pypdf:pip install pypdf

  2. 把代码保存为 merge_pdf.py

  3. 修改 INPUT_DIR 和 OUTPUT

  4. 运行 python merge_pdf.py


六、常见问题

1. 提示没有 pypdf?

运行:

pip install pypdf

如果用了虚拟环境,确认在对应环境中安装。

2. 合并顺序不对?

代码里已经用了自然排序。如果还不够,可以在文件名前加数字:

01_合同.pdf02_附件.pdf03_发票.pdf

3. PDF有密码怎么办?

脚本会先尝试空密码解密。如果不行,会跳过并提示。

4. 文件太多,内存不够?

pypdf 是纯 Python 库,合并超大文件时内存占用会高一些。可以分批合并,或者改用 PyMuPDF。

5. 想打包成 exe 给同事用?

可以安装:

pip install pyinstaller
然后:
pyinstaller -F merge_pdf.py

生成的 exe 在 dist 文件夹里。不过路径配置需要提前写好。


七、总结

今天实现了:

  • 单个文件夹PDF批量合并

  • 多个子文件夹分别合并

  • 自然排序,避免 10 排在 2 前面

  • 自动添加书签

  • 加密文件跳过

  • 异常处理

Python 处理办公自动化,最大的好处就是:一次写好,重复使用,安全可控。

如果你经常处理 PDF,不妨把脚本收藏起来,改改路径就能用。

相关学习资料