以前写技术文档,我都是 Word 里调格式调到崩溃。后来改用 Markdown,清爽了,但领导说“你给我交 Word”。同事交了个 PDF,我交了个 .md 文件,人家打不开。直到我发现了 Pandoc——一行命令,Markdown 变 Word、PDF、PPT、甚至 epub。现在我是团队里“最会交作业的人”。
这篇博客不是 Pandoc 官方手册,而是我从实际场景出发,把 Markdown 转换过程中最常用的命令、参数、以及那些我摔过的跟头全部摊开来讲。
一、为什么你还需要 Pandoc
- Markdown 写起来快,但别人要 Word/PDF/HTML,你总不能一个个复制粘贴。
- 写简历、论文、技术手册,需要自动生成目录、页眉页脚、引用文献。
- 把多个 Markdown 文件合并成一个文档(比如把几十篇周报合成一本)。
- 从 Markdown 直接生成 PPT(是的,Pandoc 可以转 beamer/reveal.js)。
Pandoc 能读几十种格式(Markdown, reST, HTML, LaTeX, docx...),能写几十种格式(PDF, epub, pptx, jira wiki, 甚至织梦的标记语言……)。你只需要学会一种写作方式:Markdown。
二、安装(顺便说说我遇到的坑)
Linux (Ubuntu/Debian)
sudo apt update
sudo apt install pandoc
踩坑:Ubuntu 20.04 自带的 pandoc 版本是 2.5(很老),不支持 --citeproc(文献引用)等新功能。建议去官网下载最新的 .deb 包,或者用 conda 装。
迫不得已我更推荐从 GitHub releases 下载静态二进制:
wget https://github.com/jgm/pandoc/releases/download/3.1.11/pandoc-3.1.11-1-amd64.deb
sudo dpkg -i pandoc-*.deb
装完后验证:
pandoc --version
pandoc 3.1.11
macOS
brew install pandoc
# 如果还要 LaTeX 才能转 PDF(见下文),额外装:
brew install --cask basictex
没什么坑,但记得装完 basictex 后要更新 $PATH。
Windows
choco install pandoc
# 或去 github releases 下载 .msi
另外 Pandoc 转 PDF 依赖 LaTeX 引擎(pdflatex/xelatex)。最省事的是安装 MiKTeX 或 TeX Live。不装的话,你可以转 .tex 文件再用 Overleaf 编译。
三、快速测试:一行命令转 PDF
拿任意一个 test.md,内容随便写,比如:
# 你好,世界
这是一个测试。
然后运行:
pandoc test.md -o test.docx
只要装了 Pandoc 本体,docx、html、epub 都不需要额外依赖。
四、常用参数(我实际工作中用到的)
4.1 基础参数
参数 含义 例子
-o 输出文件 -o output.pdf
-f 输入格式(默认 markdown) -f markdown+hard_line_breaks
-t 输出格式(默认 html) -t docx
--self-contained 把图片、CSS 都塞进 HTML 里 生成单个 HTML 文件
--standalone 生成完整文档(带 head/body) 默认单文件转换会加
4.2 PDF 生成的开关(重点)
--pdf-engine=pdflatex # 默认,也可选 xelatex, lualatex, wkhtmltopdf
--toc # 生成目录
--toc-depth=2 # 目录深度到二级标题
--number-sections # 章节自动编号
--highlight-style=tango # 代码高亮风格(tango, pygments, kate, espresso 等)
踩坑提醒:如果你的 Markdown 里有中文,用 pdflatex 会报错 ! Undefined control sequence。需要改用 xelatex 并指定中文字体:
pandoc test.md -o test.pdf --pdf-engine=xelatex -V mainfont="Noto Sans CJK SC" -V CJKmainfont="Noto Sans CJK SC"
更友好的方式:创建一个模板或使用 --variable。
4.3 引用和参考文献
Pandoc 3.0+ 原生支持 --citeproc。你需要一个 .bib 文件(BibTeX 格式)。
pandoc paper.md --citeproc --bibliography=ref.bib -o paper.pdf
在 Markdown 里用 [@citekey] 引用。
五、实战:几个我每天都在用的命令
1、Markdown 转 Word(保留表格、代码高亮)
pandoc README.md -o README.docx --highlight-style=pygments
公司内网里经常有人要 docx,这个命令救了我无数次。
2、合并多个 Markdown 文件为一个 PDF
pandoc chap1.md chap2.md chap3.md -o book.pdf --toc --number-sections
注意顺序,chap1.md 会在最前面。合并时会自动处理各文件的标题层级,且共用一套 LaTeX 模板。
3、把 Markdown 转成带侧边栏的 HTML(单个文件)
pandoc doc.md -o doc.html --standalone --self-contained --toc --toc-depth=2
生成的文件可以发给别人,不需要网络也能看到完整的样式。
4、去掉 front matter(Jekyll/Hugo 头信息)再转换
很多静态站点的 Markdown 开头有 YAML 元数据,Pandoc 默认会解析但可能不兼容。用过滤器删除:
pandoc post.md -o clean.docx --metadata title="随便" # 或者写一个 lua filter
更简单的方法:手动删除前几行,或者用 sed 预处理。
5、批量转换目录下所有 .md 为 .pdf
for f in *.md; do
pandoc "$f" -o "${f%.md}.pdf" --pdf-engine=xelatex -V mainfont="DejaVu Sans"
done
小心文件名带空格——上面 "$f" 已经处理了。
六、问题汇总(都是我真实遇到的)
1、pandoc: pdflatex not found.
原因:系统没有安装 LaTeX 引擎。
解决:只转 docx 或 html,或者安装 texlive-base (Linux) 或 basictex (macOS)。
自己挖的坑:在公司内网装不了 LaTeX?用 --to=html 输出,再用浏览器打印成 PDF,虽然不优雅但能救急。
2、中文 PDF 出来的全是空白框或乱码
原因:latex 默认字体不支持中文。
解决:强制用 xelatex + 中文字体:
pandoc -s chinese.md -o chinese.pdf --pdf-engine=xelatex -V mainfont="Microsoft YaHei" -V CJKmainfont="Microsoft YaHei"
如果是 Linux,换成 "Noto Sans CJK SC"。更通用的办法是写一个 defaults.yaml 配置文件,不用每次都敲一堆 -V。
3、表格在 Word 里跑出页面边界
场景:Markdown 表格列太多,转成 docx 后表格超宽。
原因:Pandoc 生成的 docx 表格默认不自动调整宽度。
解决:转 docx 后手动在 Word 里“自动调整到窗口”,或者用宏。
更好的方式:转成 HTML 或 PDF,控制纸张方向:
pandoc wide-table.md -o wide.pdf -V geometry:landscape -V geometry:margin=1cm
4、代码块里的特殊字符导致 LaTeX 崩溃
原因:比如 _ $ % 在 LaTeX 里是特殊字符,Pandoc 默认会转义,但有时候没转好。
解决:用 --listings 或 --highlight-style 而不是默认的。更暴力:把代码块语言指定为 text,禁用语法高亮。
5、图片路径带空格,转 PDF 后找不到图片
场景:
原因:LaTeX 处理不了空格。
解决:把图片重命名去空格,或者用 --resource-path=. 但不解决根本问题。
血泪教训:Markdown 里的图片路径永远不要用空格。
6、想生成带目录的 epub,但目录位置不对
pandoc book.md -o book.epub --toc --epub-cover-image=cover.jpg
踩坑:生成的目录会出现在正文前,但很多阅读器会自己生成目录,导致两个目录。
解决:加上 --epub-chapter-level=1 控制章节划分层级。
7、pandoc-crossref 找不到或无法安装
如果你需要给图表交叉引用(比如“见图 1.2”),Pandoc 原生不支持。社区有 pandoc-crossref 过滤器。安装麻烦,而且版本要和 pandoc 严格匹配。
我的替代方案:直接用 @label 语法 + --citeproc 假装引用,或者转成 LaTeX 后再交叉编译。
七、一点小建议
写一个 defaults.yaml 文件,把字体、模板、引擎都写好,每次 pandoc -d myconfig 一键转换。我自己的模板长这样:
from: markdown
to: pdf
pdf-engine: xelatex
variables:
mainfont: "Noto Sans CJK SC"
CJKmainfont: "Noto Sans CJK SC"
geometry: "margin=1in"
toc: true
number-sections: true
highlight-style: tango
不要在 Markdown 里手写 LaTeX 宏除非你确定只用 PDF 输出。否则转 Word 时那些 \begin{equation} 会原样输出。
如果经常转学术论文,花半小时学一下 --citeproc + Zotero 导出 BibTeX。比手工整理参考文献节约八小时。
用 pandoc -s --template=mytemplate.tex 可以自定义 LaTeX 模板,但我认为 90% 的人用默认模板 + 几个 -V 就够了。
最后,Pandoc 不是渲染最快的,但支持的格式最多。如果你只是需要本地预览 Markdown,用 glow 或 mdless 更合适。Pandoc 的角色是 “格式转换的最后一公里”。
写完这篇博客,我重新认识了一个道理:不要跟格式较劲,把内容写在最简单的 Markdown 里,输出的脏活交给 Pandoc。下次谁再跟你要 Word 版,你就一行命令丢过去,深藏功与名。