打印

本指南展示了如何使用 Printing API。

概述

可以使用以下方式打印网页:

  1. window.print() JavaScript 函数。 它可以从网页上的 JavaScript 代码中调用。
  2. DotNetBrowser API 的 IFrame.Print() 方法。 它请求打印框架。 如果需要打印整页,调用主框架中的 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。 在对话框中,您需要单击目标部分中的“更改…”按钮,然后选择“另存为 PDF”。 按下保存按钮后,网页将被保存。

打印预览事件

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

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 将用于常规网页,而 PrintPdfContentHandler 将用于打印 PDF 文件。

选择打印机

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