freemarker模板里面的template.process()方法里传入的第一个参数Object类型,如果是一个实体类对象在模板上怎么进行渲染,将实体类的值取出

freemarker会调用ObjectWrapper对传入的对象进行warp,具体类型在代码里面用instanceof进行判断。一般类型的实体对象,使用BeanModel进行解析,通过invoke getter方法取到对应的值。

所谓的object类型其实它并不是指所有类型,必须是Collection类型的

文章目录

  • 1、pom.xml
  • 2、制作.ftl模板
    • 2.1 创建word模板
    • 2.2 另存为xml格式,进行简单处理
    • 2.3 创建实体类
    • 2.4处理xml文件
    • 2.5修改后缀为ftl
  • 3、导出word方法
    • 3.1将demo.ftl放入resources/template
    • 3.2通用的word导出方法
    • 3.3执行导出方法
    • 3.4测试效果
  • 4、遇到的坑

1、pom.xml

在pom.xml文件中添加freemarker的依赖包

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency>

2、制作.ftl模板

2.1 创建word模板

创建word文档,制定表格。其中需要根据实际替换的元素用${...}书写。
主要包含几种情况:
1)正常需要替换的元素
2)“判断a”、“判断b”演示需要判断是否显示整行
3)“循环合并行”演示没有内容右边为空,有多条数据右边分行显示,左边自动合并。

2.2 另存为xml格式,进行简单处理

将word文档另存为xml格式。

1)首先找到之前写的替换元素,确保${…}和单词是连在一起的,如果不在一起,就把中间的删掉,处理到一起。

2)我习惯把xml文件按行给他格式化好
<w:tbl></w:tbl> 表示表格
<w:tr></w:tr> 表示行
<w:tc></w:tc> 表示列

2.3 创建实体类

public class DemoWordDetail {private String title;private String type;private String time;private String aaa;private int isShowA=1;//控制行显示private String bbb;private int isShowB=1;//控制行显示private List<CyclicModel> cyclics;//合并数据}public class CyclicModel {private String cyclic;/*** 合并标志;第一行"<w:vMerge w:val='restart'/>",后边行"<w:vMerge/>"*/private String merge;}

2.4处理xml文件

1)对于正常需要替换的元素可以不用做任何操作
2)“判断a”、“判断b”演示需要判断是否显示整行,定义字段isShowA、isShowB来控制

在行<w:tr></w:tr>的外层添加<#if></#if>标签,如果isShowA==1则显示这一行,如果为其他值则不显示。


3)“循环合并行”处理

采用<#if>显示处理数据<#else>显示空白,把${…}删掉</#if>
加 cyclics.merge处理第一列合并问题;将之前的{cyclics.merge}处理第一列合并问题; 将之前的cyclics.merge处理第一列合并问题;将之前的{cyclic}替换成${cyclics.cyclic}

2.5修改后缀为ftl

3、导出word方法

3.1将demo.ftl放入resources/template

3.2通用的word导出方法

@Service
public class WordService {public void exportWord(HttpServletRequest request, HttpServletResponse response, String fileName , String templeteName, Object dataModel){Configuration configuration=new Configuration();configuration.setDefaultEncoding("utf-8");configuration.setEncoding(Locale.getDefault(),"utf-8");try {configuration.setClassicCompatible(true);//处理dataModel中如果为null的情况//既能保证本地运行找得到模板文件,又能保证jar包运行能找到得到模板文件configuration.setClassForTemplateLoading(this.getClass(),"/template");configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(),"/template"));//            configuration.setDirectoryForTemplateLoading(new File(CommonUtil.getTempletePath()+"/template/"));Template t=configuration.getTemplate(templeteName,"utf-8");response.setContentType("application/msword; charset=UTF-8");// application/x-downloadresponse.setHeader("Content-Disposition", "attachment; "+ encodeFileName(request, fileName+".doc"));OutputStream outputStream = response.getOutputStream();Writer out=new OutputStreamWriter(outputStream);// 重要方法 <-----------------t.process(dataModel, out);outputStream.close();out.close();} catch (IOException | TemplateException e) {e.printStackTrace();}}public static String encodeFileName(HttpServletRequest request, String fileName)throws UnsupportedEncodingException{String new_filename = URLEncoder.encode(fileName, "UTF8").replaceAll("\\+", "%20");String agent = request.getHeader("USER-AGENT").toLowerCase();if (null != agent && -1 != agent.indexOf("msie")){/*** IE浏览器,只能采用URLEncoder编码*/return "filename=\"" + new_filename +"\"";}else if (null != agent && -1 != agent.indexOf("applewebkit")){/*** Chrome浏览器,只能采用ISO编码的中文输出*/return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";} else if (null != agent && -1 != agent.indexOf("opera")){/*** Opera浏览器只可以使用filename*的中文输出* RFC2231规定的标准*/return "filename*=" + new_filename ;}else if (null != agent && -1 != agent.indexOf("safari")){/*** Safani浏览器,只能采用iso编码的中文输出*/return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";}else if (null != agent && -1 != agent.indexOf("firefox")){/*** Firfox浏览器,可以使用filename*的中文输出* RFC2231规定的标准*/return "filename*=" + new_filename ;} else{return "filename=\"" + new_filename +"\"";}}}

3.3执行导出方法

