动态填充html中数据,生成流对象, 在转成图片
此过程中简单样式的html效果还可以,但是遇到复杂的css兼容性不太好
一、引入依赖包以下示例使用gradle引入freemarker、xhtmlrenderer
dependencies {
implementation 'org.freemarker:freemarker-gae'
implementation 'org.xhtmlrenderer:core-renderer'
}
二、引入依赖包
Java生成对象流
package com.xxxxx.utils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.springframework.util.ResourceUtils;
import org.w3c.dom.Document;
import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Locale;
import java.util.Map;
import java.io.File;
import java.io.IOException;
import org.xhtmlrenderer.swing.Java2DRenderer;
public class HtmlToImgUtils {
private static String IMG_DEFAULT_PNG = "png";
private static int DEFAULT_WIDTH = 1100;
private static int DEFAULT_HEIGHT = 1100;
public static ByteArrayOutputStream getImageStream(String networkAddress, String fileName, Map map) throws Exception {
String html = getNetworkDirectoryTemplate(networkAddress, fileName, map);
return htmlToStream(html, map);
}
private static String getNetworkDirectoryTemplate(String networkAddress, String fileName, Map map) throws IOException, TemplateException {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
//读取网络文件路径
RemoteTemplateLoader templateLoader = new RemoteTemplateLoader(networkAddress);
cfg.setTemplateLoader(templateLoader);
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
cfg.setEncoding(Locale.CHINA, "UTF-8");
//路径下读取文件
Template temp = cfg.getTemplate(fileName, Locale.CHINA, "UTF-8");
StringWriter stringWriter = new StringWriter();
temp.process(map, stringWriter);
stringWriter.flush();
stringWriter.close();
return stringWriter.getBuffer().toString();
}
public static ByteArrayOutputStream getImageStreamLocal(String localFileName, Map map) throws Exception {
String html = getTemplate(localFileName, map);
return htmlToStream(html, map);
}
private static String getTemplate(String localFileName, Map map) throws IOException, TemplateException {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_25);
//读取文件路径,自行配置本地模板存放地址,TODO
File file = ResourceUtils.getFile("classpath:templates");
cfg.setDirectoryForTemplateLoading(file);
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
//路径下读取文件
Template temp = cfg.getTemplate(localFileName);
StringWriter stringWriter = new StringWriter();
temp.process(map, stringWriter);
stringWriter.flush();
stringWriter.close();
return stringWriter.getBuffer().toString();
}
private static ByteArrayOutputStream htmlToStream(String html, Map map) throws Exception {
String extension = map.get("extension") != null ? String.valueOf(map.get("extension")) : IMG_DEFAULT_PNG;
int width = map.get("width") != null ? Integer.parseInt(String.valueOf(map.get("width"))) : DEFAULT_WIDTH;
int height = map.get("height") != null ? Integer.parseInt(String.valueOf(map.get("height"))) : DEFAULT_HEIGHT;
byte[] bytes = html.getBytes();
ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(bin);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Java2DRenderer renderer = new Java2DRenderer(document, width, height);
BufferedImage img = null;
try {
//原图
img = renderer.getImage();
if (img == null) {
throw new Exception("无法加载原始图片");
}
//这里省略对图像进行处理
ImageIO.write(img, extension, outputStream);
} catch (IOException ex) {
throw new Exception(ex.getMessage());
} finally {
if (img != null) {
img.getGraphics().dispose();
}
}
return outputStream;
}
}
三、编写ftl文件
ftl文件代码为html, 扩展名是ftl
!DOCTYPE html>
test
单据编号:
${orderNo}
销售日期:
${createTime}
<#-- ftl支持循环语法,循环一个list, 仅仅展示语法, 已被注释, -->
<#-- <#list productList as product>-->
<#-- -->
<#-- ${product.supplyProductNo} -->
<#-- ${product.productName} -->
<#-- ${product.productNumber} -->
<#-- ${product.productUnitPrice} -->
<#-- ${product.productActualAmount} -->
<#-- -->
<#-- #list>-->
四、调用
//绑定动态数据 Mapmap = new HashMap<>(); map.put("orderNo", '164165313123'); map.put("createTime", "2022-02-02"); //阿里云的oss模板路径 ByteArrayOutputStream oStream = HtmlToImgUtils.getImageStream( "https://oss-cn-xxxx.aliyuncs.com/template/", "index.ftl", map); //服务器本地模板路径 ByteArrayOutputStream oStream1 = HtmlToImgUtils.getImageStreamLocal( "index.ftl", map); //ByteArrayOutputStre生成图片的过程自行补全



