用 QuestPDF
生成 PDF 最轻量且可控
如果你只是把简单 HTML 片段(比如报表、邮件模板)转成 PDF,
QuestPDF是目前 C# 生态里最干净的选择——它不依赖系统组件、不调用外部浏览器进程、纯 .NET 实现,且能精确控制布局。但它不解析 HTML 字符串,需要你手动把 HTML 结构映射为
QuestPDF的 API 调用。
典型做法是:用
HtmlAgilityPack解析 HTML,再遍历节点,对
<p></p>、
<h1></h1>、
<table> 等标签分别调用 <code>Container、
Text、
Table等构建器。表格和样式支持有限,比如
colspan可以处理,但 CSS Flex/Grid 完全不识别。
示例片段(渲染一个带标题和段落的简单页面):
var doc = Document.Create(container =>
{
container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(20);
page.Content().Element(ComposeTitle);
});
});
<p>doc.GeneratePdf("output.pdf");</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p><p>void ComposeTitle(IContainer container)
{
container
.PaddingVertical(10)
.Text("Hello World").FontSize(24).Bold();
container
.PaddingVertical(5)
.Text("This is a paragraph.").FontSize(12);
}用 Wkhtmltopdf
+ Rotativa
或 HtmlToPdf
库做“真 HTML 渲染”
当你需要保留 CSS 样式、字体、媒体查询甚至 JavaScript 渲染后的内容(比如 ECharts 图表截图),就得走 WebKit 渲染路线。
Wkhtmltopdf是底层引擎,Windows/macOS/Linux 都有预编译二进制,C# 通过进程调用或封装库驱动它。
Rotativa.AspNetCore(ASP.NET Core)或
HtmlToPdf(.NET Standard)是常用封装,它们本质都是启动
wkhtmltopdf.exe并传参。关键点:
--no-stop-slow-scripts必加,否则 JS 执行超时会截断内容
--enable-local-file-access要开,否则
file://引用的 CSS/图片加载失败 字体问题常见:Windows 上默认用 SimSun,Linux 上可能缺中文字体,需提前安装并用
@font-face指向绝对路径 生成时间不可控,单次调用通常 300–800ms,高并发下建议加进程池或改用服务化部署(如独立 PDF 渲染 API)
Microsoft.Web.WebView2
在 .NET 6+ 中可离线渲染但极难稳定
WebView2 基于 Edge Chromium,理论上能完美渲染任意 HTML。但把它用于服务端 PDF 导出,实际踩坑密集:
必须显式创建
CoreWebView2Environment并指定固定用户数据文件夹,否则多线程下
WebView2初始化失败;导出 PDF 需调用
PrintToPdfAsync,而该方法仅在 UI 线程可用——意味着你得在后台线程里伪造一个 WinForms/WPF 消息循环,或改用
Dispatcher调度,极易死锁。
更现实的问题是:它强制依赖目标机器安装 WebView2 Runtime(约 180MB),无法 AOT 发布,且 Linux/macOS 不支持。除非你已锁定 Windows 桌面环境并控制全部部署条件,否则不建议选这条路。
别忽略编码与中文乱码这个高频故障点
所有方案都可能在含中文的 HTML 中输出方块或空格,根源几乎全是编码声明缺失或不一致:
HTML 字符串开头必须有<meta charset="utf-8">,且 HTTP 响应头(如果走 URL 加载)也要设
Content-Type: text/html; charset=utf-8用
File.ReadAllText(path, Encoding.UTF8)读取本地 HTML 文件,别依赖默认编码
Wkhtmltopdf若仍乱码,尝试加参数
--encoding utf-8(部分旧版本不支持,需 v0.12.6+) CSS 中避免用系统字体名(如
"微软雅黑"),改用通用族名
font-family: sans-serif,或确保 PDF 引擎能访问对应 TTF 文件
真正麻烦的是混合场景:HTML 里有 Base64 图片、内联 SVG、动态
fetch数据——这些都会让转换链路变脆弱。与其强求一步到位,不如把 HTML 拆成「静态结构 + JSON 数据」,用模板引擎(如
Scrutor或
Fluid)先渲染为纯净 HTML,再交给 PDF 工具处理。
