You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Playwright将Thymeleaf生成的HTML本地转为PDF(替代wkhtmltopdf)

问题描述

我有一个Spring Boot应用,原本使用已废弃的wkhtmltopdf工具,将Thymeleaf模板引擎运行时生成的HTML转换为PDF,原实现代码如下:

String html = templateEngine.process("template.html", webCtx); // 从模板引擎生成HTML内容
Pdf pdf = new Pdf(wrapperConfig);
pdf.addPageFromString(html); // 将HTML模板传入解析器
byte[] result = pdf.getPDF(); // 解析HTML并返回PDF

目前该库已废弃,计划用Playwright替代,但Playwright常规用法是访问URL生成PDF,无法直接传入HTML字符串,常规实现如下:

try(Playwright playwright = Playwright.create()) {
    Browser browser = playwright.chromium().launch();
    Page page = browser.newPage();
    var url = "/some/website";
    page.navigate(url); // 访问网页
    page.emulateMedia(new Page.EmulateMediaOptions().setMedia(Media.SCREEN));
    result = page.pdf(); // 解析网页并返回PDF
}

我希望让Playwright直接解析Thymeleaf生成的HTML并渲染为PDF,不想通过Web Controller暴露URL(需处理认证,过于繁琐),请问有没有更简便的方案?比如将HTML临时存储到文件系统后让Playwright访问?

解决方案

推荐以下两种更简便的方案:

1. 直接传入HTML字符串(最优方案)

Playwright的Page对象提供了setContent()方法,可以直接传入HTML字符串进行渲染,无需依赖外部URL或文件。修改后的代码如下:

try(Playwright playwright = Playwright.create()) {
    Browser browser = playwright.chromium().launch();
    Page page = browser.newPage();
    
    // 直接传入Thymeleaf生成的HTML字符串
    page.setContent(html);
    
    page.emulateMedia(new Page.EmulateMediaOptions().setMedia(Media.SCREEN));
    byte[] result = page.pdf(); // 生成PDF
}

这种方式完全不需要额外的文件或Web服务,直接复用模板引擎生成的HTML,是最简洁高效的方案。

2. 写入临时本地文件后访问(备选方案)

如果你的HTML依赖本地静态资源(如CSS、图片),直接传入字符串可能无法正确加载资源,可以将HTML写入临时文件,再通过file://协议让Playwright访问:

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

// ...

try(Playwright playwright = Playwright.create()) {
    Browser browser = playwright.chromium().launch();
    Page page = browser.newPage();
    
    // 创建临时HTML文件
    File tempHtmlFile = File.createTempFile("template-", ".html");
    Files.write(tempHtmlFile.toPath(), html.getBytes(StandardCharsets.UTF_8));
    
    // 通过file协议访问临时文件
    page.navigate("file://" + tempHtmlFile.getAbsolutePath());
    
    page.emulateMedia(new Page.EmulateMediaOptions().setMedia(Media.SCREEN));
    byte[] result = page.pdf();
    
    // 自动清理临时文件
    tempHtmlFile.deleteOnExit();
}

注意如果HTML中有相对路径的静态资源,需要确保这些资源的路径相对于临时文件的位置正确,或者将资源内容内联到HTML中(如Base64图片、内嵌CSS)。

内容的提问来源于stack exchange,提问作者Theiaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 05:10:19