直接用 markdown 库无法生成 PDF,必须经 Markdown→HTML→PDF 路径;推荐 pdfkit+wkhtmltopdf(需系统安装 wkhtmltopdf 并显式配置路径)或纯 Python 的 weasyprint(免系统依赖但 CSS 支持较弱),禁用 reportlab 直接渲染因维护成本过高且不支持 HTML 标签与复杂排版。

直接用 markdown 库无法生成 PDF——它只负责解析 Markdown 为 HTML,PDF 渲染必须交给其他工具链。核心路径是:Markdown → HTML → PDF,中间需明确选择渲染引擎和样式控制方式。
用 pdfkit + wkhtmltopdf 实现稳定导出
pdfkit 是最轻量且可控的方案,本质是调用命令行工具 wkhtmltopdf 渲染 HTML。它不依赖浏览器环境,生成的 PDF 排版一致、支持 CSS 分页和页眉页脚。
- 先安装系统级依赖:
wkhtmltopdf(macOS 用brew install wkhtmltopdf,Ubuntu 用apt install wkhtmltopdf) - Python 端装
pdfkit:pip install pdfkit - 转换时必须显式传入
wkhtmltopdf路径(尤其 Windows 下常报IOError: No wkhtmltopdf executable found):import pdfkit<br>pdfkit.from_file('input.md', 'output.pdf', configuration=pdfkit.configuration(wkhtmltopdf='/usr/local/bin/wkhtmltopdf')) - 注意:
pdfkit.from_file()只接受 HTML 文件,所以得先用markdown库转一次:import markdown<br>with open('input.md') as f:<br> html = markdown.markdown(f.read())<br>with open('temp.html', 'w') as f:<br> f.write(f"<html><body>{html}</body></html>")<br>pdfkit.from_file('temp.html', 'output.pdf')
用 weasyprint 替代 wkhtmltopdf(免系统依赖)
如果无法安装 wkhtmltopdf(如某些容器环境或共享主机),weasyprint 是纯 Python 实现的替代方案,依赖 cairo 和 pango,但 pip 安装时可能因系统缺失 C 库失败。
- 安装:
pip install weasyprint,若报错提示cairo.h not found,需先装系统库(Ubuntu:apt install libcairo2-dev libpango1.0-dev libpng-dev libfreetype6-dev) - 它原生支持 HTML 字符串输入,无需临时文件:
from weasyprint import HTML<br>html = markdown.markdown(open('input.md').read())<br>HTML(string=f"<html><body>{html}</body></html>").write_pdf('output.pdf') - 缺点:对复杂 CSS 支持弱于
wkhtmltopdf,表格跨页、浮动元素易错位
为什么不能直接用 markdown + reportlab?
有人想跳过 HTML 层,用 reportlab 直接画 PDF。这理论上可行,但实际极难维护——markdown 解析器输出的是 AST 或 HTML 字符串,不是结构化文档对象;reportlab 需手动映射标题、列表、代码块到 Paragraph/Spacer/Preformatted 等对象,样式、缩进、换行逻辑全得自己写,连链接下划线都要手绘矩形。
立即学习“Python免费学习笔记(深入)”;
- 常见翻车点:
reportlab不自动处理 Markdown 中的行内 HTML 标签(如<img src="...">),而markdown默认允许 HTML 输出 - 表格、数学公式(LaTeX)、自定义语法扩展(如 Mermaid 图)基本不可行
- 除非你只要极简文本(无图、无表、无样式),否则投入产出比极低
真正容易被忽略的是 CSS 控制——无论用 pdfkit 还是 weasyprint,默认导出的 PDF 字体小、页边距大、代码块没背景色。必须写一个最小 CSS 文件并用 css 参数注入,否则打印出来根本没法读。


















