List icon 目录

打印

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

概述

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

  1. 使用 window.print() JavaScript 函数。可以从网页上的 JavaScript 代码调用此函数。
  2. 使用 JxBrowser API 的 Frame.print() 方法。该方法请求打印 Frame。如果需要打印整页,应该在主 Frame 中调用 print() 方法。例如:

     browser.mainFrame().ifPresent(Frame::print);
    
     browser.mainFrame().ifPresent(Frame::print)
    

网页不会立即打印出来。PrintCallback 将被调用以告诉 Browser 如何处理打印请求。默认情况下,所有打印请求都会被取消。

打印预览

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

browser.set(PrintCallback.class, (params, tell) -> tell.showPrintPreview());
browser.set(PrintCallback::class.java, PrintCallback { params, tell -> tell.showPrintPreview() }

在“打印预览”对话框中,您可以选择首选打印选项:

Print Preview

配置设置

使用以下代码告诉 Browser 继续打印:

browser.set(PrintCallback.class, (params, tell) -> tell.print());
browser.set(PrintCallback::class.java, PrintCallback { params, tell -> tell.print() }

之后,将调用 PrintHtmlCallbackPrintPdfCallback 以允许您配置打印设置。这些回调对应于 Browser 中当前加载的内容类型。对于 HTML 内容,将调用 PrintHtmlCallback,对于 PDF 内容,将调用 PrintPdfCallback

现在,我们来看看如何使用这些回调函数。

步骤 1:选择打印机

首先,您需要选择要使用的打印机。打印机有两种类型:PdfPrinterSystemPrinterPdfPrinter 相当于打印预览对话框中的 Save as PDF 选项。SystemPrinter 类型代表系统中安装的打印机,它可以是虚拟的也可以是物理的。回调参数会提供一个可用打印机的列表。您可以检索 PdfPrinter、默认系统打印机,或从系统打印机中选择一个打印机:

browser.set(PrintHtmlCallback.class, (params, tell) -> {
    // PDF 打印机始终可用。
    PdfPrinter<PdfPrinter.HtmlSettings> pdfPrinter = params.printers().pdfPrinter();

    // 默认打印机是可选的。
    SystemPrinter<SystemPrinter.HtmlSettings> defaultPrinter =
        params.printers()
              .defaultPrinter()
              .orElseThrow(
                  () -> new IllegalStateException("未找到默认打印机。"));

    // 按名称查找系统打印机。
    SystemPrinter<SystemPrinter.HtmlSettings> systemPrinter =
        params.printers()
              .list()
              .stream()
              .filter(printer -> printer.deviceName()
                                        .equals("Microsoft XPS Document Writer"))
              .findFirst()
              .orElseThrow( () -> new IllegalStateException("未找到打印机。"));
});
browser.set(PrintHtmlCallback::class.java, PrintHtmlCallback { params, tell ->
    // PDF 打印机始终可用。
    val pdfPrinter = params.printers().pdfPrinter()

    // 默认打印机是可选的。
    val defaultPrinter = params.printers()
        .defaultPrinter()
        .orElseThrow { IllegalStateException("未找到默认打印机。") }

    // 按名称查找系统打印机。
    val systemPrinter = params.printers()
        .list()
        .firstOrNull { it.deviceName() == "Microsoft XPS Document Writer" }
        ?: throw IllegalStateException("未找到打印机。")
})

步骤 2:配置设置

每台打印机都通过 PrintSettings 类型进行参数化,该类型定义了当前上下文中打印机可用的打印设置。每台打印机都包含一个表示当前打印操作的 PrintJob。打印设置应用于打印作业:

SystemPrinter<HtmlSettings> printer = params.printers()
        .defaultPrinter()
        .orElseThrow(IllegalStateException::new);
PrintJob<HtmlSettings> printJob = printer.printJob();
printJob.settings()
        .header("<span style='font-size: 12px;'>Page header:</span>"
                + "<span class='title'></span>")
        .footer("<span style='font-size: 12px;'>Page footer:</span>"
                + "<span class='pageNumber'></span>")
        .paperSize(ISO_A4)
        .colorModel(COLOR)
        .enablePrintingBackgrounds()
        .disablePrintingHeaderFooter()
        .orientation(PORTRAIT)
        .apply();
val printer = params.printers() 
    .defaultPrinter()
    .orElseThrow { IllegalStateException() }
val printJob = printer.printJob()
printJob.settings()
    .header("<span style='font-size: 12px;'>Page header:</span>"
            + "<span class='title'></span>")
    .footer("<span style='font-size: 12px;'>Page footer:</span>"
            + "<span class='pageNumber'></span>")
    .paperSize(ISO_A4)
    .colorModel(COLOR)
    .enablePrintingBackgrounds()
    .disablePrintingHeaderFooter()
    .orientation(PORTRAIT)
    .apply()

调用 apply() 方法将应用配置的设置并重新生成将发送给打印机的打印预览文档。在告诉 Browser 开始在打印机上打印之前,您可以订阅 PrintCompleted 事件以便在打印完成后收到通知:

printJob.on(PrintCompleted.class, event -> {
    if (event.isSuccess()) {
        System.out.println("打印已成功完成。");
    } else {
        System.out.println("打印失败。");
    }
});
printJob.on(PrintCompleted::class.java) { event ->
    if (event.isSuccess()) {
       println("打印已成功完成。")
    } else {
       println("打印失败。")
    }
}

步骤 3:开始打印

现在我们已经准备好开始打印了:

tell.proceed(printer);
tell.proceed(printer)

以下是完整的代码片段:

browser.set(PrintHtmlCallback.class, (params, tell) -> {
    SystemPrinter<HtmlSettings> printer = params.printers()
            .defaultPrinter()
            .orElseThrow(IllegalStateException::new);
    PrintJob<HtmlSettings> printJob = printer.printJob();
    printJob.settings()
            .header("<span style='font-size: 12px;'>Page header:</span>"
                    + "<span class='title'></span>")
            .footer("<span style='font-size: 12px;'>Page footer:</span>"
                    + "<span class='pageNumber'></span>")
            .paperSize(ISO_A4)
            .colorModel(COLOR)
            .enablePrintingBackgrounds()
            .disablePrintingHeaderFooter()
            .orientation(PORTRAIT)
            .apply();
    printJob.on(PrintCompleted.class, event -> {
        if (event.isSuccess()) {
            System.out.println("打印已成功完成。");
        } else {
            System.out.println("打印失败。");
        }
    });
    tell.proceed(printer);
});
browser.set(PrintHtmlCallback::class.java, PrintHtmlCallback { params, tell ->
    val printer = params.printers()
       .defaultPrinter()
       .orElseThrow { IllegalStateException() }
    val printJob = printer.printJob()
    printJob.settings()
       .header("<span style='font-size: 12px;'>Page header:</span>"
               + "<span class='title'></span>")
       .footer("<span style='font-size: 12px;'>Page footer:</span>"
               + "<span class='pageNumber'></span>")
       .paperSize(ISO_A4)
       .colorModel(COLOR)
       .enablePrintingBackgrounds()
       .disablePrintingHeaderFooter()
       .orientation(PORTRAIT)
       .apply()
    printJob.on(PrintCompleted::class.java) { event ->
        if (event.isSuccess()) {
            println("打印已成功完成。")
        } else {
            println("打印失败。")
        }
    }
    tell.proceed(printer)
})

PdfPrinter 上打印也是一样,只是您需要指定目标 PDF 文件的路径:

browser.set(PrintHtmlCallback.class, (params, tell) -> {
    PdfPrinter<HtmlSettings> printer = params.printers().pdfPrinter();
    PrintJob<HtmlSettings> printJob = printer.printJob();
    printJob.settings()
            .paperSize(ISO_A4)
            .enablePrintingBackgrounds()
            .pdfFilePath(Paths.get("<path-to-pdf-file>"))
            .apply();
    printJob.on(PrintCompleted.class, event -> {
        if (event.isSuccess()) {
            System.out.println("打印已成功完成。");
        } else {
            System.out.println("打印失败。");
        }
    });
    tell.proceed(printer);
});
browser.set(PrintHtmlCallback::class.java, PrintHtmlCallback { params, tell ->
    val printer = params.printers().pdfPrinter()
    val printJob = printer.printJob()
    printJob.settings()
       .paperSize(ISO_A4)
       .enablePrintingBackgrounds()
       .pdfFilePath(Path("<path-to-pdf-file>"))
       .apply()
    printJob.on(PrintCompleted::class.java) { event ->
        if (event.isSuccess()) {
            println("打印已成功完成。")
        } else {
            println("打印失败。")
        }
    }
    tell.proceed(printer)
})

PrintPdfCallback 具有相同的接口,唯一的区别在于可以应用于打印作业的打印设置。

取消打印

要取消打印,请使用以下方法:

browser.set(PrintCallback.class, (params, tell) -> tell.cancel());
browser.set(PrintCallback::class.java, PrintCallback { params, tell -> tell.cancel() }
Go Top