• 之前操作EXCEL使用的是poi,用poi操作word有点复杂,且没有模板功能.放弃
  • 找到了freemarker这个工具,他可以根据word的模板生成导出的word

话不多说,跟着我来一步一步走

首先 我默认你已经有个maven或者gradle工程了

先别急着找freemarker的依赖,查查自己已有的依赖中是否已经有freemarker了.
查这里

有这个包就说明已经有该依赖了,不需要在导入了

  • 若没有该包,请导入该依赖项:
<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.28</version>
</dependency>

准备工作结束了,开始创建word模板

新建一个word,做好自己的模板,附上我的模板

解释:
${}中的是后面要使用的变量.
我用第一个

${l.communityName}

来举例
l表示某个集合中的某个实体,communityName是他的属性,也就是这里要填入的数据
在后面的代码中会有这样的:

List<Community> communities = communityMapper.selectList(null);
Map<String,Object> dataMap = new HashMap<String, Object>();
dataMap.put("list", communities);

word设计好后,将其转为xml

对该word文件点击另存为,选择xml

保存好后,打开,若没有一个xml的格式,大家可以对其格式化,idea直接格式化就行了,notepad++需要下载 xml tools 插件
下载xml tools插件 请自行搜索

下来这步很重要 ,需要各位非常细心!!!

打开xml后,找到第一个变量的位置,可以通过’$'符号找
找到后,会发现,这样的代码

                        <w:tc><w:tcPr><w:tcW w:w="3040" w:type="dxa"/><w:vAlign w:val="center"/></w:tcPr><w:p w:rsidR="00C43AC5" w:rsidRPr="00C43AC5" w:rsidRDefault="00C43AC5"><w:pPr><w:rPr><w:sz w:val="21"/></w:rPr></w:pPr><w:bookmarkStart w:id="0" w:name="_GoBack"/><w:r><w:rPr><w:rFonts w:hint="eastAsia"/><w:sz w:val="21"/></w:rPr><w:t>$</w:t></w:r><w:r><w:rPr><w:sz w:val="21"/></w:rPr><w:t>{</w:t></w:r><w:proofErr w:type="spellStart"/><w:r w:rsidR="00724485"><w:rPr><w:rFonts w:hint="eastAsia"/><w:sz w:val="21"/></w:rPr><w:t>l</w:t></w:r><w:r w:rsidR="00724485"><w:rPr><w:sz w:val="21"/></w:rPr><w:t>.</w:t></w:r><w:r w:rsidRPr="00C43AC5"><w:rPr><w:sz w:val="21"/></w:rPr><w:t>communityName</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:sz w:val="21"/></w:rPr><w:t>}</w:t></w:r><w:bookmarkEnd w:id="0"/></w:p></w:tc>

仔细观察这段代码中每个<w:t>标签,你会发现,他将刚刚我们写好的变量给拆分了.
下来就对这段代码进行修改.

注意:!!!

整个代码不能有删改,否则word会出现问题~~

我们只需要将<w:t>标签内的内容合并起来,变成如下所示的代码:

<w:tc><w:tcPr><w:tcW w:w="3040" w:type="dxa"/><w:vAlign w:val="center"/></w:tcPr><w:p w:rsidR="00C43AC5" w:rsidRPr="00C43AC5" w:rsidRDefault="00C43AC5"><w:pPr><w:rPr><w:sz w:val="21"/></w:rPr></w:pPr><w:bookmarkStart w:id="0" w:name="_GoBack"/><w:r><w:rPr><w:rFonts w:hint="eastAsia"/><w:sz w:val="21"/></w:rPr><w:t>${l.communityName}</w:t></w:r><w:r><w:rPr><w:sz w:val="21"/></w:rPr><w:t></w:t></w:r><w:proofErr w:type="spellStart"/><w:r w:rsidR="00724485"><w:rPr><w:rFonts w:hint="eastAsia"/><w:sz w:val="21"/></w:rPr><w:t></w:t></w:r><w:r w:rsidR="00724485"><w:rPr><w:sz w:val="21"/></w:rPr><w:t></w:t></w:r><w:r w:rsidRPr="00C43AC5"><w:rPr><w:sz w:val="21"/></w:rPr><w:t></w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:sz w:val="21"/></w:rPr><w:t></w:t></w:r><w:bookmarkEnd w:id="0"/></w:p></w:tc>

就是把<w:t>标签内的变量全部移动到第一个$后面,其他的<w:t>标签滞空.

接下来进行循环设置

找到需要循环的代码
将该段填入

<#list list as l>

第一个list表示循环,第二个表示

dataMap.put("list", communities);

dataMap的key

填入的位置

直观来看,是红色框内需要循环向下补充单元格

xml的代码中来看呢,

</w:tr>是单元格的一行结束的标签,找到他,下面就是需要循环的表格

注意!!!

<#list list as l>是需要结束标签的
结束标签:</#list>

另外,这个表格最后两个是时间格式的
如果就这样向后执行的话,会报这样的错

Tip: If you need a particular format only once, use ?string(pattern), like ?string('dd.MM.yyyy HH:mm:ss'), to specify which fields to display.

解决方法:

将这个代码
<w:t>${l.completionTime}</#if></w:t>
变为
<w:t>${l.completionTime?string('yyyy.MM.dd')}</#if></w:t>

处理数据为空的问题

当某个字段数据为空,且不处理时,会报错!
解决方法:
这里假设completionTime这个字段可能为空

<w:t><#if l.completionTime??>${l.completionTime?string('yyyy.MM.dd')}</#if></w:t>

加上

