效果图:
先看效果图,以下是基于freemarker模板渲染数据,puppeteer加载html中的js及最后图片生成:
背景:
目前为止,后台java根据html模板或者一个网页路径生成图片,都不支持flex布局及最新的css3属性,这其中的库、插件包括:html2image、cssbox、core-renderer、wkhtmltox、Flying Saucer、node插件phantom 等等,浏览器标签页打开好几十个了????????????很多插件库已经不记得了。经过粗略测试,对flex布局都不支持!
freemarker模板集成及实现:
因为是测试,所以后台模板页面只写了几个css3属性
1、springboot集成freemarker
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2、freemarker配置项
# application.yml
spring:
freemarker:
cache: false
# 字符集
charset: UTF-8
# 检查模板位置
check-template-location: true
# 模板内容类型
content-type: text/html
expose-request-attributes: true
expose-session-attributes: true
request-context-attribute: request
# 模板位置
template-loader-path: classpath:/templates/
# 必须要加 后缀,要不找不到接口
suffix: .ftl
3、编写模板 f01.ftl
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>freemarker模板</title>
<#-- 引入条形码库JsBarcode -->
<script src="https://cdn.jsdelivr.net/npm/jsbarcode@3.11.5/dist/JsBarcode.all.min.js"></script>
</head>
<body style="font-size: 20px;">
<div style="display: flex;
align-items: flex-start;
border: 1px solid darkred;
box-shadow: 1px 2px 1px 5px #cccccc;"
>
<div style="display:flex;flex-shrink: 0;width:100px;">渲染文字:</div> <h1>${msg}</h1>
</div>
<div style="display: flex;align-items: center;margin: 10px 0px;">
<div>渲染图片: </div><img style="width: 150px;height: 150px;" src="${img}" />
</div>
<#--条形码-->
<#--<div style="display: flex;align-items: flex-end;">-->
渲染条形码: <svg id="barcode"></svg>
<#--</div>-->
</body>
<#--用浏览器访问,可以加载js-->
<script>
let e = document.getElementById("barcode");
JsBarcode(e, "Hi world!");
</script>
</html>
4、创建接口
之所以创建一个接口,因为测试的时候我是通过接口方式,返回了一个html页面,在使用 puppeteer 生成图片时,可以指定一个网页或者html代码都可以。
@Slf4j
@Controller
public class Test2 {
@RequestMapping(value = "/ftest")
public String test(Model model) {
model.addAttribute("msg", "freemarker模板引擎结合node puppeteer库实现html生成图片,划重点:【支持flex布局等所有的css3属性!!!】");
model.addAttribute("img", "https://img1.baidu.com/it/u=3764156347,3722190225&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=419");
return "f01";
}
}
5、网页测试
我们先在网页上调用接口测试下,看接口、页面是否正常,以下是网页展示的效果。
node puppeteer库下载、实现最终html转图片:
1、下载puppeteer时,可能会有点慢,取决于网络。
// 我下载的是22.1.0,最新版本下载的时候报错了,可能是node版本问题
// 电脑node版本为19.0.0
npm i puppeteer@22.1.0
// 或
yarn add puppeteer@22.1.0
2、使用puppeteer
page.evaluate() 方法会执行网页或者html中的js代码,这块很关键!上边我们在模板中引入的条形码生成插件,条形码是需要执行js来生成,所以必须且只能在page.evaluate() 方法中执行html中的js代码。其他的没啥说的,注释写的很清楚。
// index.js
const puppeteer = require('puppeteer');
async function test () {
// 启动浏览器
const browser = await puppeteer.launch();
// 创建一个新页面
const page = await browser.newPage();
// 下边设置视口的长宽
await page.setViewport({
width: 960,
height: 760,
deviceScaleFactor: 1,
});
// todo 1 可以加载一段html代码
// await page.setContent(imgHTML);
// todo 2 也可以访问一个网址(下边这个网址是本地springboot后台接口,会返回一个html页面)
await page.goto('http://localhost:8001/ftest');
// 执行您自己的代码
await page.evaluate(() => {
let e = document.getElementById("barcode");
JsBarcode(e, "Hi world!");
});
// 截取网页的屏幕截图
await page.screenshot({path: "./example.png"});
// 关闭浏览器
await browser.close();
}
test()
3、执行index.js,图片生成测试,效果还是比较理想的,flex布局及条形码都会展示出来:
总结:
1、主要是 puppeteer这个库来完成的图片生成,至于html或者网页如何获取,还是要根据业务场景来。
2、puppeteer文档地址如下:
Puppeteer | Puppeteer