使用freemarker循环图片(附demo)

2023-11-05

使用freemarker循环图片

一.效果展示(word文档)

在这里插入图片描述
今天重点讲解图片部分,基础数据展示不做讲解,要求对freemarker有一定的基础,
详看使用Freemarker输出word文档到浏览器与本地

今天为什么要单独讲解图片循环呢?因为在word生成的过程中,word的生成策略运用了比较多的关联,最重要的是使用freemarker你找不到循环体,所以今天特别写了这篇文章,demo放在最后,大家可自行下载

首先先讲一下word的生成策略:word转xml文件之后打开

1.数据源
2.关联
2.正文
先看数据源的位置:pkg:binaryData二进制数据

在这里插入图片描述因为有两张图片所以有两个二进制数据源
在这里插入图片描述图片样式统一处理,忽略掉

再看关联部分Relationships

在这里插入图片描述

<Relationships>有两部分,一部分是word文件相关,另一部分是外部数据源相关,我们只考虑外部数据源相关部分,<Relationships>的Id要与正文的数据地址相对应

最后看正文部分w:document

在这里插入图片描述因未有两张图片,所以与图片相关的有两个

忽略单个图片的样式后,循环图片的核心就是这三大部分了,所以我们要对这三部分数据进行循环和拼接,在拼接的过程中要指定正确的Relationship id

二:代码部分

一:创建maven工程

目录结构如下:
在这里插入图片描述

二:引入pom.xml依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>freemarkerDemo</groupId>
    <artifactId>freemarkerDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.28</version>
        </dependency>

        <!-- Spring框架基本的核心工具 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
        <!--测试依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>2.2.6.RELEASE</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.1</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13-beta-3</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>
    
</project>

三:核心代码

package com;

import cn.hutool.core.io.FileUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

//@SpringBootTest
@RunWith(JUnit4.class)
public class FreemarkerDemo {

