printdocument 不能直接打印 pdf 文件,因其依赖 graphics 绘图指令,而 pdf 是封装的二进制格式;需用 pdfium.net sdk 解析 pdf 为位图再交由 printdocument 渲染。

PrintDocument 能不能直接打印 PDF 文件
不能。PrintDocument 是面向“绘图指令”的打印模型,它通过 OnPrintPage 事件回调,要求你用 Graphics 对象一帧一帧绘制内容——而 PDF 是封装好的二进制文档格式,它本身不提供可直接喂给 Graphics 的绘图逻辑。
常见错误现象:PrintDocument 打印出空白页、只打第一页、文字错位、中文乱码,本质都是试图“绕过解析”强行把 PDF 字节流塞进 Graphics.DrawString 或类似操作。
所以,静默打印 PDF 的关键不是“怎么配 PrintDocument”,而是“怎么把 PDF 解析成 PrintDocument 能理解的图形指令”。
推荐方案:用 Pdfium.Net SDK + PrintDocument(轻量、可控)
Pdfium.Net 是开源、免 license、支持 .NET 5+ 的 PDF 渲染库,它能将 PDF 页面精确转为 Bitmap 或直接绘制到 Graphics,再交由 PrintDocument 输出。比调用 Adobe Acrobat 或外部命令行工具更稳定、无弹窗、可嵌入部署。
实操建议:
- 通过 NuGet 安装
Pdfium.Net.SDK(注意选官方作者pdfium.net,非第三方 fork) - 加载 PDF 时用
PdfDocument.Load(),务必捕获IOException和InvalidPdfException——损坏或加密 PDF 会在这里失败 - 每页调用
page.Render()生成Bitmap,分辨率建议设为300DPI(scale = 300f / 96f),低于 200 DPI 可能模糊,高于 600 DPI 易触发 GDI 内存溢出 - 在
PrintPageEventArgs.Graphics上用DrawImage绘制位图,注意用InterpolationMode.HighQualityBicubic防锯齿
示例片段(关键逻辑):
private void printDoc_PrintPage(object sender, PrintPageEventArgs e) {
var page = doc.Pages[currentPageIndex];
using var bmp = page.Render(300, 300, true, true, false); // width, height, isGrayscale, isAnnotations, isTextOnly
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.DrawImage(bmp, e.MarginBounds);
e.HasMorePages = ++currentPageIndex
<h3>替代方案对比:Process.Start vs. Ghostscript vs. Pdfium</h3>
<p>很多人第一反应是用 <code>Process.Start("AcroRd32.exe", "/t ...")</code> 静默打印,但实际问题很多:</p>
-
AcroRd32.exe在 Windows 10/11 中默认不安装,且 Adobe 已明确弃用该命令行接口 -
Ghostscript需要额外部署 gs.dll + fonts + ps2write 设备,中文路径、空格、权限常导致ExitCode = -100错误 -
Pdfium.Net唯一硬性依赖是 vc_redist.x64(运行时已自带),无注册表写入、无后台进程残留,适合服务端或 WinForms 后台线程调用
性能上:单页 A4 PDF(1MB)渲染耗时约 80–200ms(i5-8250U),比 Process.Start 启动 Acrobat 快 3–5 倍,且内存占用可控(Bitmap 可 Dispose,PdfDocument 可复用)。
静默打印必须处理的三个细节
即使 Pdfium 渲染正确,仍可能因系统级设置失败:
-
打印机未设为默认时,
PrintDocument.PrinterSettings.PrinterName必须显式赋值,否则抛InvalidPrinterException;建议先用PrinterSettings.InstalledPrinters校验名称是否存在 - 部分网络打印机对
PrinterSettings.Copies > 1有严格校验,若需多份,建议循环调用Print()而非设Copies属性 - PDF 页面尺寸(如 A3)大于打印机纸盒设置(如仅 A4),Windows 会自动缩放并报
PrintPageEventArgs.Cancel = true——需提前用page.GetSize()比对PrinterSettings.PaperSizes,不匹配时主动缩放或报错提示
静默不是“不报错”,而是把错误收口在代码里。最容易被忽略的是纸张匹配逻辑——很多现场问题都卡在这一步,而不是渲染本身。