<#if l.completionTime??> 这个代码就行了

将word模板用java处理导出

将改好的xml后缀改为ftl

核心代码:

try {List<Community> communities = communityMapper.selectList(null);for (Community community : communities) {Integer state = community.getState();if(state==0){community.setStateStr("未开始");}else if (state==1){community.setStateStr("进行中");}else {community.setStateStr("已完成");}}Map<String,Object> dataMap = new HashMap<String, Object>();dataMap.put("list", communities);//Configuration 用于读取ftl文件//new Configuration()构造方法内是当前依赖的版本号Configuration configuration = new Configuration(new Version("2.3.28"));configuration.setDefaultEncoding("utf-8");/*** 指定ftl文件所在目录的路径,而不是ftl文件的路径* setClassForTemplateLoading(a,b)* a代表某个类加载器,b是ftl文件所在的路径,实在a所在的路径之下* 网上查了下有人说可以这么理解* 假设a的路径是:org.ql  而ftl在目录org.ql.template下* 那么这里需要写为:configuration.setClassForTemplateLoading(a.getClass, "/template下");* 但是!!! 我试了不行* 所以还是将那个包路径填为空 在后面将ftl文件的相对路径写入*/configuration.setClassForTemplateLoading(this.getClass(), "");//输出文档路径及名称File outFile = new File("E:/桌面/测试.doc");//以utf-8的编码读取ftl文件Template template = configuration.getTemplate("/template/老旧小.ftl", "utf-8");Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240);template.process(dataMap, out);out.close();} catch (Exception e) {e.printStackTrace();}

实际上,我的ftl文件放在该类所在的同包下的template包下

结束!

效果:

一步一步带你实现java根据模板导出word循环数据相关推荐

  1. java按照模板导出word 文档

    需求导出表格数据到word 文档中 新建word 文档 通过${ValueList1.value1} 来往里面添加数据, ValueList 即每一行数据的集合 保存word 文档,另存为 xml 格 ...

  2. java根据模板导出word文档

    1,新建word 格式是:姓名 ${vv} 或者 {{vv}} 如图: 2, 将该word文件另存为xml格式(注意是另存为,不是直接改扩展名) 3, 将xml文件的扩展名直接改为ftl 4, 用ja ...

  3. Java使用模板导出Word文档

    由于POI在word上操作导出也太麻烦了,直接放弃了,代码多又难控制.直接使用FreeMarker了 之前写过一个Java POI导出Excl个人简历,单元格合并.插入图片等虽然时间挺久了记忆犹新,需 ...

  4. java根据模板导出word

    制作模板 将word改成xml: 内容替换 将xml改成ftl list找到起始位置和结束位置 起始位置插入<#list lowlist as list> 结束位置插入</#list ...

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

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

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

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

  7. java按照模板导出pdf或者word

    一.java按照模板导出pdf (一)制作模板 1.在word里制作模板 因为PDF常用的软件不支持编辑,所以先用Word工具,如WPS或者Office新建一个空白Word文档,里面制作出自己想要的样 ...

  8. Java 根据模板导出PDF

    文章目录 前言 思路一:直接导出pdf 使用itext模板导出pdf 思路二:先导出word再转成pdf 1)导出word 2)word转pdf 最终方案 ~~docx4j~~ spire.doc.f ...

  9. java根据模板导出PDF详细教程(无bug版)

    题记:由于业务的需要,需要根据模板定制pdf文档,经测试根据模板导出word成功了:但是导出pdf相对麻烦了一点.两天的研究测试java导出PDF,终于成功了,期间走了不少弯路,今分享出来,欢迎大家有 ...

最新文章

  1. asp.net 在 Ngnix 服务器 中配置攻略
  2. mysql innodb 1017_MySQL InnoDB表压缩
  3. c语言编写经验逐步积累3
  4. ***快速理解Docker - 容器级虚拟化解决方案
  5. 安卓APP_ 控件(6)—— Notification通知
  6. 读书和不读书的女人之间,一眼就能看得出来差别
  7. 网络设备巨头优倍快的客户数据遭泄露
  8. 海康—SADP激活(设备网络搜索)
  9. 【考研数学】二. 一元函数积分学
  10. MySQL计算天数差
  11. QPalette类详细使用方法
  12. 老司机亲自整理的和弦知识让你事半功倍学乐理
  13. 一个在图片上写字的方法
  14. IKBC_DC-108 改装,加灯,加锂电池和充电
  15. 【学习笔记】从零开始造一个汗液检测穿戴设备——01.葡萄糖电化学检测
  16. 【千律】OpenCV基础:图像阈值分割 -- 自适应阈值分割 -- 代码实现
  17. rtx 加密机制_[原创]RTX(腾讯通)本地保存密码TEA变形算法及还原器
  18. 2.1.4 字符与字符串编码
  19. 通过python自动发送测试验收邮件及报告-实现邮件自动发送
  20. AVProVideo☀️四、视频播放案例

热门文章

  1. python循环语句while求和1-100_python循环语句(for/while)
  2. 串口编程 - windows如何枚举串口|获取活跃串口号
  3. 辅助账余额表分区方案
  4. 传统软件向SaaS软件转型方案的研究
  5. 如何机智的回复诈骗短信!
  6. 写一个设备的分配与调度简单方案_第八章:I/O设备管理
  7. C语言sizeof()和strlen()
  8. 向大家推荐一个治疗鼻炎的民间偏方
  9. SSM 框架 搭建整合(IDEA)保姆级
  10. 基于微信小程序在线电子书阅读、在线小说系统 系统的设计与实现 开题报告和效果图