    //请求响应方式
    public void printTroublerectifyAdvice(HttpServletResponse response) throws Exception{
        String content = exportFile();

        InputStream inputStream = IOUtils.toInputStream(content);
        ServletOutputStream out = null;
        try {
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode("隐患整改通知书", "UTF-8")+ ".doc")));

            out = response.getOutputStream();
            byte[] buffer = new byte[1024]; // 缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while((bytesToRead = inputStream.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        }catch (Exception e){
            throw new RuntimeException("导出word失败,请联系网站管理员!");
        }finally {
            out.flush();
            out.close();
            inputStream.close();
        }
    }

    /**
     * 单元测试
     * @throws Exception
     */
    @Test
    public void printTroublerectifyAdviceTest() throws Exception {
        byte[] buff=new byte[]{};
        String content = exportFile();
        buff=content.getBytes();
        FileOutputStream out=new FileOutputStream("D://scan//out.doc");
        out.write(buff,0,buff.length);

    }


    public String exportFile() throws Exception{
        //创建配置类
        Configuration configuration = new Configuration(Configuration.getVersion());
        String classPath = this.getClass().getResource("/").getPath();
        configuration.setDirectoryForTemplateLoading(new File(classPath+"template/"));

//        //获取模板文件
        Template template = configuration.getTemplate("troublerectifyAdvice.ftl");

        //随便添加几张图片
        BufferedInputStream in1 = FileUtil.getInputStream("D:/scan/test2_result.png");
        BufferedInputStream in2 = FileUtil.getInputStream("D:/scan/ucharts.png");
        BufferedInputStream in3 = FileUtil.getInputStream("D:/scan/IMG_2884.jpg");
        BufferedInputStream in4 = FileUtil.getInputStream("D:/scan/2019-09-04_105944.jpg");
        List<InputStream> list = new ArrayList<InputStream>();
        list.add(in1);
        list.add(in2);
        list.add(in3);
        list.add(in4);

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("number","20200817111106");
        data.put("checkedTime", "2020-09-30");
        data.put("checkedProjectName", "安全生产项目");
        data.put("checkedUser", "张三");
        data.put("rectifyPerson", "李四");
        data.put("rectifyedDate", "2020-08-07");
        data.put("troubleInfo", "详细信息");
        data.put("troubleResult", "整改结果详细");
        data.put("notarizePersion", "王五");

        //处理图片
        String beforePicStart = "<pkg:part pkg:name=\"/word/media/image";
        String afterPicStart = "<pkg:part pkg:name=\"/word/media/image";
        String picBeforeString = "";
        String picAfterString = "";

        String picStrEnd = ".jpeg\" pkg:contentType=\"image/jpeg\" pkg:compression=\"store\"><pkg:binaryData>";
        String picStrEnd2 = "</pkg:binaryData></pkg:part>";
        StringBuffer stringPicBufferBefore = new StringBuffer();
        StringBuffer stringPicBufferAfter = new StringBuffer();
        //处理Relation
        String beforeRelationStart = "<Relationship Id=\"rId";
        String afterRelationEnd = "\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image";
        String afterRelationEnd2 = ".jpeg\"/>";
        String relationStringBefore = "";
        String relationStringAfter = "";
        StringBuffer stringrelationshipBufferBefore = new StringBuffer();
        StringBuffer stringrelationshipBufferAfter = new StringBuffer();

        //处理rsidR
        String rsidStart = "<w:r><w:rPr><w:rFonts w:hint=\"eastAsia\"/><w:noProof/></w:rPr><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"114300\" distR=\"114300\"><wp:extent cx=\"1302589\" cy=\"1302589\"/><wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/><wp:docPr id=\"1\" name=\"图片 1\" descr=\"weixinceshi\"/><wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect=\"1\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"/></wp:cNvGraphicFramePr><a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\"><pic:nvPicPr><pic:cNvPr id=\"1\" name=\"图片 1\" descr=\"weixinceshi\"/><pic:cNvPicPr><a:picLocks noChangeAspect=\"1\"/></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip r:embed=\"rId";
        String rsidEnd = "\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"1304474\" cy=\"1304474\"/></a:xfrm><a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r>";
        String rsidAfterString = "";
        String rsidBeforeString = "";
        StringBuffer stringRsidBufferBefore = new StringBuffer();
        StringBuffer stringRsidBufferAfter = new StringBuffer();

        for (int i = 0; i < list.size(); i++) {
            String beforePic = FileToBase64(list.get(i));
            picBeforeString = beforePicStart + (i + 40) + picStrEnd + beforePic + picStrEnd2;
            relationStringBefore = beforeRelationStart + (i + 40) + i + afterRelationEnd + (i + 40) + afterRelationEnd2;
            rsidBeforeString = rsidStart + (i + 40) + i + rsidEnd;
            stringPicBufferBefore.append(picBeforeString);
            stringrelationshipBufferBefore.append(relationStringBefore);
            stringRsidBufferBefore.append(rsidBeforeString);
        }


        data.put("picDataBefore", stringPicBufferBefore.toString());
        data.put("picDataAfter", stringPicBufferAfter.toString());
        data.put("relationshipBefore", stringrelationshipBufferBefore.toString());
        data.put("relationshipAfter", stringrelationshipBufferAfter.toString());
        data.put("beforeRsid", stringRsidBufferBefore.toString());
        data.put("afterRsid", stringRsidBufferAfter.toString());

        String model="yyyy-MM-dd";  //指定格式化的模板
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(model);
        String date = simpleDateFormat.format(new Date());
        String[] split = date.split("-");
        data.put("year", split[0]);
        data.put("month", split[1]);
        data.put("day", split[2]);
        String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, data);

        return content
    }

    //文件转base编码
    public String FileToBase64(InputStream in) throws IOException {
        byte[] bytes = IOUtils.toByteArray(in);
        String encoded = Base64.getEncoder().encodeToString(bytes);
        return encoded;
    }
}


四:模板文件.ftl

太大了,百度云盘下载吧
链接:https://pan.baidu.com/s/1MRdyrknW4DHOLKsrSQu2HA
提取码:1111

