日常写技术文档、记笔记、维护项目 README基本都离不开 Markdown。写的时候很爽但真要发给别人看或者打印成纸质版还是得转成 PDF。这个问题看起来简单实操起来却有不少坑有的工具转换后中文乱码有的代码块没有语法高亮有的表格直接变形还有的折腾半天装了一堆依赖还是报错。我前后试过十几种方案最后固定下来 3 种最顺手的带预览的编辑器直接导出、Pandoc 命令行转换、VS Code 插件批量处理。这篇就把三种方法从安装到实操完整走一遍用同一个测试文档对比排版效果、转换速度和操作步数帮大家找到最合适的一条路。赶时间的朋友直接看第三部分实测结论不赶时间的可以按顺序看完每一步都有踩坑记录。1. 三种方案选型GUI 预览、命令行批量、编辑器插件各自解决什么问题先说结论不存在一个“万能”的工具不同场景下的最优解完全不同。选型之前先搞清楚自己的痛点是什么——是偶尔转一份几十页的文档还是要批量处理成百上千个文件是追求最短操作路径还是对排版细节有苛刻要求我曾经用 A 同学的习惯打个比方。A 同学是个产品经理平时用某个带实时预览的编辑器写需求文档他需要的是“所见即所得”打开文件、点导出、拿到 PDF最好别让他碰命令行。B 同学是个开源项目维护者仓库里有大量 README 和文档需要定时生成 PDF 发布他要的是脚本化、可复现一条命令批量产出。C 同学是个技术博主经常要把稿子转成 PDF 存档他既要排版可控又懒得记复杂参数。这三种需求分别对应三种方案。方案一是带预览的桌面编辑器直接导出 PDF优点是零配置、操作路径最短适合单篇文档快速转换方案二是 Pandoc 配合 LaTeX 引擎适合批处理和对排版有自定义需求的用户但前期环境搭建成本高方案三是 VS Code 装插件导出在编辑器生态内完成闭环适合本来就在 VS Code 里写文档的人兼顾了自动化能力和可视化操作。选型还要考虑一个容易被忽视的因素文档内容复杂度。纯文字文档用什么工具转都差不多但一旦涉及代码块、表格、数学公式、流程图、图片引用不同工具的渲染差异就出来了。我的实测文档里特意把这些元素全部塞了进去就是为了暴露工具之间的真实差距。2. 三种方法实操全记录从环境准备到最终导出2.1 方法一带预览的桌面编辑器直接导出这个方法的核心思路是“在编辑器里渲染好再通过打印引擎输出 PDF”。我把测试文档用某款常用的 Markdown 编辑器打开左侧是源码右侧是实时渲染结果。确认排版没问题后点击右上角的导出按钮选择 PDF 格式几秒钟后就拿到了成品文件。整个操作确实只有两步打开文件、导出 PDF。不需要安装任何额外组件编辑器内置的渲染引擎会处理代码高亮、表格边框、标题层级这些样式。实测下来一个包含图片和公式的中等长度文档从打开到导出完成不到五秒。这个方案最适合的场景是临时转换、单篇文档、对排版样式没有特殊要求的用户。但要注意这类编辑器的导出实质上是把渲染后的 HTML 通过内置的 Chromium 内核打印成 PDF。这意味着如果文档里有超链接默认是不会自动变成可点击的如果文档里嵌入了外部图片导出时可能需要加载网络资源。我在实测中就遇到过一个问题文档里引用了一张外链图片网络波动导致导出时图片位置变成空白占位。解决办法是把图片下载到本地再引用或者使用不带外部依赖的图床。2.2 方法二Pandoc 命令行转换方案Pandoc 被称为“文档格式转换的瑞士军刀”支持的格式转换组合多到吓人。在 Markdown 转 PDF 这个场景里Pandoc 本身只负责把 Markdown 转换成 LaTeX 源文件真正的 PDF 渲染工作由 LaTeX 引擎完成。这也是它安装起来比一般工具麻烦的原因——你需要装 Pandoc 本体还需要装一个 LaTeX 发行版。我用的组合是 Pandoc 加 TinyTeX。TinyTeX 是精简版的 TeX Live体积比完整版小很多安装时间也更短。基础的转换命令长这样pandoc input.md -o output.pdf --pdf-enginexelatex -V mainfontNoto Serif CJK SC解释一下几个关键参数。--pdf-enginexelatex指定用 XeLaTeX 引擎而不是默认的 pdfLaTeX这是中文文档能正常显示的前提。-V mainfont设置正文字体我指定的某个中文字体如果不存在于你的系统里需要用fc-list :langzh查看系统已安装的中文字体替换成实际有的字体。不加这个参数中文大概率会变成方块乱码这是新手最容易卡住的地方。如果需要代码高亮追加参数pandoc input.md -o output.pdf --pdf-enginexelatex --highlight-styletango--highlight-style可以换成zenburn、kate、monochrome等主题。实测下来tango的配色在黑白打印时对比度最好zenburn偏暗色调适合屏幕阅读。批量转换就写个循环脚本我一次性处理过 20 个文档总耗时约两分钟效率和稳定性明显好过手动操作。2.3 方法三VS Code 插件导出VS Code 本身只是个代码编辑器但它的插件生态让它能干很多超出“编辑器”范畴的活。我用的插件是 Markdown PDF安装后只需要打开 Markdown 文件右键选择导出 PDF 即可。插件默认使用系统自带的 Chrome/Chromium 渲染所以排版效果和浏览器打印基本一致。这个方案的优势在于如果你平时就在 VS Code 里写文档不需要切换到其他工具也不需要理解 Pandoc 的复杂参数。而且插件支持配置文件自定义导出样式比如修改页边距、页面尺寸、页眉页脚内容。最常用的一个配置项是通过markdown-pdf.format.PageSize指定页面大小默认是 A4可以改成 Letter 或者自定义尺寸。和方案一类似这个插件走的也是“渲染 HTML 再打印”的路线。实测效果有个明显差异代码块的背景色、行号、高亮主题直接继承 VS Code 的 Markdown 预览样式比方案一自带渲染要好看一些。但如果文档里的数学公式用了行内公式用单个美元符号包围这个插件默认支持不好需要在设置里把markdown-pdf.math相关选项打开才能正确显示。我实测时第一次导出公式位置变成了一串原始 LaTeX 代码就是这个原因。3. 实测对比同一份文档三种方法谁最快、谁最稳、谁最省心3.1 测试环境与测试文档设计为了公平对比我准备了一个标准的测试文档里面包含五个不同层级的标题、一段长中文文本、一个带 10 行 Python 代码的代码块、一个 3 行 3 列的表格、一个行内数学公式和一个块级数学公式、一张本地图片、一条超链接。测试电脑是 Windows 11处理器是常见的 i5 级别内存 16G所有工具都是当前最新稳定版本。这个文档刻意模拟了一篇真实技术博客的完整结构因为只测纯文本没有意义大多数人的文档都比纯文本复杂。每跑完一次转换我记录三样东西操作步数从打开工具到拿到 PDF 的点击/命令数、转换耗时从触发导出到文件生成完毕、输出文件大小。同时人工检查最终 PDF 中每个元素的呈现结果分“正常”“勉强能用”“损坏”三档记录。3.2 测试结果与速度分析先说总耗时结论方案一最快从打开编辑器到拿到 PDF大约 5 秒操作步数严格说是两步。方案三略慢一点大约 8 秒。方案二如果从安装环境开始算最慢但真正执行转换命令只需要 3 秒左右。如果看“净转换时间”Pandoc 反而是最快的。三者在渲染质量上的差异更加微妙。方案一和方案三都使用 Chromium 内核打印页面所以在元素支持度上有相似性——图片正常、表格正常、超链接正常。方案一在代码高亮上中规中矩默认配色不够精致但胜在清晰。方案三集成 VS Code 的预览主题代码块显示效果更好一些。方案二的排版质量是最好的尤其是文字间距和页面边距的控制非常精细但代价是定制样式需要改 LaTeX 模板学习成本明显更高。如果只是默认模板直接转中文字体如果没配对效果反而不如前两个方案。从稳定性看方案二在批量转换场景下明显胜出跑 20 个文件没有一次出错。方案一和方案三在单文件场景都很稳定但批量操作不太适合——不是不能做而是手动点 20 次鼠标实在不合理。3.3 三种方法适用场景速查对比维度编辑器导出Pandoc 方案VS Code 插件操作步数2 步1 条命令3 步打开、右键、导出单文件净耗时约 5 秒约 3 秒约 8 秒批处理能力弱极强一般学习成本零较高低排版精细度中高中中文支持开箱即用需配置字体开箱即用公式渲染一般优秀需手动开启我的建议很直接如果你一年只转十几次文档无脑用方案一就行不需要为了低频需求折腾环境。如果你是开发者文档数量多且需要定期生成花半小时配好 Pandoc 环境后面省下的时间远超投入。如果你本来就在 VS Code 里写 Markdown方案三是零成本切入不用切工具就能满足 90% 的日常需求。4. 转完 PDF 之后常见问题排查与其他实用技巧4.1 中文乱码问题的根源与解决中文乱码是 Markdown 转 PDF 的头号问题原理其实一句话就能说清楚PDF 生成引擎找不到能渲染中文字形的字体。方案一和方案三因为走的是 Chromium 打印系统里只要有中文字体基本就能用。真正容易中招的是方案二默认的 LaTeX 引擎不加载中文字体必须手动指定字体。解决的路径有两种任选其一要么用 XeLaTeX 引擎配合-V mainfont指定中文字体要么在 Markdown 的 YAML 头部里加 metadata 声明字体参数。我推荐把字体参数写进文档头部这样同一个文档在任何设备上转换效果都一样--- mainfont: Noto Serif CJK SC monofont: Noto Sans Mono CJK SC ---一个隐藏的坑如果文档包含代码块需要单独设置monofont否则中文注释会变成乱码或者被替换成奇怪的字体。这个我踩过很深的坑默认的 monofont 对中文字符支持并不好。4.2 目录、页眉页脚和超链接这些细节导出 PDF 后目录是否可点击很多人不太在意但实际体验差别很大。方案一导出的目录是静态文本不能跳转方案二默认生成可点击的超链接目录点击能跳转到对应章节方案三默认不生成目录需要在插件配置里开启。页眉页脚方面方案一和方案三默认生成页码但页码的位置和字体大小需要进入设置调整。方案二可以通过 LaTeX 模板高度自定义想要“公司名 页码 日期”这种组合都能实现。超链接的问题前面提过如果你希望 PDF 里的链接可点击需要确认导出时打开了对应选项方案一默认是关闭的。我养成的习惯是正式对外发布的文档统一用方案二处理利用--toc参数自动生成目录pandoc input.md -o output.pdf --toc --toc-depth2--toc-depth2让目录只显示到二级标题这样目录不会太长。如果文档结构很深全部列出来反而显得杂乱。4.3 工具使用中的几个隐藏坑用方案一导出时有一个非常反直觉的问题如果文档里包含 SVG 格式的图片预览能正常显示但导出后的 PDF 里这个图可能变成空白。原因在于 Chromium 的打印引擎在导出 SVG 到 PDF 时部分样式支持并不完整。解决方法是提前把关键图片转成 PNG 格式虽然会损失一点清晰度但至少不会空白。方案三的插件在某些操作系统版本上有一个兼容性问题表现为点击导出后没有任何反应过几分钟才弹出一个空白 PDF。原因是插件调用的 Chrome 渲染进程没有正确初始化解决办法是在插件设置里更换渲染引擎路径或者升级到最新版本。这个问题在不同版本间反复出现过最新的解决办法是给插件指定一个明确位置的 Chrome 可执行文件路径{ markdown-pdf.executablePath: C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe }方案二看着最“技术流”其实也有坑。如果安装 LaTeX 发行版时选择的是基础版而不是完整版一些常用的宏包缺失会导致转换直接报错。比如文档里有一个表格Pandoc 生成 LaTeX 时可能用到longtable宏包基础版 TinyTeX 不一定预装运行时会报Environment longtable undefined。解决办法是手动安装缺失的宏包tlmgr install longtable这个坑专门坑聪明人因为报错信息很像代码写错了其实只是环境没装好。5. 这几个月的使用心得为什么最终留下了这三种组合工具用多了慢慢会发现Markdown 转 PDF 这件事本质上是“HTML/CSS 渲染能力”和“LaTeX 排版能力”的博弈。方案一和方案三站在浏览器一侧能用 CSS 控制一切样式开箱即用方案二站在出版级排版一侧输出质量上限高但入门门槛也高。没有哪边绝对正确看的是你手头的活儿更需要哪边的能力。我个人的工作流现在是这样的给团队内部同步的文档统一用方案一图快、零配置打开直接导出发到群里。给客户或对外发布的正式文档走方案二加目录、配好中文字体、定制页码出来的文件质感明显好一个档次。在写代码仓库里的 README 时顺手转到 PDF 存档就用方案三因为本来就在 VS Code 里不需要额外打开任何工具。最后分享一个小技巧不管是哪个方案导出的 PDF 体积如果异常大比如一个几十页文档超过了几十 MB多半是文档里的图片没有压缩。Markdown 里引用的图片通常都是原图直接嵌入 PDF 会保留全部信息。我在往文档里插入截图前会用脚本把超过一定宽度的图片自动压缩再引用转换后的 PDF 体积能缩小一半还多。这个习惯坚持了挺长时间效果非常值得。Markdown 转 PDF 不是什么高深技术但把细节抠到这一步使用体验才能真正稳定下来。