SpringBoot整合Freemarker导出word文档表格
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文档表格相关推荐
- freemarker导出word文档——WordXML格式解析
前不久,公司一个项目需要实现导出文档的功能,之前是一个同事在做,做了3个星期,终于完成了,但是在项目上线之后却发现导出的文档有问题,此时,这个同事已经离职,我自然成为接班者,要把导出功能实现,但是我看 ...
- freemarker导出word文档
使用freemarker导出word文档的过程 **************************************************************************** ...
- Springboot 使用freemaker导出word文档
利用freemarker导出word文档,主要分为一下几部分,但是循环写入图片是其中最难的一点,尤其是从未使用freemaker导出word模板的新手.话不多说,开搞. 1 找到需要导出的word模 ...
- freemarker导出Word文档并在其中插入图片
先将word转成xml格式,再用notepad将其转为ftl格式(将要填入数据的地方加个占位符,${name}) import java.io.File; import java.io.FileInp ...
- 使用freemarker导出word文档包含多张图片
使用freemarker导出word文档包含多张图片 最近项目中有个需求就是导出word文档并且文档中需要有多张图片,我当时一脸懵逼啊,之前没有搞过这个啊,但是不要灰心,肯定会有很多人搞过的,百度一下 ...
- Java+freemarker 导出Word文档的实现(包括word for Mac 插入域的方法)-静态数据,动态表格list
1. 准备环境 1.1 word版本:MacOS系统下的Office360 word for Mac下好多操作和win的不一样啊啊啊,差点栽在Mac word的模版设计上. win版本的word模版设 ...
- java循环导出word文档_Java使用freemarker导出word文档
通过freemarker,以及JAVA,导出word文档. 共分为三步: 第一步:创建模板文件 第二步:通过JAVA创建返回值. 第三步:执行 分别介绍如下: 第一步: 首先创建word文档,按照想要 ...
- WordXML格式解析(应用于Freemarker导出word文档)
[WordXML] 项目中有时需要Word文档的导出/预览功能,使用Freemarker工具可以实现,文档的模板为WordXML格式,类似于html语言,不同标签含义不同,以下是经常用到的一些标签和注 ...
- java 如何将word 转换为ftl_使用 freemarker导出word文档
近日需要将人员的基本信息导出,存储为word文档,查阅了很多资料,最后选择了使用freemarker,网上一共有四种方式,效果都一样,选择它呢是因为使用简单,再次记录一下,一个简单的demo,仅供参考 ...
最新文章
- 数字签名和数字证书详解
- Linux删除 指定数目行【或者所有行】删除光标到行首
- ecshop goods.php,重命名ecshop的商品页goods.php为shangpin.php
- java最全基础知识_Java编程入门,选择排序(Selection Sort)怎么做?
- 看拉扎维《模拟CMOS集成电路设计》的一些总结和思考(九)——运算放大器
- map.java.opts_关于mapreduce.map.java.opts
- (翻译)线框图和设计原型图之间的区别是什么?
- 从零搭建若依环境(非分离版)
- 为什么字节跳动的年薪50万的软件测试工程师遍地都是?
- linux 内核调试 booting the kernel.,Linux无法启动解决 booting the kernel.
- 如果Mac苹果电脑关机关不了怎么办?
- 超级棒的一个DP问题详解(入门)
- java动效_Animations开源动效分析(一)POP按钮动画
- 2020年自考专科可以自考本科吗丨自考专科、自考本科能同时考吗
- 2.3-非平稳时间序列分析
- CVE漏洞攻击链案例描述
- 暴雪机器人消防_消防机器人技术在消防中的使用
- Open edX 学习、开发、运维相关链接整理
- “能握手才是好朋友(协议)”拓尔微高兼容性PD快充协议芯片 IM2406
- 100个网站推广实用方法