一、引入freemarker maven依赖
<!--freemarker模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
二、在项目resources目录下就可以创建以ftl结尾的引擎模板啦
WHImgShare.ftl 内容如下
<html lang="en">
<head>
</head>
<body>
<div ref="el" class="valueshow">
<img class="" src="${bgImg}" alt=""/>
<div class="valueshow-box ">
<p class="vs-box-txt">You can transfer</p>
<p class="vs-box-val">${amtValue} Mile</p>
</div>
</div>
</body>
</html>
三、定义接口
public interface IFreemarkerService {
/**
* @Description: 模板生成
* @data: [model, templatePath]
* @return: java.lang.String
* @Date: 2023-03-65 10:12:26
*/
String shareInfoToHtml(Map<String,Object> model,String templatePath);
}
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import java.util.Map;
@Service
@Slf4j
public class FreemarkerServiceImpl implements IFreemarkerService {
@Autowired
Configuration configuration;
/**
* @param model
* @param templatePath
* @Description: 模板生成
* @data: [model, templatePath]
* @return: java.lang.String
* @Date: 2023-03-65 10:12:26
*/
@Override
public String shareInfoToHtml(Map<String, Object> model, String templatePath) {
Template template = null;
try {
template = configuration.getTemplate(templatePath);
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
} catch (Exception e) {
log.info("Freemarker模板渲染视图失败"+e.getMessage());
}
return "";
}
}
四、业务调用
// 传入数据modelMap + 模板名称
String html = iFreemarkerService.shareInfoToHtml(modelMap, "/WHImgShare.ftl");
public class ImageUtil {
/**
* @Description: html转图片
* @data: [html, width, height] html字符串、宽、高
* @return: java.awt.image.BufferedImage
* @Date: 2023-03-65 14:09:57
*/
public static BufferedImage turnImage(String html, Integer width, Integer height) throws Exception {
// 转文档
byte[] bytes=html.getBytes();
ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(bin);
/*
画笔生成图
*/
DOMAnalyzer da = new DOMAnalyzer(document);
// 创建一个字节流
InputStream is = new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8));
DocumentSource docSource = new StreamDocumentSource(is, null, "text/html; charset=utf-8");
// 设置样式属性
da.attributesToStyles();
da.addStyleSheet(null, CSSNorm.stdStyleSheet(), DOMAnalyzer.Origin.AGENT);
da.addStyleSheet(null, CSSNorm.userStyleSheet(), DOMAnalyzer.Origin.AGENT);
da.addStyleSheet(null, CSSNorm.formsStyleSheet(), DOMAnalyzer.Origin.AGENT);
da.getStyleSheets();
// 转图片
GraphicsEngine contentCanvas = new GraphicsEngine(da.getRoot(), da, docSource.getURL());
contentCanvas.createLayout(new Dimension(width, height));
// contentCanvas.setSize(width, height);
contentCanvas.setUseKerning(false);
contentCanvas.setAutoSizeUpdate(false);
contentCanvas.getConfig().setClipViewport(false);
contentCanvas.getConfig().setLoadImages(true);
contentCanvas.getConfig().setLoadBackgroundImages(true);
// 生成图片
BufferedImage img = contentCanvas.getImage();
//图片裁剪(移除白边)
Rectangle bounds = getBounds(img, Color.WHITE);
//输出当前图片宽高
BufferedImage cutBufferedImage = img.getSubimage(bounds.x, bounds.y, bounds.width, bounds.height);
// final FSImageWriter imageWriter = new FSImageWriter();
// imageWriter.setWriteCompressionQuality(0.0f);
// // 生成图片名字
// String uuid = UUID.randomUUID().toString();
// //输出路径
// imageWriter.write(bufferedImage, "D:\\img\\" + uuid + ".png");
return bufferedImage;
}
public static MultipartFile bufferedImageToMultipartFile(BufferedImage bufferedImage,String filename,String originalFilename){
//创建一个ByteArrayOutputStream
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
//把BufferedImage写入ByteArrayOutputStream
ImageIO.write(bufferedImage, "jpg", os);
//ByteArrayOutputStream转成InputStream
InputStream input = new ByteArrayInputStream(os.toByteArray());
//InputStream转成MultipartFile
return new MockMultipartFile(filename, originalFilename, ContentType.IMAGE_JPEG.toString(), input);
} catch (IOException e) {
log.info("BufferedImageToMultipartFile error:"+e.getMessage());
}
return null;
}
/**
* @Description: 图片裁剪
* @data: [img, fillColor] 图像、颜色
* @return: java.awt.Rectangle
* @Date: 2023-03-66 10:20:09
*/
public static Rectangle getBounds(BufferedImage img, Color fillColor) {
int top = getYInset(img, 20, 0, 1, fillColor);
int bottom = getYInset(img, 20, img.getHeight() - 10, -1, fillColor);
int left = getXInset(img, 10, top, 1, fillColor);
int right = getXInset(img, img.getWidth() - 40, top, -1, fillColor);
return new Rectangle(left, top, right - left, bottom - top);
}
public static int getYInset(BufferedImage img, int x, int y, int step, Color fillColor) {
while (new Color(img.getRGB(x, y), true).equals(fillColor)) {
y += step;
}
return y;
}
public static int getXInset(BufferedImage img, int x, int y, int step, Color fillColor) {
while (new Color(img.getRGB(x, y), true).equals(fillColor)) {
x += step;
}
return x;
}
/**
* 模拟 http post请求
*
* @param httpUrl
* @return
* @throws IOException
*/
public static InputStream dowloadFile(String httpUrl) throws IOException {
URL url = null;
try {
url = new URL(httpUrl);
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
URLConnection conn = url.openConnection();
InputStream inStream = conn.getInputStream();
return inStream;
}
/**
* 读取字节输入流内容
*
* @param is
* @return
*/
public static byte[] readInputStream(InputStream is) {
ByteArrayOutputStream writer = new ByteArrayOutputStream();
byte[] buff = new byte[1024 * 2];
int len = 0;
try {
while ((len = is.read(buff)) != -1) {
writer.write(buff, 0, len);
}
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return writer.toByteArray();
}
}