需求:后台代码批量生成图片,图片中的title和二维码,需要动态变化。
解决思路:
1.使用FreeMaker模板index.ftl渲染动态数据(title和二维码链接作为动态入参)
2.添加动态数据的模板代码通过xhtmlrenderer转换成图片
3.上传图片至图片服务器,获取图片url
拆分实现步骤:
1.使用FreeMaker模板index.ftl渲染动态数据(title和二维码链接作为动态入参)
1.1 引入FreeMaker依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
1.2 准备模板代码 index.ftl
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8"></meta>
<title>海报</title>
<style>
* {
margin: 0;
padding: 0;
}
.certificate {
position: relative;
display: inline-block;
width: 750px;
height: 1288px;
background-repeat: no-repeat;
background-position: center;
background-size: 750px 1288px;
text-align: center;
}
.title {
position: absolute;
display: inline-block;
width: 578px;
margin: 0 86px;
font-size: 34px;
font-weight: 500;
color: #E66C6C;
font-family: simsun;
line-height: 48px;
top: 410px;
padding-bottom: 14px;
border-bottom: 2px solid #E66C6C;
text-align: center;
}
.qr_code {
position: absolute;
width: 228px;
height: 228px;
background-color: #fff;
top: 964px;
left: 260px;
}
img {
display: inline-block;
width: 228px;
height: 228px;
}
</style>
</head>
<body>
<div class="certificate" style="background-image: url(${bg})">
<div class="title" style="word-break: break-all!important; word-wrap: break-word!important;">
《${title?html}》
</div>
<div class="qr_code">
<img src="${qrCode}" alt=""></img>
</div>
</div>
</body>
</html>
1.3 FreemarkerUtils加载index.ftl模板,渲染数据
public class FreemarkerUtils {
public static String getTemplate(String template, Map<String, Object> map) throws IOException, TemplateException {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_25);
cfg.setTemplateLoader(new ClassTemplateLoader(
FreemarkerUtils.class.getClass().getClassLoader(), "/templates/static"));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
Template temp = cfg.getTemplate(template, "UTF-8");
StringWriter stringWriter = new StringWriter();
temp.process(map, stringWriter);
stringWriter.flush();
stringWriter.close();
String resutl = stringWriter.getBuffer().toString();
return resutl;
}
}
2.添加动态数据的模板代码通过xhtmlrenderer转换成图片
2.1 引入xhtmlrenderer依赖
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
注意xhtmlrenderer中央仓库为:
<repository>
<id>mvnrepository</id>
<name>mvnrepository</name>
<url>https://mvnrepository</url>
</repository>
2.2 xhtmlrenderer生成图片
public String turnImage(String template, Map<String, Object> map) throws Exception {
String html = FreemarkerUtils.getTemplate(template, map);
byte[] bytes = html.getBytes("UTF-8");
ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(bin);
//加载自定义字体,解决生成图片title处汉字展示不正常问题
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("font/simsun.ttf");
Font font = Font.createFont(TRUETYPE_FONT, inputStream);
AWTFontResolver awtFontResolver = new AWTFontResolver();
awtFontResolver.setFontMapping("simsun", font);
Java2DRenderer renderer = new Java2DRenderer(document, 750, 1286);
renderer.getSharedContext().setFontResolver(awtFontResolver);
BufferedImage img = renderer.getImage();
// 转成流上传至服务器
ByteArrayOutputStream dataOutputStream = new ByteArrayOutputStream();
ImageIO.write(img, "png", dataOutputStream);
byte[] bts = dataOutputStream.toByteArray();
String imgUrl = uploadPic(bts);
return imgUrl;
}
2.3 加载自定义字体,解决生成图片title处汉字展示不正常问题
由于Java2DRenderer类中定义的字体对于汉字处理不友好,生成的图片title会显示如下图:
解决方法:
1.引入第三方字体
2.代码中自定义字体解析器
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("font/simsun.ttf");
Font font = Font.createFont(TRUETYPE_FONT, inputStream);
AWTFontResolver awtFontResolver = new AWTFontResolver();
awtFontResolver.setFontMapping("simsun", font);
3.测试代码
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
map.put("title", "标题");
map.put("bg", "https://xxx/2021-07-22/ed91af576f3947d6ba60dcabfc3ca122.png");
map.put("qrCode", "https://xxx/2021-07-22/ed91af576f3947d6ba60dcabfc3ca122.png");
String url = turnImage("index.ftl", map);
}
更多推荐
java 将html页面转成图片
发布评论