#### Java根据内容生成图片
文章来源于 星星点灯
序言: 这两天接到一个需求,某种特定的客户类型需要根据上游系统传过来的参数生成一份图片文件,并把这个图片文件送给某对接系统。这个需求要是放在前端一看可能确实比较好处理了,但是对于一个半残废的后端来说,是有点新鲜哈。(这并不可以拒绝需求的理由,做不出来就是菜,不要解释) 经过我的一番思量,脑海中浮现了两种办法
* 利用java原生的画图(太low了,而且代码巨复杂) * 利用上游报文生成一份html文件,然后将html文件转换成图片文件(疯狂查询资料,可行,需要使用freemarker来动态填充数据)
先看下失效效果图吧 (自己YY了一个简单的简历生成器)
报文:
Resume(name=王二狗, age=30, education=[Education(schoolName=家里蹲大学, beginDate=2000-01-01, finishDate=2005-01-01, level=本科), Education(schoolName=牢里蹲大学, beginDate=2005-01-01, finishDate=2010-01-01, level=研究生)])生成后的图片文件:
文件:
**于是我就有了下面的实现方式。**
项目结构示意图
源码地址:本功能源码地址
1、需要引入的依赖
<dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>core-renderer</artifactId> <version>R8</version> </dependency> <dependency> <groupId>com.github.xuwei-k</groupId> <artifactId>html2image</artifactId> <version>0.1.0</version> </dependency> <!-- freemarker模板引擎--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>2、新增freemarker相关配置
spring.freemarker.cache = false spring.freemarker.charset = UTF-8 spring.freemarker.check-template-location = true spring.freemarker.expose-request-attributes = true spring.freemarker.request-context-attribute = request spring.freemarker.content-type = text/html spring.freemarker.content-template-loader-path = classpath:/templates3、新建freemarker模板文件
<html> <head> <style> </style> </head> <body> <div> <h4>韭菜信息</h4> <p>姓名:${resume.name!""}</p> <p>年龄:${resume.age!""}</p> <h4>--</h4> </div> <div style="text-align:center;"> <table border="1" style="margin: auto;" width='60%' > <tr><th>学校</th><th>进修时间</th><th>学校类别</th></tr> <#list resume.education as item> <tr><td>${item.schoolName}</td><td>$${item.beginDate!""}至${item.finishDate!""}</td><td>${item.level}</td></tr> </#list> </table> </div> </body> </html>4、Freemarker工具类
package com.workshare.workshare.common; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.xhtmlrenderer.swing.Java2DRenderer; import org.xhtmlrenderer.util.FSImageWriter; import java.awt.image.BufferedImage; import java.io.*; import java.util.Map; /** * hutinga */ @Slf4j public class FreemarkeTools { /** * 获取模板转为html */ public static String ftlToString(Map<String,Object> map, String templateName) throws IOException, TemplateException { String value = ""; Configuration configuration = new Configuration(); Resource resource = new ClassPathResource("templates"); File sourceFile = resource.getFile(); String ftlPath = sourceFile.getAbsolutePath(); String filName = templateName; String encoding = "UTF-8"; StringWriter out = new StringWriter(); configuration.setDirectoryForTemplateLoading(new File(ftlPath)); Template template = configuration.getTemplate(filName,encoding); template.setEncoding(encoding); template.process(map, out); out.flush(); out.close(); value = out.getBuffer().toString(); return value; } /** * html转为图片 * @param html * @param inputFileName * @param outputFileName * @param widthImage * @param heightImage * @return * @throws IOException */ public static String turnImage(String html, String inputFileName, String outputFileName ,int widthImage, int heightImage) throws IOException { BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(inputFileName),"UTF-8")); bufferedWriter.write(html); bufferedWriter.newLine(); bufferedWriter.flush(); bufferedWriter.close(); File f = new File(inputFileName); Java2DRenderer renderer = new Java2DRenderer(f, widthImage, heightImage); BufferedImage image = renderer.getImage(); FSImageWriter imageWriter = new FSImageWriter(); imageWriter.setWriteCompressionQuality(0.9f); File imgFile = new File(outputFileName); FileOutputStream fout = new FileOutputStream(imgFile); imageWriter.write(image, fout); fout.close(); return outputFileName; } }5、单元测试生成文件
package com.workshare.workshare; import com.workshare.workshare.common.FreemarkeTools; import com.workshare.workshare.dto.Education; import com.workshare.workshare.dto.Resume; import freemarker.template.TemplateException; import org.json.JSONObject; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.ui.ModelMap; import java.io.IOException; import java.util.ArrayList; import java.util.List; @SpringBootTest class WorkshareApplicationTests { @Test void contextLoads() throws IOException, TemplateException { //生成图片 ModelMap modelMap = new ModelMap(); Resume resume = new Resume(); resume.setName("王二狗"); resume.setAge("30"); List<Education> education = new ArrayList<>(); Education education1 = new Education(); education1.setSchoolName("家里蹲大学"); education1.setBeginDate("2000-01-01"); education1.setFinishDate("2005-01-01"); education1.setLevel("本科"); education.add(education1); Education education2 = new Education(); education2.setSchoolName("牢里蹲大学"); education2.setBeginDate("2005-01-01"); education2.setFinishDate("2010-01-01"); education2.setLevel("研究生"); education.add(education2); resume.setEducation(education); System.out.println(""+ education.toString()); modelMap.put("resume", resume); String templateName = "resume.ftl"; String html = FreemarkeTools.ftlToString(modelMap, templateName); String htmlFilePath = "D:\\huting\\resume.html"; String imageFilePath = "D:\\huting\\resume.png"; String imgPath = FreemarkeTools.turnImage(html,htmlFilePath,imageFilePath,1000,1000); System.out.println("文件生成路径" + imgPath); } }