动态填充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;
/**
* @author
* @date
*/
public class HtmlToImgUtils {
/***
* 默认画布宽度 1100px
*/
private static String IMG_DEFAULT_PNG = "png";
/***
* 默认画布宽度 1100px
*/
private static int DEFAULT_WIDTH = 1100;
/***
* 默认画布高度 1100px
*/
private static int DEFAULT_HEIGHT = 1100;
/**
* 得到图片流 可用于读取oss模板
*
* @param networkAddress 网络模板路径 https://xxxxxx.com/template/
* @param fileName 模板名称 index.html
* @param map map.extension 设置扩展名,可空, 默认值:png, jpg、png等
* map.width 设置画布宽度,可空, 默认值:1100, 单位px
* map.height 设置画布高度,可空, 默认值:1000, 单位px
* @return ByteArrayOutputStream
*/
public static ByteArrayOutputStream getImageStream(String networkAddress, String fileName, Map<String, Object> map) throws Exception {
String html = getNetworkDirectoryTemplate(networkAddress, fileName, map);
return htmlToStream(html, map);
}
/**
* 读取模板
*
* @param networkAddress 模板目录 https://xxxxxx.com/template/index.html
* @param fileName 模板名称 index.html
* @param map
* @return
*/
private static String getNetworkDirectoryTemplate(String networkAddress, String fileName, Map<String, Object> 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();
}
/**
* 得到图片流 可用于读取本地模板
*
* @param localFileName 本地模板名称
* @param map
* @return ByteArrayOutputStream
*/
public static ByteArrayOutputStream getImageStreamLocal(String localFileName, Map<String, Object> map) throws Exception {
String html = getTemplate(localFileName, map);
return htmlToStream(html, map);
}
/**
* 读取模板
*
* @param localFileName 模板名称
* @param map
* @return String
*/
private static String getTemplate(String localFileName, Map<String, Object> 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();
}
/**
* html模板转图片流
*
* @param html html模板
* @return ByteArrayOutputStream
*/
private static ByteArrayOutputStream htmlToStream(String html, Map<String, Object> 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>
<html xmlns="http://www.w3.org/1999/xhtml">
<head lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">meta>
<title>testtitle>
<style>
body {
font-family:"宋体";
}
.container {
position: relative;
box-sizing: border-box;
-moz-box-sizing: border-box; /* Firefox */
-webkit-box-sizing: border-box; /* Safari */
width: 1000px;
padding: 50px 50px 50px 50px;
}
.table_box {
width: 100%;
}
td {
min-height: 44px;
padding-left: 8px;
}
.col_15 {
width: 15%;
}
.col_40 {
width: 40%;
}
style>
head>
<body>
<div class="container">
<table class="table_box" border="1" cellspacing="0" frame="box" rules="all">
<tr>
<td class="col_15">单据编号:td>
<td class="col_40">${orderNo}td>
<td class="col_15">销售日期:td>
<td class="col_40">${createTime}td>
tr>
table>
<#-- ftl支持循环语法,循环一个list, 仅仅展示语法, 已被注释, -->
<#-- <#list productList as product>-->
<#-- >-->
<#-- class="col_15"><div>${product.supplyProductNo}div>td>-->
<#-- class="col_40"><div>${product.productName}div>td>-->
<#-- class="col_15">${product.productNumber}td>-->
<#-- class="col_15">${product.productUnitPrice}td>-->
<#-- class="col_15">${product.productActualAmount}td>-->
<#-- tr>-->
<#-- #list>-->
div>
body>
html>
四、调用
//绑定动态数据
Map<String, Object> map = 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生成图片的过程自行补全
欢迎分享,转载请注明来源:内存溢出
赞
(0)
打赏
微信扫一扫
支付宝扫一扫
KAFKA-02-kafka单机和集群的安装和使用详解
上一篇
2022-05-15
若依框架下Excel 导出自定义列属性只能下垃选择
下一篇
2022-05-15
评论列表(0条)