打印

本指南介绍如何使用打印 API。

概述

可以通过以下方式打印网页:

  1. window.print() JavaScript 函数。 它可以从网页上的 JavaScript 代码中调用。
  2. DotNetBrowser API 的 IFrame.Print() 方法。 它请求打印 frame)。 如果您需要打印整个页面,请在主框架中调用Print()方法。 请参阅以下代码示例:
browser.MainFrame?.Print();
If browser.MainFrame IsNot Nothing Then
    browser.MainFrame.Print()
End If

网页不会立即打印。 RequestPrintHandler 将被调用以告知引擎如何处理打印请求。 默认情况下,所有打印请求都会被取消。

配置打印

有三种处理程序可用于配置打印:

  • RequestPrintHandler 用于确定如何处理打印请求。 此处理程序可用于完全取消打印、显示打印预览或告诉浏览器以编程方式打印内容。
  • PrintHtmlContentHandler 用于配置如何以编程方式打印 HTML 内容。
  • PrintPdfContentHandler 用于配置如何以编程方式打印 PDF 内容。

取消打印

要取消任何打印请求或完全禁用打印,请按以下代码示例所示注册 RequestPrintHandler

browser.RequestPrintHandler =
    new Handler<RequestPrintParameters, RequestPrintResponse>(p =>
    {
        return RequestPrintResponse.Cancel();
    });
browser.RequestPrintHandler = 
    New Handler(Of RequestPrintParameters, RequestPrintResponse)(Function(p)
        Return RequestPrintResponse.Cancel()
    End Function)

打印预览

要允许打印请求并显示打印预览对话框,请使用以下代码示例:

browser.RequestPrintHandler =
    new Handler<RequestPrintParameters, RequestPrintResponse>(p =>
    {
        return RequestPrintResponse.ShowPrintPreview();
    });
browser.RequestPrintHandler = 
    New Handler(Of RequestPrintParameters, RequestPrintResponse)(Function(p)
        Return RequestPrintResponse.ShowPrintPreview()
    End Function)

打印预览 中,您可以选择首选的打印选项:

打印预览

还可以使用 Print Preview 对话框将内容打印为 PDF。 在对话框中,您需要单击 Destination 部分中的 Change… 按钮,然后选择 Save as PDF。 按下 Save 按钮后,网页将被保存。

打印预览事件

要在打印预览对话框打开或关闭时获得通知,请使用 PrintPreviewOpened and PrintPreviewClosed 事件:

Browser.PrintPreviewOpened += (sender, args) =>
{
    // 打印预览对话框已打开。
};

Browser.PrintPreviewClosed += (sender, args) =>
{
    // 打印预览对话框已关闭
};
AddHandler Browser.PrintPreviewOpened, Sub(sender, args)
    ' 打印预览对话框已打开。
End Sub

AddHandler Browser.PrintPreviewClosed, Sub(sender, args)
    ' 打印预览对话框已关闭。
End Sub

以编程方式打印内容

要以编程方式打印内容,并在不显示任何对话框的情况下配置打印设置,需要使用多个处理程序。

首先,您需要注册 RequestPrintHandler ,如以下代码示例所示:

browser.RequestPrintHandler =
    new Handler<RequestPrintParameters, RequestPrintResponse>(p =>
    {
        return RequestPrintResponse.Print();
    });
browser.RequestPrintHandler = 
    New Handler(Of RequestPrintParameters, RequestPrintResponse)(Function(p)
        Return RequestPrintResponse.Print()
    End Function)

当 Chromium 被告知以编程方式执行打印时,它将使用 PrintHtmlContentHandlerPrintPdfContentHandler 来确定应如何打印内容。

将被调用的处理程序取决于当前加载到浏览器中的内容 - 对于常规网页将使用 PrintHtmlContentHandler,而对于打印 PDF 文件将使用 PrintPdfContentHandler

选择打印机

PrintHtmlContentHandlerPrintPdfContentHandler 的参数包含 Printers 属性 - 一组当前可用于打印的打印机。 例如,以下是如何在 PrintHtmlContentHandler 实现中获取您所需的打印机:

