【发布时间】:2020-02-19 09:05:17
【问题描述】:
我有一个FixedDocument,我允许用户在 WPF GUI 中预览,然后打印到纸上而不显示任何 Windows 打印对话框,如下所示:
private void Print()
{
PrintQueueCollection printQueues;
using (var printServer = new PrintServer())
{
var flags = new[] { EnumeratedPrintQueueTypes.Local };
printQueues = printServer.GetPrintQueues(flags);
}
//SelectedPrinter.FullName can be something like "Microsoft Print to PDF"
var selectedQueue = printQueues.SingleOrDefault(pq => pq.FullName == SelectedPrinter.FullName);
if (selectedQueue != null)
{
var myTicket = new PrintTicket
{
CopyCount = 1,
PageOrientation = PageOrientation.Portrait,
OutputColor = OutputColor.Color,
PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA4)
};
var mergeTicketResult = selectedQueue.MergeAndValidatePrintTicket(selectedQueue.DefaultPrintTicket, myTicket);
var printTicket = mergeTicketResult.ValidatedPrintTicket;
// TODO: Make sure merge was OK
// Calling GetPrintCapabilities with our ticket allows us to use
// the OrientedPageMediaHeight/OrientedPageMediaWidth properties
// and the PageImageableArea property to calculate the minimum
// document margins supported by the printer. Very important!
var printCapabilities = queue.GetPrintCapabilities(myTicket);
var fixedDocument = GenerateFixedDocument(printCapabilities);
var dlg = new PrintDialog
{
PrintTicket = printTicket,
PrintQueue = selectedQueue
};
dlg.PrintDocument(fixedDocument.DocumentPaginator, "test document");
}
}
问题是我还想通过提供文件目标路径而不显示任何 Windows 对话框来支持虚拟/文件打印机,即 PDF 打印,但这似乎不适用于 PrintDialog。
我真的很想尽可能避免使用 3rd 方库,所以至少现在,使用 PdfSharp 之类的东西将 XPS 转换为 PDF 并不是我想做的事情。 更正:似乎从最新版本的 PdfSharp 中删除了 XPS 转换支持。
经过一些研究,似乎直接打印到文件的唯一方法是使用PrintDocument,可以在PrinterSettings 对象中设置PrintFileName 和PrintToFile,但没有办法要给出实际的文档内容,我们需要订阅 PrintPage 事件并在创建文档的位置进行一些 System.Drawing.Graphics 操作。
这是我尝试过的代码:
var printDoc = new PrintDocument
{
PrinterSettings =
{
PrinterName = SelectedPrinter.FullName,
PrintFileName = destinationFilePath,
PrintToFile = true
},
PrintController = new StandardPrintController()
};
printDoc.PrintPage += OnPrintPage; // Without this line, we get a blank PDF
printDoc.Print();
然后是我们需要构建文档的PrintPage 的处理程序:
private void OnPrintPage(object sender, PrintPageEventArgs e)
{
// What to do here?
}
我认为可以使用的其他方法是使用System.Windows.Forms.PrintDialog 类,但这也需要PrintDocument。我能够像这样轻松地创建 XPS 文件:
var pkg = Package.Open(destinationFilePath, FileMode.Create);
var doc = new XpsDocument(pkg);
var writer = XpsDocument.CreateXpsDocumentWriter(doc);
writer.Write(PreviewDocument.DocumentPaginator);
pkg.Flush();
pkg.Close();
但它不是 PDF,如果没有第三方库,似乎无法将其转换为 PDF。
是否有可能做一个自动填充文件名然后点击PrintDialog上的保存的hack?
谢谢!
编辑: 可以使用Microsoft.Office.Interop.Word 从 Word 文档直接打印到 PDF,但似乎没有从 XPS/FixedDocument 转换为 Word 的简单方法。
编辑:目前看来,最好的方法是获取 PdfSharp 1.31 中存在的旧 XPS 到 PDF 转换代码。我抓取了源代码并构建了它,导入了 DLL,它就可以工作了。感谢 Nathan Jones,查看他关于 here 的博客文章。
【问题讨论】:
-
我记得 Microsoft Print to PDF 没有提供该选项。我的一个解决方法是创建一个 XPS 或 PNG 文件并使用 GhostScript 转换为 PDF。
-
@NawedNabiZada 我宁愿避免安装第 3 方工具并从我的代码中调用 exe,但感谢您分享知识。