需求:将数据生成到word模板文件
实现方式:使用ftl做模板文件,将数据写到word文档中
1、导包

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

2、将做好的word模板文件另存为xml;再将xml文件的后缀改成ftl。然后就可以使用ftl的表达式写需要替换的内容(和写jsp类似)注意:word 模板最好用03版的,如果不是的话 先另存为03版的再另存为03版的模板(为了兼容,避免低版本的office无法打开高版本)



3、使用ftl表达式,取数据

//循环
<#list infos as info > //嵌套的循环<#list info.values  as value > </#list>
</#list>
//if判断 ?? 表示非空 ?表示调用方法
<#if value.disPersonnel??>
//取值
${value.disPersonnel}
<#else>
</#if>
//调用日期格式化的方法
${workExp.startTime?string('yyyy-MM')}
//还有更多的ftl表达式 可根据需要单独百度ftl表达式

4、使用(代码很简单)

/*** @Author xxx* @Date 2020/4/19 - 15:52**/
public class Data2Word {public static void main(String[] args) throws Exception{Configuration configuration = new Configuration(new Version("2.3.28"));configuration.setDefaultEncoding("utf-8");//模板文件存放目录configuration.setDirectoryForTemplateLoading(new File("D:xxxx\\xxx"));//模板文件名称Template t = configuration.getTemplate("xxxx.ftl");// 模拟数据Map<String,Object> map = new HashMap<>();List<Map> list = new ArrayList<>();List<Integer> values = null;for(int i = 0 ; i < 3 ; i ++){values = new ArrayList<>();for(int j = 0 ; j < 60; j ++){values.add(j);}Map<String,Object> vMap =  new HashMap<>();vMap.put("values",values);list.add(vMap);}//此处是字节输出流、也可以用文件输出流输出到指定目录、ByteArrayOutputStream out = new ByteArrayOutputStream();map.put("infos",list);t.process(map, new OutputStreamWriter(out));System.out.println("end");}/**** @param data 数据源* @param dir 模板文件存放的目录* @param fileName 模板文件( 文件名 + 后缀)* @param dst 输出目录* @throws Exception*/public static void dataToWord(Object data,String dir, String fileName,String dst) throws Exception{Configuration configuration = new Configuration(new Version("2.3.28"));configuration.setDefaultEncoding("utf-8");configuration.setDirectoryForTemplateLoading(new File(dir));Template  t = configuration.getTemplate(fileName);t.process(data, new OutputStreamWriter(new FileOutputStream(dst)));}/**** @param data 数据源* @param dir 模板文件存放的目录* @param fileName 文件名 + 后缀* @return 字节输出流* @throws Exception*/public static OutputStream dataToWord(Object data, String dir,String fileName) throws Exception{Configuration configuration = new Configuration(new Version("2.3.28"));configuration.setDefaultEncoding("utf-8");configuration.setDirectoryForTemplateLoading(new File(dir));Template  t = configuration.getTemplate(fileName);ByteArrayOutputStream out = new ByteArrayOutputStream();OutputStreamWriter outputWriter = new OutputStreamWriter(out, "UTF-8");BufferedWriter writer = new BufferedWriter(outputWriter);t.process(data, writer);return out;}/**** @param data 数据源* param dir 模板文件存放的目录* @param fileName 文件名 + 后缀* @param outputStream 一般用作浏览器输出(response.getOutputStream())* @throws Exception*/public static void dataToWord(Object data,String dir, String fileName,OutputStream outputStream) throws Exception{Configuration configuration = new Configuration(new Version("2.3.28"));configuration.setDefaultEncoding("utf-8");configuration.setDirectoryForTemplateLoading(new File(dir));Template  t = configuration.getTemplate(fileName);t.process(data, new OutputStreamWriter(outputStream));}}

5、效果(文件太大了,拆成小文件,拆文件的方法未提供)

最后1、如果需求是每份表单结束后要分页,可在</#list> 循环标签结束前插入分页符,需要注意的是,有时分页不起效果,可以在做模板文件的时候,写几个特殊的字符,比如“aaaa”,找到对应的位置,在再插入分页符。反正都是些office的标签 多调试几次就能找到正确的位置。(因为不是专业搞office软件的,只能说些摸索的方式)

<wx:sect><w:p><w:pPr><w:rPr><w:rFonts w:fareast="宋体" w:hint="default"/><w:lang w:val="EN-US" w:fareast="ZH-CN"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="微软雅黑" w:eastAsia="微软雅黑" w:hAnsi="Calibri" w:cs="Times New Roman"/><w:b/><w:bCs/><w:kern w:val="44"/><w:sz w:val="28"/><w:szCs w:val="28"/></w:rPr><w:br w:type="page"/></w:r><w:r w:rsidRPr="00A77B55"><w:rPr><w:rFonts w:ascii="微软雅黑" w:eastAsia="微软雅黑" w:hAnsi="微软雅黑" w:cs="Times New Roman"/><w:b/><w:noProof/><w:spacing w:val="40"/><w:sz w:val="28"/><w:szCs w:val="28"/></w:rPr><w:lastRenderedPageBreak/><w:t xml:space="preserve"></w:t></w:r></w:p><w:sectPr><w:ftr w:type="odd"><w:p><w:pPr><w:pStyle w:val="a13"/><w:rPr><w:rFonts w:fareast="宋体" w:hint="default"/></w:rPr></w:pPr></w:p></w:ftr><w:pgSz w:w="11905" w:h="16837"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/></w:sectPr></wx:sect>

最后2、如果需求需要插入图片也简单,在模板中找到图片标签的位置,然后将图片转成base64的字符串 使用ftl标签替换就好了,和取普通数据一样,关键是找到图片标签的位置

总之使用ftl生成word文档会遇到一些奇奇怪怪的问题,代码很简单,主要是心细。假如遇到打开报“很抱歉,无法打开xxxx.doc,因为文件内容有问题”可能是因为字符串有特殊符号,组装值的时候把字符串转译一下,有好多类似的工具类,可自行百度。

动态生成word文档的靠谱方式相关推荐

