You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无打印对话框将WPF窗口直接导出为PDF?

解决方案

一、优化现有位图方案(解决占满页面+高分辨率问题)

如果暂时不想更换依赖库,可先调整现有代码解决前两个核心问题:

1. 提升渲染分辨率

将RenderTargetBitmap的DPI从默认96调高至300(或更高),同时按DPI比例放大渲染尺寸,确保生成的图片足够清晰:

// 目标打印DPI,设为300
double targetDpi = 300;
// 计算相对于系统96DPI的缩放比例
double scale = targetDpi / 96;
RenderTargetBitmap rendertargetbitmap = new RenderTargetBitmap(
    (int)(datagrid.ActualWidth * scale), 
    (int)(datagrid.ActualHeight * scale), 
    targetDpi, 
    targetDpi, 
    PixelFormats.Pbgra32);
rendertargetbitmap.Render(datagrid);

2. 让图片填满PDF页面

放弃使用MarginBounds,改用PageBounds作为绘制范围,调整缩放逻辑让图片在保留比例的前提下最大化填充页面:

doc.PrintPage += (sender, args) =>
{
    System.Drawing.Rectangle pageBounds = args.PageBounds;
    double imageRatio = (double)i.Width / i.Height;
    double pageRatio = (double)pageBounds.Width / pageBounds.Height;

    int drawWidth, drawHeight;
    if (imageRatio > pageRatio)
    {
        drawWidth = pageBounds.Width;
        drawHeight = (int)(pageBounds.Width / imageRatio);
    }
    else
    {
        drawHeight = pageBounds.Height;
        drawWidth = (int)(pageBounds.Height * imageRatio);
    }
    // 如果不需要居中,直接将x、y设为0即可完全填充页面
    int x = (pageBounds.Width - drawWidth) / 2;
    int y = (pageBounds.Height - drawHeight) / 2;
    args.Graphics.DrawImage(i, x, y, drawWidth, drawHeight);
};

注:此方案仅优化位图质量和填充效果,无法解决文本不可选中的问题。

二、直接导出WPF Grid为矢量PDF(彻底解决所有问题)

采用无交互打印或专业PDF库,直接将WPF元素以矢量格式导出为PDF,从根源解决分辨率、文本可选、页面填充的问题。

方法1:使用WPF PrintQueue实现无交互打印

利用系统自带的"Microsoft Print to PDF"打印机,直接将Grid打印到指定文件,生成的PDF为矢量格式:

public void ExportGridToPdf(string outputPath)
{
    Grid datagrid = pOTemplate.g;

    // 获取Microsoft Print to PDF打印队列
    var printQueue = new PrintQueue(new PrintServer(), "Microsoft Print to PDF");
    // 设置打印参数(横竖版、纸张尺寸按需调整)
    var printTicket = printQueue.DefaultPrintTicket;
    printTicket.PageOrientation = PageOrientation.Landscape;
    printTicket.PageMediaSize = new PageMediaSize(PageMediaSizeName.Letter);

    // 提交打印作业
    var printJob = printQueue.AddJob("采购订单打印", datagrid, printTicket);
    
    // 等待打印完成,确保文件写入完成
    while (!printJob.IsCompleted)
    {
        System.Threading.Thread.Sleep(100);
    }

    // 将系统临时生成的PDF移动到指定路径
    var tempPdfPath = printJob.GetDocumentPath();
    if (File.Exists(tempPdfPath))
    {
        Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
        File.Move(tempPdfPath, outputPath, overwrite: true);
    }
}

调用时传入目标文件路径即可,全程无用户交互,生成的PDF文本可选中、布局与Grid完全一致。

方法2:使用新版PdfSharp/MigraDoc

放弃旧版1.31,使用最新版的PDF处理库,示例以.NET Core/.NET 5+的PdfSharpCore为例:

首先安装NuGet包:

Install-Package PdfSharpCore
Install-Package MigraDocCore.DocumentObjectModel

示例代码(将Grid渲染为高清晰度PDF):

using PdfSharpCore.Drawing;
using PdfSharpCore.Pdf;
using System.Windows.Media;

public void ExportGridToPdfWithPdfSharp(string outputPath)
{
    Grid datagrid = pOTemplate.g;
    // 先测量并排列Grid,确保获取正确尺寸
    datagrid.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
    datagrid.Arrange(new Rect(0, 0, datagrid.DesiredSize.Width, datagrid.DesiredSize.Height));

    // 高DPI渲染Grid
    double dpi = 300;
    var renderBitmap = new RenderTargetBitmap(
        (int)(datagrid.DesiredSize.Width * dpi / 96),
        (int)(datagrid.DesiredSize.Height * dpi / 96),
        dpi, dpi, PixelFormats.Pbgra32);
    renderBitmap.Render(datagrid);

    // 转换为PDF并保存
    using (var stream = new MemoryStream())
    {
        var encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
        encoder.Save(stream);
        stream.Position = 0;

        var document = new PdfDocument();
        var page = document.AddPage();
        // 将WPF尺寸转换为PDF的毫米单位
        page.Width = XUnit.FromMillimeters(datagrid.DesiredSize.Width * 25.4 / 96);
        page.Height = XUnit.FromMillimeters(datagrid.DesiredSize.Height * 25.4 / 96);

        using (var gfx = XGraphics.FromPdfPage(page))
        {
            var xImage = XImage.FromStream(stream);
            gfx.DrawImage(xImage, 0, 0, page.Width, page.Height);
        }

        document.Save(outputPath);
    }
}

若需要纯矢量PDF,可手动将Grid的XAML元素映射为MigraDoc的文档结构,适合复杂布局场景。


内容的提问来源于stack exchange,提问作者m4rs___

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 00:16:04