返回博客
5 分钟阅读
MarkdownToImage

批量把多个 Markdown 文件转换为 PDF 的几种方法

批量把 Markdown 转 PDF 的三种方法:一一对应用 npm CLI;多个合并为一个 PDF 用 Pandoc;每次提交生 PDF 用 CI。附可复制命令、图片路径坋以及合并现有 PDF 的方法。

批量把多个 Markdown 文件转换为 PDF 的几种方法

30 秒给答案

三种常见批量任务:

  1. 一个 Markdown → 一个 PDF,重复多个文件md-to-pdf *.md(npm CLI)。
  2. 多个 Markdown → 一个合并 PDF(一本书、多章报告):pandoc chapter*.md -o book.pdf
  3. 多个 Markdown → 每次提交输出一份 PDF:GitHub Actions + npm CLI。

浏览器版 /markdown-to-pdf 是单文件的;批量任务需要 CLI。本文走一遍三个场景,有可复制粘贴的命令与常见坋。

场景 1 —— N → N(一个 Markdown 一个 PDF)

最简单的情况。你有 chapter01.mdchapter02.md,要生成 chapter01.pdfchapter02.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 启动开销限制。

场景 2 —— N → 1(多个 .md 合成一个 PDF)

适用于书、技术报告、多文件入职文档。

Pandoc(适合有序章节)

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

拼接+转换(适用任何 Markdown→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> 在章之间插入分页。初级但可靠。

场景 3 —— CI/CD(每次提交生 PDF)

一个在每次 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。

常见坋

  1. 合并 PDF 中图片路径出错。 如果 chapter01.md 引用了 ./images/a.png,拼接后路径会坏。要么重写为绝对路径,要么嵌入为 data URI,要么用 Pandoc 的 --resource-path=. 加查找路径。
  2. front-matter 冲突。 每个 .md 可能有自己的 YAML front-matter。Pandoc 取第一个;md-to-pdf 逐文件模式读各自的。如果冲突,拼接前先去掉。
  3. 页码在章间重置。 Pandoc 用 --top-level-division=chapter 处理;拼接路径不会,页码连续(书里通常这个是你要的)。
  4. Unicode / CJK 字体。 中日韩:Pandoc 配 XeLaTeX 需 --pdf-engine=xelatex -V mainfont:"Source Han Serif CN"。Headless Chromium 的工具(md-to-pdf/markdown-to-pdf)继承系统字体栈,开箱就能用。
  5. 批量大时的内存。 500+ 个文件走 md-to-pdf 会启动 Chromium 几百次。用 xargs -P 并行,但并发度不超 CPU 核数。

什么时候用网页工具 vs CLI

  • 偶尔单文件/markdown-to-pdf。打开页面比装 npm 快。
  • 同一模板、十几个文件、一次性md-to-pdf CLI。
  • 同一模板、多文件、每次提交 → CI 里的 CLI。
  • 书、报告、多章节 → Pandoc + --top-level-division=chapter --toc
  • 每章不同模板 → 先逐文件生 PDF(场景 1),后用 pdfuniteqpdf 合并。

更多各工具权衡看 Markdown 转 PDF 方法对比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 → pdfuniteqpdf

如果是一次性批量且以上都没装,摩擦最小路径是:用网页 /markdown-to-pdf 逐文件跳标签页跱一遍,最后 pdfunite 拼上。

Markdown To Image | 批量把多个 Markdown 文件转换为 PDF 的几种方法 | MarkdownToImage