效果图:
先看效果图,以下是基于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