java-制作flt模板,导出word文档带图片循环

  • 模板制作
    • 制作xml
    • 编辑xml文档
    • 将xml模板转换为flt
  • 编写工具类
    • 导出word工具类
    • 获取远程图片
  • 使用示例
    • 使用示例--springboot

模板制作

制作xml

根据自己的业务需求制作相应的word模板
例如:

将对应的模板另存为xml格式

编辑xml文档

1.将保存好的xml文档利用idea打开,并使用快捷键将其简单的规整,这样有利于我们后期对它的编辑
2.规整后我们找到我们需要动态改变的位置,将需要变换的位置用${变量名}的方式标记
3.循环的写法
例子:
这里例子是给我模板图中的表格第二第三行

//这里标识循环的开始
//singlemaps 这个是list集合的变量名称,map 标识循环后每个变量的名字,这里有点类似于我们java中的foreach循环
<#list singlemaps as map><w:tr wsp:rsidR="00DA1F2C"><w:trPr><w:trHeight w:val="851"/><w:jc w:val="center"/></w:trPr><w:tc><w:tcPr><w:tcW w:w="5151" w:type="dxa"/><w:tcBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/></w:tcBorders><w:vAlign w:val="center"/></w:tcPr><w:p wsp:rsidR="00984D10" wsp:rsidRDefault="0031697E"><w:pPr><w:widowControl/><w:rPr><w:rFonts w:fareast="黑体"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="黑体" w:fareast="黑体" w:h-ansi="黑体" w:cs="宋体" w:hint="fareast"/><wx:font wx:val="黑体"/><w:color w:val="000000"/><w:kern w:val="0"/><w:sz-cs w:val="21"/></w:rPr>//这里我们用循环后的对象map获取相应的键值//如果是不需要循环的地方,我们则直接${键名}即可<w:t>${map.title}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="5055" w:type="dxa"/><w:tcBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/></w:tcBorders><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p wsp:rsidR="00984D10" wsp:rsidRDefault="00984D10"><w:pPr><w:widowControl/><w:rPr><w:rFonts w:ascii="黑体" w:fareast="黑体" w:h-ansi="黑体" w:cs="宋体"/><wx:font wx:val="黑体"/><w:color w:val="000000"/><w:kern w:val="0"/><w:sz-cs w:val="21"/></w:rPr></w:pPr></w:p></w:tc></w:tr><w:tr wsp:rsidR="00DA1F2C" wsp:rsidTr="008047BD"><w:trPr><w:trHeight w:val="3402"/><w:jc w:val="center"/></w:trPr><w:tc><w:tcPr><w:tcW w:w="5151" w:type="dxa"/><w:tcBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/></w:tcBorders><w:vAlign w:val="center"/></w:tcPr><w:p wsp:rsidR="00984D10" wsp:rsidRDefault="007D2947"><w:pPr><w:widowControl/><w:rPr><w:rFonts w:ascii="黑体" w:fareast="黑体" w:h-ansi="黑体" w:cs="宋体"/><wx:font wx:val="黑体"/><w:color w:val="000000"/><w:kern w:val="0"/><w:sz-cs w:val="21"/></w:rPr></w:pPr><w:r wsp:rsidRPr="009D2FA9"><w:rPr><w:noProof/></w:rPr><w:pict>//这个标识下面需要渲染图片的样式<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"/><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"/><v:f eqn="sum @0 1 0"/><v:f eqn="sum 0 0 @1"/><v:f eqn="prod @2 1 2"/><v:f eqn="prod @3 21600 pixelWidth"/><v:f eqn="prod @3 21600 pixelHeight"/><v:f eqn="sum @0 0 1"/><v:f eqn="prod @6 1 2"/><v:f eqn="prod @7 21600 pixelWidth"/><v:f eqn="sum @8 21600 0"/><v:f eqn="prod @7 21600 pixelHeight"/><v:f eqn="sum @10 21600 0"/></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/><o:lock v:ext="edit" aspectratio="t"/></v:shapetype>//这里标识的是一个导出的图片//这里的${map.url}中url的值为转换为base64格式的图片数据<w:binData w:name="wordml://${map.code}.png" xml:space="preserve">${map.url}</w:binData>//这里是将图片的数据和样式渲染出来//${map.code}这个标识图片的编号,多张图片的情况,这个值需要唯一//src="wordml://${map.code}.png" 这里我们需要这顶图片的名称//此后面的.png也可以根据实际的图片数据来进行动态<v:shape id="${map.code}" o:spid="${map.code}" type="#_x0000_t75" style="width:247.3pt;height:121.45pt;visibility:visible;mso-wrap-style:square"><v:imagedata src="wordml://${map.code}.png" o:title=""/></v:shape></w:pict></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="5055" w:type="dxa"/><w:tcBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="000000"/></w:tcBorders><w:shd w:val="clear" w:color="auto" w:fill="auto"/><w:vAlign w:val="center"/></w:tcPr><w:p wsp:rsidR="00984D10" wsp:rsidRDefault="0031697E"><w:pPr><w:widowControl/><w:rPr><w:rFonts w:ascii="黑体" w:fareast="黑体" w:h-ansi="黑体" w:cs="宋体"/><wx:font wx:val="黑体"/><w:color w:val="000000"/><w:kern w:val="0"/><w:sz-cs w:val="21"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="黑体" w:fareast="黑体" w:h-ansi="黑体" w:cs="宋体" w:hint="fareast"/><wx:fontwx:val="黑体"/><w:color w:val="000000"/><w:kern w:val="0"/><w:sz-cs w:val="21"/></w:rPr>//输出文字<w:t>${map.info}</w:t></w:r></w:p></w:tc></w:tr></#list>