browser.PrintHtmlContentHandler 
    = new Handler<PrintHtmlContentParameters, PrintHtmlContentResponse>(p =>
    {
        // 获取可用打印机的集合。
        var printers = p.Printers;
        // 获取环境中的默认打印机。
        var defaultPrinter = printers.Default;
    
        // 获取内置 PDF 打印机。
        var pdfPrinter = printers.Pdf;
    
        // 通过设备名称查找打印机。
        var xpsPrinter = printers.FirstOrDefault(pr => pr.DeviceName.Contains("XPS"));
    
        // 使用特定打印机打印内容。
        return PrintHtmlContentResponse.Print(xpsPrinter);
    });
browser.PrintHtmlContentHandler = 
    New Handler(Of PrintHtmlContentParameters, PrintHtmlContentResponse)(Function(p)
        ' 获取可用打印机的集合。
        Dim printers = p.Printers

        ' 获取环境中的默认打印机。
        Dim defaultPrinter = printers.Default

        ' 获取内置 PDF 打印机。
        Dim pdfPrinter = printers.Pdf

        ' 通过设备名称查找打印机。
        Dim xpsPrinter = 
            printers.FirstOrDefault(Function(pr) pr.DeviceName.Contains("XPS"))

        ' 使用特定打印机打印内容。
        Return PrintHtmlContentResponse.Print(xpsPrinter)
    End Function)

处理程序中的 Print() 响应用于指定使用哪台打印机进行打印。

每台打印机都有自己的功能,包括特定打印机支持的纸张大小、颜色模式和双面模式。 例如,以下是检查打印机是否支持 A4 的方法:

bool a4Supported = xpsPrinter.Capabilities.PaperSizes.Contains(PaperSize.IsoA4);
Dim a4Supported As Boolean = xpsPrinter.Capabilities.PaperSizes.Contains(PaperSize.IsoA4)

配置打印设置

每台打印机都包含一个表示当前打印操作的 PrintJob。 特定打印操作的打印设置可作为打印作业的一部分使用。 下面介绍如何自定义和应用打印设置:

pdfPrinter.PrintJob.Settings.Apply((s) =>
{
    s.Orientation = Orientation.Landscape;
    s.PageRanges = new[] { new PageRange(2, 5) };
    s.PaperSize = PaperSize.IsoA4;
    s.PdfFilePath = pdfFilePath;
    // 其他设置。
});
pdfPrinter.PrintJob.Settings.Apply(Sub(s)
    s.Orientation = Orientation.Landscape
    s.PageRanges = { New PageRange(2, 5) }
    s.PaperSize = PaperSize.IsoA4
    s.PdfFilePath = pdfFilePath
    ' 其他设置。
End Sub)

在应用打印设置期间,进行页面布局,并重新生成稍后将发送到打印机的打印预览文档。 因此,Apply() 调用可能需要一些时间来执行。

如果处理程序实现应用的设置与打印机功能不匹配,则会抛出异常。

在使用内置 PDF 打印机打印时需要通过 PdfFilePath 指定完全限定的路径。 如果未设置路径,则打印操作将被取消。

PageCountUpdated 事件

页面布局完成后,将触发 PageCountUpdated 事件,从而提供生成的页数。 以下是如何为特定打印机订阅此事件的方法:

printer.PrintJob.PageCountUpdated += (s, e) => 
{
    int newPageCount = e.PageCount;
};
AddHandler printer.PrintJob.PageCountUpdated, Sub(s, e)
    Dim newPageCount As Integer = e.PageCount
End Sub

PrintCompleted 事件

通过 PrintHtmlContentResponse.Print()PrintPdfContentResponse.Print() 选择要打印的打印机后,一旦打印操作完成,就会为其打印作业触发 PrintCompleted 事件。 以下是订阅此事件的方法:

printer.PrintJob.PrintCompleted += (s, e) => 
{
    var printJob = e.PrintJob;
    bool completed = e.IsCompletedSuccessfully;
};
AddHandler printer.PrintJob.PrintCompleted, Sub(s, e)
    Dim printJob = e.PrintJob
    Dim completed As Boolean = e.IsCompletedSuccessfully
End Sub

以编程方式将网页打印为 PDF

以下代码片段演示了以编程方式将网页打印为 PDF 的一般方法:

// 将浏览器调整为所需的尺寸。
browser.Size = new Size(1024, 768);

// 加载所需的网页,并等待直至加载完成。
Console.WriteLine($"Loading {url}");
browser.Navigation.LoadUrl(url).Wait();