        DemoWordDetail demoWordDetail=new DemoWordDetail();//一系列处理wordService.exportWord(request, response, "title", "demo.ftl", demoWordDetail);

3.4测试效果

判断a、判断b均显示,循环合并行多条数据

判断a这行不显示,循环合并行无数据

4、遇到的坑

1)导出对象字段有为null时,报错,加上“configuration.setClassicCompatible(true);”
2)idea运行能正常导出,jar运行不能找到模板,代码中给出了解决
3)cmd运行jar,能正常导出word,但是打开错误。经过测试发现导出word文档乱码,发现是是cmd默认编码问题,在cmd执行时加上:start javaw -Dfile.encoding=utf-8 -jar xxx.jar

SpringBoot整合Freemarker导出word文档表格相关推荐

  1. freemarker导出word文档——WordXML格式解析

    前不久,公司一个项目需要实现导出文档的功能,之前是一个同事在做,做了3个星期,终于完成了,但是在项目上线之后却发现导出的文档有问题,此时,这个同事已经离职,我自然成为接班者,要把导出功能实现,但是我看 ...

  2. freemarker导出word文档

    使用freemarker导出word文档的过程 **************************************************************************** ...

  3. Springboot 使用freemaker导出word文档

    利用freemarker导出word文档,主要分为一下几部分,但是循环写入图片是其中最难的一点,尤其是从未使用freemaker导出word模板的新手.话不多说,开搞. 1  找到需要导出的word模 ...

  4. freemarker导出Word文档并在其中插入图片

    先将word转成xml格式,再用notepad将其转为ftl格式(将要填入数据的地方加个占位符,${name}) import java.io.File; import java.io.FileInp ...

  5. 使用freemarker导出word文档包含多张图片

    使用freemarker导出word文档包含多张图片 最近项目中有个需求就是导出word文档并且文档中需要有多张图片,我当时一脸懵逼啊,之前没有搞过这个啊,但是不要灰心,肯定会有很多人搞过的,百度一下 ...

  6. Java+freemarker 导出Word文档的实现(包括word for Mac 插入域的方法)-静态数据,动态表格list

    1. 准备环境 1.1 word版本:MacOS系统下的Office360 word for Mac下好多操作和win的不一样啊啊啊,差点栽在Mac word的模版设计上. win版本的word模版设 ...

  7. java循环导出word文档_Java使用freemarker导出word文档

    通过freemarker,以及JAVA,导出word文档. 共分为三步: 第一步:创建模板文件 第二步:通过JAVA创建返回值. 第三步:执行 分别介绍如下: 第一步: 首先创建word文档,按照想要 ...

  8. WordXML格式解析(应用于Freemarker导出word文档)

    [WordXML] 项目中有时需要Word文档的导出/预览功能,使用Freemarker工具可以实现,文档的模板为WordXML格式,类似于html语言,不同标签含义不同,以下是经常用到的一些标签和注 ...

  9. java 如何将word 转换为ftl_使用 freemarker导出word文档

    近日需要将人员的基本信息导出,存储为word文档,查阅了很多资料,最后选择了使用freemarker,网上一共有四种方式,效果都一样,选择它呢是因为使用简单,再次记录一下,一个简单的demo,仅供参考 ...

最新文章

  1. 数字签名和数字证书详解
  2. Linux删除 指定数目行【或者所有行】删除光标到行首
  3. ecshop goods.php,重命名ecshop的商品页goods.php为shangpin.php
  4. java最全基础知识_Java编程入门,选择排序(Selection Sort)怎么做?
  5. 看拉扎维《模拟CMOS集成电路设计》的一些总结和思考(九)——运算放大器
  6. map.java.opts_关于mapreduce.map.java.opts
  7. (翻译)线框图和设计原型图之间的区别是什么?
  8. 从零搭建若依环境(非分离版)
  9. 为什么字节跳动的年薪50万的软件测试工程师遍地都是?
  10. linux 内核调试 booting the kernel.,Linux无法启动解决 booting the kernel.
  11. 如果Mac苹果电脑关机关不了怎么办?
  12. 超级棒的一个DP问题详解(入门)
  13. java动效_Animations开源动效分析(一)POP按钮动画
  14. 2020年自考专科可以自考本科吗丨自考专科、自考本科能同时考吗
  15. 2.3-非平稳时间序列分析
  16. CVE漏洞攻击链案例描述
  17. 暴雪机器人消防_消防机器人技术在消防中的使用
  18. Open edX 学习、开发、运维相关链接整理
  19. “能握手才是好朋友(协议)”拓尔微高兼容性PD快充协议芯片 IM2406
  20. 100个网站推广实用方法

热门文章

  1. 面试中C语言常问问题(含答案)
  2. Java中的如何检测字符串是否相等
  3. C语言:n个数的阶乘之和
  4. 吴恩达机器学习 EX7 第二部分 主成分分析(PCA)
  5. 195元爱奇艺会员只卖5元 揭秘背后黑色产业链
  6. 爆!出现滑块验证码的原因找到了!
  7. 【医学图像处理】CT成像技术之CT剂量
  8. vue中如何加入横线_vue
  9. 补码 符号数的二进制 整数
  10. String Ioc简介