  1. Freemarker - 根据模板动态生成word文档

    文章目录 Freemarker 根据模板动态生成word文档 Freemarker 介绍: Freemarker 使用: freemarker加载模板目录的方法 参考资料 Freemarker 根据模 ...

  2. Springboot中使用freemarker动态生成word文档

    文章目录 freemarker模板动态生成word文档 前言 准备 简单模板准备 <一> `word 2003` 新建`.doc` 模板 <二> 另存为`.xml` 文件,格式 ...

  3. 用Aspose.Words for .NET动态生成word文档中的图片或水印

    1.概述 在项目中生成word文档,这个功能很普遍的,一般生成都是纯文字或是列表的比较多,便于客户打印,而要把图片也生成到word文档中的需求有些客户也是需要的,例如产品图片.这次我们介绍的是如何利用 ...

  4. 【.NET】用Aspose.Words for .NET动态生成word文档中的数据表格

    1.概述 最近项目中有一个这样的需求:导出word 文档,要求这个文档的格式不是固定的,用户可以随便的调整,导出内容中的数据表格列是动态的,例如要求导出姓名和性别,你就要导出这两列的数据,而且这个文档 ...

  5. java根据模板动态生成word文档

    模板文档 首先,需要创建一个word模板,我的模板例子如下: 动态生成的文档 根据java代码动态的修改模板生成自己想要的文档,结果如下: 具体代码 代码操作如下:其中进行了文本的替换,图片的插入,以 ...

  6. Java动态生成word文档(图文并茂)

    很多情况下,软件开发者需要从数据库读取数据,然后将数据动态填充到手工预先准备好的Word模板文档里,这对于大批量生成拥有相同格式排版的正式文件非常有用,这个功能应用PageOffice的基本动态填充功 ...

  7. 动态生成word文档原来如此简单!Aspose.Words助力以Java编程方式创建丰富的Word文档

    近年来,Word文档的动态生成已成为组成报告,报价,发票和其他类型文档的流行功能.各种制造公司都基于数据库中存储的数据生成发票.在这种情况下,文档自动化可以节省手动文档创建过程中所需的时间,精力和资源 ...

  8. java利用freemarker动态生成word文档及动态表格

    这里写自定义目录标题 目标 准备 实现 处理模板 java实现 验证 目标 根据给定word模板,动态填充指定内容,并输出为新的word文档. 准备 1.模板: 准备一份目标格式的word文档,如:w ...

  9. C#动态生成Word文档并填充数据(二)

    /* * 1.添加引用->COM->Microsoft Word 11.0 Object Library 本文来源:IT传媒网 原文链接:http://www.cniter.com/tec ...

最新文章

  1. jdbc mysql - Column count doesn't match value count at row 1.
  2. MySQL 数据表备份导出,恢复导入操作实践
  3. 【概念集锦】之 浅拷贝与深拷贝
  4. Tomcat打开远程调试和jmx远程监控
  5. 树莓派 Zero WH 初使用体验
  6. VMware Workstation与Hyper-V不兼容。请先从系统中移除Hyper-V角色,然后再运行VMware Workstation。...
  7. RGB_LED,WS2811彩带驱动设计
  8. python标准库abc的实用技巧
  9. Data Base学习记录:关系模型
  10. Flutter 实现一款简单的音乐播放器
  11. 微信小程序判断是否开启定位功能引导重新打开定位权限
  12. mysql数据库innodb性能优化之缓冲池配置
  13. 写给零基础小白的网站开发入门
  14. 安装程序无法打开注册表项 UNKNOWN\Components\…解决办法
  15. 使用watermark.js给HTML、Word、PPT、Excel等添加水印
  16. linux驱动开发之内核线程
  17. 计算机系统构成及硬件基础知识(中级软件评测师备考笔记)
  18. 使用命令能够查看本地计算机,网络故障常用诊断命令及使用方法
  19. 巴拉巴拉一下戴森爷爷的产品发展历史
  20. 【转载】网络文件夹目前是以其他用户名和密码进行映射的。

热门文章

  1. html如何消除视频声音,剪映怎么去掉原视频声音
  2. OXID eShop 6.x ~ 6.3.4 版本SQL注入漏洞到命令执行漏洞在线实验
  3. Android中常用限定符的使用
  4. cesium+threejs结合实现GIS+BIM大场景-1
  5. 准备入手iPhone13,纠结选择买13 Pro Max还是13 Pro?
  6. You computer needs to restart to complete your Nahimic 3 installation.Do you want to restart now?
  7. Strom实时热力图展示项目
  8. yolov3 map、recall、p-r曲线可视化超详细
  9. 烟雾报警器语音提示芯片方案?
  10. youtube 视频引用问题 [隐藏标题和yt 图标]