将xml模板转换为flt

这里建议在改变文件后缀时再idea工具中进行,这样可以有效避免编码的问题
转换后

编写工具类

导出word工具类

import freemarker.template.Configuration;
import freemarker.template.Template;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;public class WordUtils {private static Configuration configuration = null;private static final String templateFolder = WordUtils.class.getClassLoader().getResource("").getPath();static {configuration = new Configuration(Configuration.VERSION_2_3_23);configuration.setDefaultEncoding("utf-8");try {configuration.setDirectoryForTemplateLoading(new File(templateFolder));} catch (IOException e) {e.printStackTrace();}}private WordUtils() {throw new AssertionError();}public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map, String title, String ftlFile) throws IOException {//ftl模板文件//这里需要将模板文件放在项目的resources目录下configuration.setClassForTemplateLoading(WordUtils.class,"/");//获取模板Template template = configuration.getTemplate(ftlFile);File file = null;InputStream fin = null;ServletOutputStream out = null;try {// 调用工具类的createDoc方法生成Word文档file = createDoc(map, template);fin = new FileInputStream(file);String fileName = title + ".doc";response.setCharacterEncoding("utf-8");response.setContentType("application/msword");// 设置浏览器以下载的方式处理该文件名response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));out = response.getOutputStream();byte[] buffer = new byte[512];  // 缓冲区int bytesToRead = -1;// 通过循环将读入的Word文件的内容输出到浏览器中while ((bytesToRead = fin.read(buffer)) != -1) {out.write(buffer, 0, bytesToRead);}} finally {if (fin != null) {fin.close();}if (out != null) {out.close();}if (file != null) {file.delete();} // 删除临时文件}}//渲染文件private static File createDoc(Map<?, ?> dataMap, Template template) {String name = "test.doc";File f = new File(name);Template t = template;try {// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");t.process(dataMap, w);w.close();} catch (Exception ex) {ex.printStackTrace();throw new RuntimeException(ex);}return f;}
}

获取远程图片

import sun.misc.BASE64Encoder;
import java.io.*;
import java.net.URL;
/*** 读取远程文件为base64*/
public class FileDown {//urlImage文件的远程地址public static String getImageStr(String urlImage) throws Exception {InputStream in = null;byte[] data = null;try {//这里的处理是为了在读取文件的时候因为带宽影响转换String newNumber = urlImage.replace("http://域名地址/image/", "http://对应服务器内部地址/image/");in = getInputStream(newNumber);data = new byte[in.available()];in.read(data);in.close();} catch (IOException e) {e.printStackTrace();}BASE64Encoder encoder = new BASE64Encoder();return encoder.encode(data);}public static InputStream getInputStream(String imageUrl) throws Exception {URL url = new URL(imageUrl);InputStream ism = url.openStream();return ism;}public static void main(String[] args) throws Exception {getImageStr("https://xxx/xxx.png");}
}

使用示例

使用示例–springboot

     //存储的整体数据Map<String, Object> dataMap = new HashMap<String, Object>();dataMap.put("无需循环的值", "无需循环的值");List<Map<String, String>> singlemaps = new ArrayList<Map<String, String>>();if (report.getConstructionUrl()!=null&&report.getConstructionInfo()!=null){Map<String, String> map = new HashMap<String, String>();map.put("循环值", "循环值");map.put("循环值图", FileDown.getImageStr("图片路径")/直接填写bsae64);map.put("循环图片编号","03000001/建议数字");singlemaps.add(map);}WordUtils.exportMillCertificateWord(request, response, dataMap/参数map集合, "文件名称", "mb.flt/模板文件名称");

