动态填充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);//读取文件路径,自行配置本地模板存放地址,TODOFile 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>test</title><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>-->
<#--            <tr>-->
<#--                <td class="col_15"><div>${product.supplyProductNo}</div></td>-->
<#--                <td class="col_40"><div>${product.productName}</div></td>-->
<#--                <td class="col_15">${product.productNumber}</td>-->
<#--                <td class="col_15">${product.productUnitPrice}</td>-->
<#--                <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生成图片的过程自行补全

java html模板转图片、动态绑定数据相关推荐

  1. 一步一步带你实现java根据模板导出word循环数据

    之前操作EXCEL使用的是poi,用poi操作word有点复杂,且没有模板功能.放弃 找到了freemarker这个工具,他可以根据word的模板生成导出的word 话不多说,跟着我来一步一步走 首先 ...

  2. java向Word模板中替换书签数据,插入图片,插入复选框,插入Word中表格的行数据,删除表格行数据

    java向Word模板中替换书签数据,插入图片,插入复选框,插入Word中表格的行数据,删除表格行数据 使用插件:spire.doc 创建工具类,上代码: import com.spire.doc.D ...

  3. Java中带图片的数据导出到excel

    Java中导入,导出带图片的数据及模板下载 数据导出 数据导出 导出包含了带图片的与不带图片的导出方式,大致如下: 无图片的导出 : 这种导出可以选择你喜欢用的,POI或者EasyExcel等,这里选 ...

  4. 利用freemarker 在模板里面写入动态数据,动态表格,图片插入并生成word文档

    利用freemarker 在模板里面写入动态数据,动态表格,图片插入. 以下测试代码图片(image.jpg)和模板(template.xml)是直接放到src目录下面的,可以根据自己需求调整 废话不 ...

  5. java生成PDF(图片,模板,表格)

    刚接到了一个需求,生成一个pdf,一开始以为挺简单的,通过模板生成嘛,我也发过相应的文章,根据模板直接生成pdf,响应到前端或者根据模板生成pdf,直接指定下载位置,这两种方案都可以,不过这篇文章主要 ...

  6. java使用itext将图片放到pdf模板的指定位置

    java使用itext将图片放到pdf模板的指定位置 前面的准备步骤可以参考我的上一篇文章 这里直接上代码 这里用的图片是路径的形式,还有种情况是图片是base64的时候,这种情况就需要转一下图片格式 ...

  7. java后台保存base64图片数据

    java后台保存base64图片数据 使用byte[] bytes = new BASE64Decoder().decodeBuffer(str);需要引入sun.misc.BASE64Decoder ...

  8. Java使用模板导出带图片word文档

    之前已经写过一个 Java使用模板导出Word文档 由于系统升级,模板得添加图片,这个时候遇到了一个比较恶心的问题特地发文记录一下. 先把老模板翻出来 **.ftl 然后右键用wps或者office打 ...

  9. 【用Java爬取网页图片——爬虫爬取数据】

    用Java爬取网页图片--爬虫爬取数据 1.在创建项目中导入jsoup 2.创建一个保存下载图片的路径 3.使用URL读取网页路径,jsoup读取网页内容 4.利用属性标签获取图片连接块 5.因为该路 ...

  10. java在模板图片中填写文字,java 操作pdf模板(向指定域添加文本内容和图片)

    项目需求涉及到操作pdf模板,根据生成好的模板向里面填充数据 用到的jar包是iText-5.0.6.jar 和iTextAsian.jar 上代码: public static void main( ...

最新文章

  1. SCOI2009 最长距离
  2. 【青少年编程】【三级】躲避恐龙
  3. 求职Python开发,面试官最喜欢问的几个问题
  4. Spring 3整合Quartz 2实现定时任务--转
  5. RedHat虚拟机安装VMware Tools
  6. SpringCloud Ribbon实战以及Ribbon的源码浅析(四)
  7. CSS background-position用法
  8. 我国常用的微型计算机是,2013云南省全国计算机等级考试二级笔试试卷VB理论考试试题及答案...
  9. cadence SPB 16.2下载地址
  10. oracle sql执行计划分析
  11. windows自带备份驱动
  12. 什么用matlab做ewma,ewma模型
  13. 五个最佳FTP客户端工具
  14. 为什么你搜不到想要的小程序?【附带最全小程序名单】
  15. FPGA学习—数码管显示
  16. 超好玩的硬币游戏,你会玩吗?
  17. 【歌曲分享-第一期】Bendy and the Ink Machine
  18. CPU GPU 扫盲帖
  19. CoolPad 8190工程模式
  20. python matlab 普朗克公式黑体光谱辐射出射度 绘图

热门文章

  1. NLPIR python测试
  2. 【游戏开发创新】用Unity等比例制作广州地铁,广州加油,早日战胜疫情(Unity | 地铁地图 | 第三人称视角)
  3. 《App后台开发运维和架构实践》勘误
  4. 一个很好用的JS在线格式化工具
  5. 为什么Word打印预览的跟实际的不一样呢
  6. 2019年南京大学计算机考研复试机试真题
  7. TCP调试助手,十六进制发送或者字符串形式发送的理解
  8. 贝叶斯公式的通俗理解
  9. 通俗易懂的讲解贝叶斯原理(保证简单)
  10. Magisk中文文档