// 配置打印处理程序。
browser.RequestPrintHandler =
    new Handler<RequestPrintParameters, RequestPrintResponse
    >(p => RequestPrintResponse.Print());

TaskCompletionSource<string> printCompletedTcs =
    new TaskCompletionSource<string>();
browser.PrintHtmlContentHandler
    = new Handler<PrintHtmlContentParameters, PrintHtmlContentResponse
    >(p =>
    {
        try
        {
            // 获取内置 PDF 打印机的打印作业。
            PdfPrinter<PdfPrinter.IHtmlSettings> pdfPrinter =
                p.Printers.Pdf;
            IPrintJob<PdfPrinter.IHtmlSettings> printJob =
                pdfPrinter.PrintJob;

            // 应用必要的打印设置。
            printJob.Settings.Apply(s =>
            {
                IReadOnlyCollection<PaperSize> paperSizes =
                    pdfPrinter.Capabilities.PaperSizes;
                s.PaperSize =
                    paperSizes.First(size => size.Name.Contains("A4"));

                s.PrintingHeaderFooterEnabled = true;
                // 指定保存结果的路径。
                s.PdfFilePath = pdfFilePath;
            });

            string browserUrl = p.Browser.Url;
            printJob.PrintCompleted += (sender, args) =>
            {
                // 在打印完成时设置任务结果。
                printCompletedTcs.TrySetResult(browserUrl);
            };

            // 告诉 Chromium 使用内置的 PDF 打印机
            // 打印。
            return PrintHtmlContentResponse.Print(pdfPrinter);
        }
        catch (Exception e)
        {
            printCompletedTcs.TrySetException(e);
            throw;
        }
    });

// 开始打印并等待打印完成。
Console.WriteLine("URL loaded. Initiate printing");
browser.MainFrame.Print();
string printedUrl = printCompletedTcs.Task.Result;
Console.WriteLine($"Printing completed for the URL: {printedUrl}");
' 将浏览器调整为所需的尺寸。
browser.Size = New Size(1024, 768)

' 加载所需网页,等待直至加载完成。
Console.WriteLine($"Loading {url}")
browser.Navigation.LoadUrl(url).Wait()

' 配置打印处理程序。
browser.RequestPrintHandler =
    New Handler(Of RequestPrintParameters, RequestPrintResponse )(
        Function(p) RequestPrintResponse.Print())

Dim printCompletedTcs As New TaskCompletionSource(Of String)()
browser.PrintHtmlContentHandler =
    New Handler(Of PrintHtmlContentParameters, PrintHtmlContentResponse )(
        Function(p)
            Try
                ' 获取内置 PDF 打印机的打印作业。
                Dim pdfPrinter As PdfPrinter(Of PdfPrinter.IHtmlSettings) =
                        p.Printers.Pdf
                Dim printJob As IPrintJob(Of PdfPrinter.IHtmlSettings) =
                        pdfPrinter.PrintJob

                ' 应用必要的打印设置。
                printJob.Settings.Apply(Sub(s)
                    Dim paperSizes As IReadOnlyCollection(Of PaperSize) =
                            pdfPrinter.Capabilities.PaperSizes
                    s.PaperSize = 
                        paperSizes.First(
                            Function(size) size.Name.Contains("A4"))

                    s.PrintingHeaderFooterEnabled = True
                    ' 指定保存结果的路径。
                    s.PdfFilePath = pdfFilePath
                End Sub)

                Dim browserUrl As String = p.Browser.Url
                AddHandler printJob.PrintCompleted, Sub(sender, args)
                    ' 在打印完成时设置打印任务。
                    printCompletedTcs.TrySetResult(browserUrl)
                End Sub

                ' 告诉 Chromium 使用内置的 PDF 打印机
                ' 打印。
                Return PrintHtmlContentResponse.Print(pdfPrinter)
            Catch e As Exception
                printCompletedTcs.TrySetException(e)
                Throw
            End Try
        End Function)

' 开始打印并等待打印完成。
Console.WriteLine("URL loaded. Initiate printing")
browser.MainFrame.Print()
Dim printedUrl As String = printCompletedTcs.Task.Result
Console.WriteLine($"Printing completed for the URL: {printedUrl}")
Go Top