PDF合并
官方脚本
可调用节点
v1.1.0
PDF合并工具 | 多选 PDF 一键合并为一个文件,支持自然排序/文件名/修改时间/大小/反转等顺序,可选书签、分隔页、覆盖输出 | 输出合并后的 PDF 路径与总页数
脚本能力
直接启动支持
右键启动支持
快捷键启动支持
超级复制启动不支持
定时任务支持
可被其他脚本调用是
依赖其他脚本否
图形化启动界面支持
一键将多个 PDF 文件按指定顺序合并为一个 PDF,基于 pdfcpu 引擎,支持书签、分隔页,可选多种排序方式。
✨ 核心特性
- 多种排序方式:自然排序(
第2章 < 第10章)、按文件名、按修改时间、按大小、反转等,合并顺序随心控制 - 一键合并:选中多个 PDF → 右键 → 在启动窗口确认选项 → 自动合并
- 书签支持:自动为合并结果按源文件分组添加书签
- 分隔页:可在每个文件之间插入空白分隔页
- 自定义输出:可指定输出文件名与输出目录,默认
合并_{时间戳}.pdf - 自动覆盖:可覆盖已存在的输出文件
- 总页数提示:合并完成后自动显示结果总页数
- 支持定时任务:可配置定时自动合并指定文件
- 可作为节点被调用:返回合并结果路径与页数,供其他脚本联动使用
脚本演示