项目地址https://gitee.com/marion1060/freemarkerDemo

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用freemarker循环图片(附demo) 的相关文章

  • 全面探索 FreeMarker 模版引擎的扩展性

    FreeMarker 模版引擎简介 FreeMarker 是一个采用 Java 开发的模版引擎 是一个基于模版生成文本的通用工具 FreeMarker 被设计用来生成 HTML Web 页面 特别是基于 MVC 模式的应用程序 虽然 Fre
  • 解决freemarker数组中的对象属性获取不到

    1 问题现象 使用Freemarker写入模板的时候 遍历List的时候发现对象中的首字母大写和带下划线的时候就会报错 The following has evaluated to null or missing FTL stack tra
  • 比MyBatis Generator更强大的代码生成器

    本文为 从零打造项目 系列第一篇文章 首发于个人网站 从零打造项目 系列文章 比MyBatis Generator更强大的代码生成器 SpringBoot项目基础设施搭建 前言 工欲善其事 必先利其器 作为 从零打造项目 系列的第一篇文章
  • 使用freemarker循环图片(附demo)

    使用freemarker循环图片 一 效果展示 word文档 今天重点讲解图片部分 基础数据展示不做讲解 要求对freemarker有一定的基础 详看使用Freemarker输出word文档到浏览器与本地 今天为什么要单独讲解图片循环呢 因
  • freemarker教程

    FreeMarker语言 FreeMarker语言概述 FreeMarker是一个模板引擎 一个基于模板生成文本输出的通用工具 使用纯Java编写 FreeMarker被设计用来生成HTML Web页面 特别是基于MVC模式的应用程序 虽然
  • jsp、freemarker、velocity、thymeleaf页面方案分析

    1 概述 在java领域 表现层技术主要有三种 1 jsp 2 freemarker 3 velocity 4 thymeleaf 2 jsp 优点 1 功能强大 可以写java代码 2 支持jsp标签 jsp tag 3 支持表达式语言
  • FTL 入门

    最近的项目中用的是ftl文件而不是传统的jsp 于是上网查了一下 感觉这是个好东西 于是准备记录下来 以下摘自百度百科 1 概念 FreeMarker是一款模板引擎 即一种基于模板和要改变的数据 并用来生成输出文本 HTML网页 电子邮件
  • Freemarker 转义 freemarker

    我正在使用 freemarker 生成 freemarker 模板 但我需要一些方法来逃避 freemarker 标签 我该如何逃脱 lt list gt 标签或 expression 您还可以使用 expression 如果您发现 嵌套令
  • 几个 jar 中的 freemarker 模板

    如何配置 freemarker 来搜索多个 jar 中的模板 随着春天
  • Keycloak 的 FreeMarker 电子邮件模板

    我正在使用 Keycloak 发送忘记密码的电子邮件 从我在他们的文档和 FreeMarker 文档中读到的内容来看 我似乎应该能够很好地使用 HTML 标签 但是 当我在 password rest ftl 文件中使用它们时 它会呈现整个
  • Freemarker 迭代 hashmap 键

    Freemarker 有两种集合数据类型 列表和哈希图 有没有一种方法可以像我们处理列表一样迭代哈希图键 因此 如果我有一个带有数据的变量 可以这样说 user name user email email protected homepag
  • 获取存储在变量中的字符串的值,该变量的名称作为字符串存储在另一个变量中

    lt assign blah foo gt lt assign foo awesome gt 我们可以在不引用 foo 的情况下渲染 awesome 吗 我尝试过类似的东西 blah 但它不起作用 有什么想法吗 有一个eval内置函数 它将
  • Keycloak主题变量

    在 Keycloak 的基本模板中 有多个变量示例 可在 Freemarker 模板中访问 例如 在文件中 https github com keycloak keycloak blob master themes src main res
  • GAE 上的 Struts 2:无法在拦截器内设置会话值

    我正在编写一个 Struts 2 拦截器 在其中检查用户是否有效 如果无效 用户将被重定向到登录页面 但在此之前 我尝试检索用户访问此处的 URL 并将其放入会话变量中 以便在登录完成后我可以将他重定向回那里 但是当我尝试在会话中放入一个值
  • IntelliJ下Spring Boot热部署模板和资源

    有谁知道在 IntelliJ 14 0 2 下为 Spring Boot 应用程序热部署资源和模板的机制 我知道完整的 Spring Boot 支持计划在 14 1 发布 但我有一个项目从标准 WAR 项目转换为 Spring Boot 项
  • 如何将日期时间显示为当地时间,末尾不带时区?

    编辑 由于一些看似混乱的情况 让我澄清一下 如果可能的话 我希望解决方案在 freemarker 中完成 而不是在 java 中完成 我有一个日期时间字符串 如下所示 2019 03 12T16 02 00 02 00我必须以特定的格式来显
  • 访问 <#list> 中对象的属性

    Solution 我之前曾尝试向 LineItem 类添加访问器 例如 public String getItemNo return itemNo 并将 FTL 从 lineItem itemNo to lineItem getItemNo
  • Freemarker:从模板文件 (*.ftl) 调用静态 util 方法

    在 Freemarker FTL 文件中 我想调用StringUtils capatilize myString 例如 p You selected selectionString p p StringUtils capatilize se
  • java.lang.NoClassDefFoundError:freemarker/template/TemplateModelException

    尝试打造先进HTML报告使用extentReportsjar 但它抛出以下错误 java lang NoClassDefFoundError freemarker 模板 TemplateModelException Code public
  • 在 freemarker 中,是否可以在包含文件之前检查文件是否存在?

    我们正在尝试在 freemarker 中构建一个系统 可以选择添加扩展文件来替换标准模板的块 我们已经到了这一步 lt attempt gt lt include extension ftl gt lt recover gt Standar

