在 Java 中将 HTML 转换为 PDF 可能是一个挑战。

进行这种转换时,首先需要正确渲染 HTML,然后再将其转换为 PDF。虽然这听起来很简单,但 HTML 渲染本身是一个非常复杂的任务。

幸运的是,像 Flying Saucer 这样的流行库不仅可以较好地渲染 HTML,还能从中创建 PDF 文件。然而,这些库都有一个共同的缺陷,那就是它们无法跟上最新的网络标准。

如果您需要使用 CSS3、WebGL 或其他现代技术,这些库可能不适合您。此外,它们也无法执行 JavaScript。

在本文中,我们将探讨如何在 Java 中将 HTML 转换为 PDF,并能够使用最新的网络标准。

解决问题的方法 

我们建议使用 JxBrowser 来渲染网页并将其转换为 PDF。

JxBrowser 是一个用于 Java 应用程序的集成 Browser Engine。它基于 Chromium,因此可以像 Google Chrome 一样准确地渲染任何页面。它还为开发者提供了 API,以使用 Chromium 的许多功能。其中之一就是将网页转换为 PDF。

使用 JxBrowser,转换过程分为两个步骤:

  • 加载页面。
  • 将页面打印为 PDF。

让我们看看代码中是如何实现的。

HTML 转换为 PDF 的代码示例 

以下代码示例演示了如何在一个方法中加载页面、配置打印,并将 HTML 打印为 PDF:

private static void convert(Path htmlFile, Path pdfFile) {
    var whenCompleted = new CompletableFuture<Void>();

    // 创建一个 Browser Engine。
    try (var engine = Engine.newInstance(HARDWARE_ACCELERATED)) {
        var browser = engine.newBrowser();

        // 告诉 Engine 从代码配置打印,而不是显示打印预览对话框。
        browser.set(PrintCallback.class, (params, action) -> action.print());
        
        // 配置打印。
        browser.set(PrintHtmlCallback.class, (params, action) -> {
            var printer = params.printers().pdfPrinter();
            var job = printer.printJob();
            job.settings()
               .paperSize(ISO_A4)
               .pageMargins(none()) // 边缘没有空白。
               .pdfFilePath(pdfFile) // 结果文件的位置。
               .disablePrintingHeaderFooter() // 页面上没有其他信息。
               .apply();
            job.on(PrintCompleted.class, event -> whenCompleted.complete(null));
            action.proceed(printer);
        });

        // 在浏览器中加载文件。这可以是任何 URL。
        browser.navigation().loadUrlAndWait(htmlFile.toString());

        // 页面加载完成后,打印网页。
        browser.mainFrame().ifPresent(Frame::print);

        // 等待 PDF 文件创建完成。
        whenCompleted.join();
    }
}

生成的方法非常易于使用:

convert(Paths.get("/path/to/file.html"), Paths.get("/path/to/file.pdf"));

使用 JxBrowser 将 HTML 转换为 PDF

使用 JxBrowser 将 HTML 转换为 PDF

Spinner

发送中。。。

抱歉,发送中断

请再次尝试,如果问题仍然存在,请联系我们 info@teamdev.com.

阅读并同意条款以继续。

您的个人 JxBrowser 试用密钥和快速入门指南将在几分钟内发送至您的电子邮箱。

实用建议 

上述示例适用于偶尔将 HTML 转换为 PDF 的应用程序。对于频繁且大批量地将 HTML 转换为 PDF 的应用程序,请参见本节中的提示。

1. 重复使用 Engine 实例。创建和关闭 Engine 的成本很高,因为它会启动和停止 Main Chromium 进程。我们建议创建一次 Engine 并重复使用它。

2. 使用 Profiles 实现隔离。可能需要在浏览器中加载每个页面,使其不受以前加载的页面留下的陈旧缓存和数据的影响。为每次转换创建一个新的 Profile,以便在空白的隔离环境中打开页面。

以下是示例:

public final class HtmlToPdf {

    private static Engine engine;

    private static void convert(Path htmlFile, Path pdfFile) {
        ...
        if (engine == null) {
            // 仅创建一次 Browser Engine。
            engine = Engine.newInstance(HARDWARE_ACCELERATED);
        }
        var profile = engine.profiles().newIncognitoProfile("临时 profile 名称");
        var browser = profile.newBrowser();
        ...
    }
}

3. 阅读我们的文章《如何在 Docker 中部署 JxBrowser》。在云环境中使用 JxBrowser 时,可能会很有用。

结论 

本文详细展示了如何在 Java 环境中利用 JxBrowser 高效地将 HTML 内容转换为 PDF 文件。

我们之所以推荐 JxBrowser,是因为它具备卓越的能力来渲染采用最新网络技术的 HTML 页面,并顺利执行 JavaScript 代码,这是众多同类库中难以匹敌的优势。

要了解更多关于 JxBrowser 的强大功能和应用场景,欢迎访问产品页面