安装方法
本脚本的运行环境、依赖组件及图形化窗口均依赖"不忙脚本盒子",建议仅通过盒子安装和使用本脚本。
前置条件:安装好 不忙脚本盒子
- 打开盒子 → 脚本市场 → 搜索 「PDF合并」
- 点击「安装」
使用方式
- 右键启动
- 在文件管理器中选中多个 PDF 文件
- 右键点击,选择「PDF合并」
- 在启动窗口中确认排序方式与输出选项,点击「执行」
- 快捷键启动
- 为脚本设置全局快捷键,选中 PDF 后按下快捷键即可
- 定时任务
- 在盒子的定时任务中新建任务,选择本脚本
- 填写要合并的 PDF 列表及排序方式等参数
- 到点后盒子自动无人值守执行
💡 使用提示
- 排序方式:默认按文件名自然排序(
第2章 < 第10章);选择「保持选中顺序」则按选择文件的先后顺序合并 - 输出命名:留空默认使用
合并_{时间戳}.pdf防止误覆盖;填写自定义名称可配合「覆盖已存在」重复合并 - 输出目录:留空输出到第一个源文件所在目录
- 书签:合并结果自动添加书签,按源文件分组
- 分隔页:勾选后每个文件之间插入一页空白分隔页
- 覆盖说明:默认覆盖已存在的输出文件,取消勾选后遇到同名文件会跳过
节点脚本(开发者阅读)
本脚本已声明为节点(node.enabled = true),可被其他盒子脚本通过 /api/link 同步调用,返回合并结果。
import json, sys, requests
payload = json.load(open(sys.argv[1], encoding='utf-8'))
env = payload["environment"]
PDF_MERGE_ID = "3aeabd2d-9ee9-4eaf-9cb3-24aa7f5668b9"
r = requests.post(f"{env['api_base']}/api/link", json={
"script_id": PDF_MERGE_ID,
"data": {"target_paths": ["C:/a.pdf", "C:/b.pdf"]},
"params": {
"sort_mode": "natural", # natural/keep/name/mtime_asc/mtime_desc/size_asc/size_desc/reverse
"output_name": "合并结果",
"output_dir": "C:/out",
"divider": False,
"bookmarks": True,
"force": True,
},
}, timeout=600)
body = r.json()
if not body.get("success"):
raise RuntimeError(body.get("message", "联动调用失败"))
result = body["result"] # 节点信封
if result.get("code") != 0:
raise RuntimeError(result.get("msg"))
print(result["output_path"]) # 合并后的 PDF 绝对路径
print(result["page_count"]) # 总页数
print(result["file_count"]) # 参与合并的文件数
返回业务键(信封顶层平铺):
| 键 | 类型 | 说明 |
|---|---|---|
output_path |
str | 合并后的 PDF 绝对路径 |
page_count |
str | 合并后总页数,读取失败为空字符串 |
file_count |
str | 参与合并的文件数量 |
🖥️ 环境要求
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows 10+(64位) |
| 运行环境 | Python 3.8+、pdfcpu |
本脚本已声明为节点,可被其他脚本通过「不忙脚本盒子」机制调用。完整配置见下方 TOML,其他脚本若需调用请严格按此配置构造请求。
bm-scripts-box-rc.toml
[bmscriptsbox]
[bmscriptsbox.info]
id = "3aeabd2d-9ee9-4eaf-9cb3-24aa7f5668b9"
name = "PDF合并"
desc = "PDF合并工具 | 多选 PDF 一键合并为一个文件,支持自然排序/文件名/修改时间/大小/反转等顺序,可选书签、分隔页、覆盖输出 | 输出合并后的 PDF 路径与总页数"
version = "1.1.0"
icon = "./imgs/img.png"
[bmscriptsbox.runtime]
language = "python"
language_version = ">=3.8"
entry = "main.py"
terminal = "always"
binaries = [{name = "pdfcpu"}]
[bmscriptsbox.triggers.context_menu]
enabled = true
targets = ["files"]
filters = [".pdf"]
[bmscriptsbox.triggers.shortcut]
enabled = true
input_type = "files"
filters = [".pdf"]
[[bmscriptsbox.inputs]]
name = "target_paths"
label = "PDF 文件"
type = "list"
exts = [".pdf"]
pick = "files"
description = "要合并的 PDF 文件,至少 2 个;顺序由 sort_mode 决定"
[[bmscriptsbox.outputs]]
name = "output_path"
type = "str"
description = "合并后的 PDF 文件绝对路径"
[[bmscriptsbox.outputs]]
name = "page_count"
type = "str"
description = "合并后 PDF 的总页数,读取失败时为空字符串"
[[bmscriptsbox.outputs]]
name = "file_count"
type = "str"
description = "参与合并的 PDF 文件数量"
[[bmscriptsbox.params]]
name = "sort_mode"
label = "排序方式"
type = "str"
default = "natural"
choices = ["natural", "keep", "name", "mtime_asc", "mtime_desc", "size_asc", "size_desc", "reverse"]
choice_labels = { natural = "自然排序(第2章<第10章)", keep = "保持选中顺序", name = "按文件名", mtime_asc = "按修改时间(旧→新)", mtime_desc = "按修改时间(新→旧)", size_asc = "按大小(小→大)", size_desc = "按大小(大→小)", reverse = "反转选中顺序" }
description = "决定合并顺序,默认按文件名自然排序"
[[bmscriptsbox.params]]
name = "output_name"
label = "输出文件名"
type = "str"
default = ""
description = "留空 = 合并_{时间戳}.pdf;不含 .pdf 会自动补全"
[[bmscriptsbox.params]]
name = "output_dir"
label = "输出目录"
type = "str"
default = ""
description = "留空 = 第一个源文件所在目录"
[[bmscriptsbox.params]]
name = "divider"
label = "分隔页"
type = "bool"
default = false
description = "每个文件之间插入空白分隔页"
[[bmscriptsbox.params]]
name = "bookmarks"
label = "书签"
type = "bool"
default = true
description = "按源文件分组添加书签"
[[bmscriptsbox.params]]
name = "force"
label = "覆盖已存在"
type = "bool"
default = true
description = "输出文件已存在时是否覆盖"
[bmscriptsbox.node]
enabled = true
[bmscriptsbox.schedule]
enabled = true
[bmscriptsbox.params_form]
enabled = true
免责声明
所有脚本由用户通过开源仓库自行发布。本站仅提供索引服务,"不忙脚本盒子"仅提供展示与安装服务。请在使用前仔细核实脚本内容,作者不对其安全性、准确性及适用性作任何保证。