随机推荐

  • eclipse 导出maven 项目关联jar 文件

    一 默认导出maven 项目所在的文件夹target dependency 1 打开控制台指令窗口cmd 2 切换到maven 项目所在pom xml 文件所在目录 我的项目目录所在地址 D j2ee Morning 3 执行mvn 项目指
  • Qt多线程的创建详解

    文章目录 一 摘要 1 线程基础 2 为什么要创建多线程 3 创建多线程的方法 二 继承于QObject线程的创建 1 项目创建 2 代码编写与实现 三 线程间数据的传递 1 通过外部变量 2 通过信号与槽机制 四 总结 一 摘要 1 线程
  • Mysql 事务锁

    一 InnoDB锁的类型 S行级共享锁 S锁简单理解就是 运行 select from l where id 1 innoDB就会对id 1的这行数据进行加S锁 X行级排它锁 对数据进行修改时 就会对修改的行加X锁 排它的意思就是 在同一时
  • 【路径规划】基于哈里斯鹰优化算法的栅格法路径规划 机器人路径规划【Matlab代码#20】

    文章目录 可更换其他算法 获取资源 请见文章第6节 资源获取 1 原始HHO算法 2 机器人路径规划环境创建 3 路径规划模型建立 4 部分代码展示 5 仿真结果展示 6 资源获取 可更换其他算法 获取资源请见文章第6节 资源获取 1 原始
  • 白盒测试 代码检查

    6 2 1 代码检查法 代码检查包括桌面检查 代码审查和走查等 主要检查代码和设计的一致性 代码对标准的遵循 可读性 代码逻辑表达的正确性 代码结构的合理性等方面 发现违背程序编写标准的问题 程序中不安全 不明确和模糊的部分 找出程序中不可
  • SpringMvc学习-5-Spring MVC 文件上传

    文件上传 需要加入commons fileupload包 maven项目加入依赖
  • 1.SCT15单片机(建keil C51工程)

    1 文件管理 与新建文件 在其中创建3个文件 user obj app user 存放主函数和公共文件 obj keil软件生成的文件 app 存放各种外设文件 2 新建工程 a 打开Keil软件 点击如下进入新建工程界面 b 点击开始新建
  • assert_param()函数

    我们在学STM32的时候函数assert param出现的几率非常大 上网搜索一下 网上一般解释断言机制 做为程序开发调试阶段时使用 下面我就谈一下我对这些应用的看法 学习东西抱着知其然也要知其所以然 4 断言机制函数assert para
  • Pycharm激活注意事项及问题解决

    Pycharm激活方式 推荐采用破解补丁激活 基本上可以是永久使用 破解补丁请自行百度 都可以找得到 破解注意事项 激活之前需要先以试用的形式先启动一次Pycharm 进入到编程界面即为算作一次 破解完成之后打不开Pycharm问题 此问题
  • 在ubuntu16.04上搭建svn服务器

    本文介绍在如何在ubuntu16 04 的系统上搭建svn服务器以及可能遇到的问题 下面的操作都以root用户进行 1 安装svn服务器软件subversion 安装完成后的svn版本为 1 9 3 通过svn version可以查看版本号
  • 代码克隆检测(Code Clone Detection)数据集BigCloneBench最新版的使用方法

    代码克隆检测 Code Clone Detection 是软件工程领域的一个重要方向 每年都有很多论文 其中很多论文都用到了BigCloneBench 这里简单总结一下这个数据集的使用 不得不吐槽一点 学术界的数据集和工具 易用性都太差了
  • 斯坦福、伯克利、MIT、CMU、UIUC计算机专业概况

    自20世纪40年代世界第一台现代计算机在美国诞生以来 美国一直执全球计算机学界之牛耳 这同时也是美国计算机产业界占据绝对优势的重要原因之一 我们成批量地引进的国外众多优秀教材绝大多数也都来自美国 计算机学科仍然在高速发展 与此对应的计算机人
  • Gradle 7 ---版本依赖

    1 概述 1 1 特性 自动化的依赖管理有两个特性 明确依赖的版本 解决因传递性依赖带来的版本冲突 1 2 常用仓库 mavenLocal 本地 mavenCentral 公网 jcenter 公网 自定义maven仓库 nexus 1 3
  • 树莓派环境监控系统搭建(一)

    树莓派环境监控系统搭建 一 项目简介 使用树莓派和相关的观感器搭建系统 用以收集温度 湿度 而二氧化碳浓度保存至数据库中 同时在OLED屏幕上显示天气信息 温湿度 二氧化碳浓度 TVOC浓度 播报天气相关信息 系统功能 数码管显示当前时间
  • LeetCode第127题解析

    给定两个单词 beginWord 和 endWord 和一个字典 找到从 beginWord 到 endWord 的最短转换序列的长度 转换需遵循如下规则 每次转换只能改变一个字母 转换过程中的中间单词必须是字典中的单词 说明 如果不存在这
  • 2020-12-29 WARP SHUFFLE的大坑

    global void bcast int args int laneId threadIdx x 0x1f int value 31 laneId if threadIdx x lt 8 value args value shfl dow
  • SprinBoot使用PageHelper实现分页

    1 引入依赖
  • Windows 10搭建FTP服务器实现局域网文件共享

    1 安装 FTP服务器组件 打开 控制面板 单击 程序 单击 启动或关闭Windoes功能 在Internet information Services下勾选FTP服务和IIS相关服务 如下图所示 勾选完成后单击 确定 加载完成后重启电脑
  • Delphi结合LabelView进行条码打印

    使用LabelView软件的COM服务来对LabelView进行控制 即传递数据到LabelView的条码对象上 使我们可以自定义需要打印的条码数据 首先 导入类型库 在 Import Type Library 中选择LabelView O
  • 使用freemarker循环图片(附demo)

    使用freemarker循环图片 一 效果展示 word文档 今天重点讲解图片部分 基础数据展示不做讲解 要求对freemarker有一定的基础 详看使用Freemarker输出word文档到浏览器与本地 今天为什么要单独讲解图片循环呢 因