java-制作flt模板,导出word文档带图片循环相关推荐

  1. java通过freemarker导出word文档带图片并且循环

    转载请标明出处: https://blog.csdn.net/weixin_41965979/article/details/80969287 本文出自付付讶的博客 1:所需jar包:freemark ...

  2. java调用word模板文件_Java使用模板导出word文档

    Java使用模板导出word文档 需要导入freemark的jar包 使用word模板,在需要填值的地方使用字符串代替,是因为word转换为xml文件时查找不到要填入内容的位置.尽量不要在写字符串的时 ...

  3. java关于对于word或者pdf文件的批量下载实现,其中包括(Java实现创建word文档模板,根据模板导出word文档)

    本次需求是,pdf是表格类型的文件,我这里使用了word模板进行处理.但由于是多个文件一起导出,因此全部放到一个目录底下进行打包下载. ## 整体思路 /*** 下载思路:* 1.查询出数据后:* 2 ...

  4. Springboot通过模板生成pdf文档带图片

    Springboot通过模板生成pdf文档带图片 环境:springboot2.3.10.RELEASE + itextpdf5.5.13.2 依赖 <dependency><gro ...

  5. 【Java】使用模板生成word文档到服务器,并下载

    前台js只需要一个方法, 1.Action:说明:dataMap是需要展示的数据, String rootPath = SaveFileUtil.FILE_PATH;此处是为了判断盘符的,win系统和 ...

  6. 用word模板导出word文档

    项目需求要把页面上的分析结果导出为word文档,实现的办法是POI.查了一下网上很多方式都采用FreeMark,自己认为比较麻烦,所以还是采取了POI导出.之前的框架是SSH的,现在换成了Spring ...

  7. Java使用POI实现导出Word文档

    POI官网链接:http://deepoove.com/poi-tl/(方便各位博友后期深入学习) 1.首先导入POM依赖包 <dependency><groupId>com. ...

  8. Aspose.Words利用Word模板导出Word文档

    今天工作中遇到了导出Word文档的问题,但是在搜索Aspose.Words 导出Word文档时发现网上的方法都是有头没尾的,有的只有一小段实例,让人看着摸不着头脑. 利用Aspose.Words导出W ...

  9. Java使用Spire.Doc实现Word文档添加图片水印

    通过本文你将学到: Spire.Doc是什么? 如何在项目中引入Spire.Doc依赖? 项目中基于Spire.Doc封装工具类实现Word文档添加图片水印? 一.Spire.Doc是什么? 1.Sp ...

最新文章

  1. 循环语句——7月23日
  2. 利用Use Case为系统行为建模(1)
  3. 黑莓作为猫带笔记本上网
  4. python安装docx库_linux 环境下的python 安装 docx 的过程
  5. 面试mysql中怎么创建索引_阿里面试:MySQL如何设计索引更高效?
  6. 电信aep平台是什么意思_江苏天鼎证券:股票平台跳水是什么意思?股票为什么会跳水?...
  7. Bokeh——交互式可视化库
  8. Facebook: 亿级向量相似度检索库Faiss 原理+应用
  9. Invalidate() UpdateData() OnPaint()与OnDraw
  10. [转]什么是lib文件,lib和dll的关系如何
  11. CRM客户管理系统能为企业带来什么好处?
  12. Docker学习之镜像删除的Untagged 和 Deleted
  13. 【IDEA】如何修改已创建的文件类型,虽然很无脑,但是也很棘手
  14. 三栏式布局详解(代码+图解)
  15. 计算ERA-5数据的相对湿度(RH)与饱和水汽压差(VPD)
  16. 计蒜客 428(人人都有极客精神-日期问题)
  17. Django项目骨架与常见配置修改
  18. C语言教程(五):选择结构
  19. 从零开始实现一个基于RISC-V的流水线处理器 (1) :RISC-V指令集架构详解
  20. 大学计算机实验报告答案 南京理工大学,南京理工大学微机实验报告.doc

热门文章

  1. UVA12563 Jin Ge Jin Qu hao
  2. 带你了解现有UWB技术及原理
  3. 坏样本不够多,怎么办?
  4. 帆软中python调用_如何1min了解台灣及全球地震分佈情況:用PythonFineReport培養分析思維(上)...
  5. 解决:Cause: java.sql.SQLException: Incorrect integer value: ‘xxx‘ for column ‘xxx‘ at row 1
  6. CSDN 写博客 word文档复制粘贴 图片粘贴 加载失败问题解决
  7. 丢掉鼠标吧,使用最好用的Eclipse快捷键
  8. 手机操作系统开源软件
  9. IT人生nbsp;需要指引lt;转自:51ctogt;
  10. 用聚宽量化炒股1-设置函数