使用 Windows 窗体的 PrintDocument 直接将 WPF FlowDocument 保存为 PDF 文件

Posted

技术标签:

【中文标题】使用 Windows 窗体的 PrintDocument 直接将 WPF FlowDocument 保存为 PDF 文件【英文标题】:Saving WPF FlowDocument to PDF file directly by using PrintDocument of Windows Forms 【发布时间】:2019-02-11 10:18:41 【问题描述】:

我在 Windows 10 中使用 Microsoft Visual Studio 2017 和 Microsoft Print to PDF。

我尝试在没有 PrintDialog 的情况下制作 FlowDocument 的 PDF 文件,我知道这在纯 WPF 中是不可能的。所以我将 Windows 窗体的 system.drawing.printing.PrintDocument 引用到我的 WPF 项目中。

我被困在将 FlowDocument 转换为 PrintDocument 的问题上。

PrintDocument _PrintDocument = (PrintDocument)FlowDocument1;

IDocumentPaginatorSource _DocumentPaginatorSource = FlowDocument1;
PrintDocument _PrintDocument = FlowDocument1;

它们都不起作用。

是否可以通过使用代码分配文件夹和文件名来制作PDF?我一定要使用 3rd 方组件吗?

【问题讨论】:

换句话说,您正在询问如何将 FlowDocument 打印为 PDF。只要有可用的 PDF 打印机驱动程序,就可以像在任何打印机上打印一样。你试过什么,什么不起作用?您可以打印到实际打印机吗?是否安装了 PDF 打印机驱动程序? 正如我上面提到的,我想要通过打印机保存直接文件而不是物理文档。谢谢。 这就是Print to PDFPrint to FilePrint to XPS 所做的。 PrintDocument是一个用于打印的类,不生成文件 @PanagiotisKanavos PrintDocument 确实通过 PrinterSettings 类制作文件。谢谢。 因为这就是打印到文件的意思。它通过将输出发送到文件而不是实际打印机的打印机驱动程序来实现。如果您想回答您的问题,则需要找到 PDF 打印机驱动程序 【参考方案1】:

如果您可以将默认打印机设置为 PDF 或 XPS,那么您可以使用此代码 sn-p。它将使用默认打印机,然后打印您想要的视觉效果。请记住,如果您需要与横向不同的方向,则应更改它。编辑: 为了完整起见,您可以像这样搜索 PDF 打印的打印机队列:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Printing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Xps;
using System.Windows.Xps.Packaging;

namespace Services.Printing

    public static class PrintingService
    
        public static void Print(Visual elementToPrint, string description)
        
            using (var printServer = new LocalPrintServer())
            
                var dialog = new PrintDialog();
                //Find the PDF printer
                var qs = printServer.GetPrintQueues();
                var queue = qs.FirstOrDefault(q => q.Name.Contains("PDF"));
                if(queue == null) /*handle what you want to do here (possibly use XPS?)*/
                dialog.PrintTicket.PageOrientation = PageOrientation.Landscape;
                dialog.PrintQueue = queue;
                dialog.PrintVisual(elementToPrint, description);
            
        
    

【讨论】:

这个 sn-p 打印到默认的 prinet,它没有指定 XPS。如果指定了适当的驱动程序,它可以用于打印到 PDF 或 XPS 因此如果您可以将默认打印机设置为 XPS 您的代码调用了一个 PDF 文件保存对话框,这不是我所要求的解决方案。谢谢。 @SHINJaeGuk 你试过 Xamimax 的代码了吗? PrintVisualdoesn't display a dialog box. @PanagiotisKanavos 是的,我确实做到了。对,它不会调用 PrintDialog,而是会调用 PDF 文件保存对话框,询问文件名和文件夹。 PrintDialog 询问我选择哪种打印设备。 PDF 有 2 个对话框。谢谢。【参考方案2】:

在当前的Windows和WPF版本下,似乎没有没有任何对话框的直接PDF文件保存方式。但我通过 PdfSharp.Xps 得到了答案。非常简单,文档的质量保存得很好。

您可以通过 Visual Studio 的 Nuget 包管理器轻松使用它。

【讨论】:

以上是关于使用 Windows 窗体的 PrintDocument 直接将 WPF FlowDocument 保存为 PDF 文件的主要内容,如果未能解决你的问题,请参考以下文章

我用C#创建的是windows窗体应用项目,做的是登陆页面,里面可以使用session吗

使用两个 Windows 窗体 DataGridView 控件创建一个主/从窗体

使用另一个窗体应用程序更改 Windows 窗体的背景颜色

如何使用 WCF 在 Windows 服务和 Windows 窗体之间进行通信?

VSTO避免多次加载窗体

SignalR - 在Windows窗体服务器上验证Windows窗体用户