批量把多个 Markdown 文件转换为 PDF 的几种方法
批量把 Markdown 转 PDF 的三种方法:一一对应用 npm CLI;多个合并为一个 PDF 用 Pandoc;每次提交生 PDF 用 CI。附可复制命令、图片路径坋以及合并现有 PDF 的方法。
三种常见批量任务:
- 一个 Markdown → 一个 PDF,重复多个文件:
md-to-pdf *.md(npm CLI)。 - 多个 Markdown → 一个合并 PDF(一本书、多章报告):
pandoc chapter*.md -o book.pdf。 - 多个 Markdown → 每次提交输出一份 PDF:GitHub Actions + npm CLI。
浏览器版 /markdown-to-pdf 是单文件的;批量任务需要 CLI。本文走一遍三个场景,有可复制粘贴的命令与常见坋。
最简单的情况。你有 chapter01.md、chapter02.md,要生成 chapter01.pdf、chapter02.pdf …
npm install -g md-to-pdf
md-to-pdf 'chapters/*.md'
完事—默认会在每个 .md 旁边写一个 .pdf。加主题控制外观:
md-to-pdf 'chapters/*.md' --stylesheet ./style.css
几百个文件要并行:
ls chapters/*.md | xargs -P 4 -I {} md-to-pdf {}
-P 4 并发处理 4 个 PDF。超过 4-8 会被 Chromium 启动开销限制。
适用于书、技术报告、多文件入职文档。
pandoc chapter01.md chapter02.md chapter03.md -o book.pdf
坋:文件名顺序重要。Pandoc 按参数顺序拼接,不是字母顺序。谨慎使用 shell 展开:
pandoc chapter*.md -o book.pdf # 字母顺序,如果你零填充了编号则没问题
生成目录:
pandoc chapter*.md --toc -o book.pdf
章节间加 LaTeX 分页:
pandoc chapter*.md --toc --top-level-division=chapter -o book.pdf
不想装 Pandoc,先拼接:
echo "" > combined.md
for f in chapter*.md; do
cat "$f" >> combined.md
echo -e "\n\n<div style=\"page-break-before: always;\"></div>\n\n" >> combined.md
done
md-to-pdf combined.md
<div> 在章之间插入分页。初级但可靠。
一个在每次 push 到 main 时生成 PDF 的 GitHub Actions:
# .github/workflows/build-pdfs.yml
name: Build PDFs
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g md-to-pdf
- run: md-to-pdf 'docs/**/*.md'
- uses: actions/upload-artifact@v4
with:
name: pdfs
path: 'docs/**/*.pdf'
对 docs/ 下所有 Markdown 运行 md-to-pdf,PDF 作为构建产物上传。改成 tag push 触发,可以附加到 Release。
- 合并 PDF 中图片路径出错。 如果
chapter01.md引用了./images/a.png,拼接后路径会坏。要么重写为绝对路径,要么嵌入为 data URI,要么用 Pandoc 的--resource-path=.加查找路径。 - front-matter 冲突。 每个
.md可能有自己的 YAML front-matter。Pandoc 取第一个;md-to-pdf逐文件模式读各自的。如果冲突,拼接前先去掉。 - 页码在章间重置。 Pandoc 用
--top-level-division=chapter处理;拼接路径不会,页码连续(书里通常这个是你要的)。 - Unicode / CJK 字体。 中日韩:Pandoc 配 XeLaTeX 需
--pdf-engine=xelatex -V mainfont:"Source Han Serif CN"。Headless Chromium 的工具(md-to-pdf、/markdown-to-pdf)继承系统字体栈,开箱就能用。 - 批量大时的内存。 500+ 个文件走
md-to-pdf会启动 Chromium 几百次。用xargs -P并行,但并发度不超 CPU 核数。
- 偶尔单文件 →
/markdown-to-pdf。打开页面比装 npm 快。 - 同一模板、十几个文件、一次性 →
md-to-pdfCLI。 - 同一模板、多文件、每次提交 → CI 里的 CLI。
- 书、报告、多章节 → Pandoc +
--top-level-division=chapter --toc。 - 每章不同模板 → 先逐文件生 PDF(场景 1),后用
pdfunite或qpdf合并。
更多各工具权衡看 Markdown 转 PDF 方法对比 与 PDF 中代码高亮深入。
如果你已经生成了各自的 PDF,只是要拼接不重新渲染:
# pdfunite (poppler-utils)
pdfunite chapter01.pdf chapter02.pdf chapter03.pdf book.pdf
# 或 qpdf
qpdf --empty --pages chapter*.pdf -- book.pdf
# 或 ghostscript
gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=book.pdf chapter*.pdf
不重新渲染意味着无损且快(100 个文件 1 秒以内)。
能用网页 /markdown-to-pdf 做批量吗?
网页工具是单文件的。批量请用 CLI;一次性请用网页。有人跑完 CLI 后手工打包一下。
批量模式里怎么保留代码高亮?
CLI 用 --stylesheet 传入的主题会被所有文件继承。一致使用同一主题。详见 Markdown 转 PDF 保留代码高亮。
单个合并 PDF 的上限是多少?
功能上无限 —— 我们见过 5000 页的合并 PDF 运行正常。实际上:PDF 阅读器在 ~1000 页后搜索变慢,邮件附件在 25 MB 上下。超大文档拆卷。
有批量转换 API 吗?
有 —— 我们的 Markdown to Image API 支持 format=pdf 参数,任何能进行 HTTP 调用的语言都能脚本化批量转换。不想在 CI 添加 Node 依赖时很有用。
Pandoc 批量模式里保留 Mermaid 图表吗?
不原生支持。需要 pandoc-mermaid-filter 或者先把 Mermaid 转 SVG 再引用。npm CLI 批量也需要 markdown-it Mermaid 插件。
选什么批量工具看你要出什么:
- 1对 1 PDF →
md-to-pdf '*.md' - 多对 1 书 →
pandoc chapter*.md --toc -o book.pdf - 持续构建 → GitHub Actions + npm CLI
- 合并现有 PDF →
pdfunite或qpdf
如果是一次性批量且以上都没装,摩擦最小路径是:用网页 /markdown-to-pdf 逐文件跳标签页跱一遍,最后 pdfunite 拼上。