java基于feemarker 生成word文档(超级简单)
问题由来:
开发个新需求,需要按规定导出word文档,文档截图如下
因为之前没做过这个,一脸懵B啊,导出excel和txt倒是经常接触到,对于这个word这种格式不严谨的文件怎么处理呢?
技术选型:可协助实现的技术很多,但是本人极力推荐feemarker,简直太好用了。
具体实施:
步骤一:maven项目 先添加如下依赖:
<!--freemarker 协助word 导出-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
不是maven的,去下载feemarker.jar 导入就好了
步骤二:原理就是先做一个word模板, 该模板中变量数据用${xxx}这种方式填写, 然后再导出时只需读取模板然后用相应的数据替换其中的${xxx}即可.
我们这里设置了三个变量;
步骤三: 把该word文档 另存为xml文件(是另存为,不是改扩展名为xml),然后再改扩展名为ftl,步骤不能错。随便放在一个地方,我们这里先放在D盘根目录 名为 测试.ftl;
步骤四:上代码
try {
Map<String,String> dataMap = new HashMap<String,String>();
dataMap.put("account", "123456");
dataMap.put("name", "张三");
dataMap.put("idNumber", "123123");
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
//指定模板路径的第二种方式,我的路径是D:/ 还有其他方式
configuration.setDirectoryForTemplateLoading(new File("D:/")); // 输出文档路径及名称
File outFile = new File("D:/test.doc");
//以utf-8的编码读取ftl文件
Template t = configuration.getTemplate("测试.ftl","utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"),10240);
t.process(dataMap, out);
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
跑起来,大兄弟。
步骤四:跑完,发现在我的D盘 有个test.doc,点开看看
完美啊,发现数据进去了。
技术扩展(循环列表):
其实到这里,已经可以满足很多的场景需要了。
但是我们这里还欠缺了点,因为我们的数据列表是循环的,因为可能不止一条数据。
那怎么办呢?
其实feemarker已经为我们考虑了这一点了, 先上代码
Map<String,String> map1 = new HashMap<String,String>();
map1.put("account", "123456");
map1.put("name", "张三");
map1.put("idNumber", "123123");
Map<String,String> map2 = new HashMap<String,String>();
map2.put("account", "456789");
map2.put("name", "李四");
map2.put("idNumber", "123"); List<Map<String,String>> newlist = new ArrayList<>();
newlist.add(map1);
newlist.add(map2);
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("userList", newlist); Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
//指定模板路径的第二种方式,我的路径是D:/ 还有其他方式
configuration.setDirectoryForTemplateLoading(new File("D:/")); // 输出文档路径及名称
File outFile = new File("D:/test.doc");
//以utf-8的编码读取ftl文件
Template t = configuration.getTemplate("测试.ftl","utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"),10240);
t.process(dataMap, out);
out.close();
代码里我们对数据的封装做了改动,我们传了list进去,list里面都是key相同的map;
还得对我们的 ftl 文件内容改动一下
搜索 w:tr 可以找到行的起点与结束点(注意第一对w:tr 是表头,应找第二对 w:tr), 如图(网上摘录的图,因为我自己的ftl文件内容太大,截不了):
用<#list userList as user> </#list>标签将第二对 w:tr 标签包围起来(userList是集合的key, user是集合中的每个元素, 类似<c:forEach items='userList' var='user'>), 如图:
当然,这里的user.a 要换 user随便写,和上面的as user对应起来就好,这里需要改成user.account, user.name,user.idNumber;
现在看看文件变成什么样了
完美解决list循环读取的问题;
扩展二(直接导出):
显然我们这里处理文件的方式是直接生成文件放在了D盘里,更多的时候,我们需要直接导出;
Map<String,String> dataMap = getData(); //获取数据
//Configuration用于读取ftl文件
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8"); //获取模板所在的路径
configuration.setDirectoryForTemplateLoading(new File(pathHelper.getWebClassesPath()+"/template")); //以utf-8的编码读取ftl文件
Template t = configuration.getTemplate("测试.ftl","utf-8"); String fileName = URLEncoder.encode("客户信息-","UTF-8") + dataMap.get("formCode")+".doc";
//1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
response.setContentType("multipart/form-data");
//2.设置文件头:最后一个参数是设置下载文件名(假如我们叫a.pdf)
response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), "utf-8"),10240);
t.process(dataMap, out);
out.close();
这样就可以直接导出了。
可能遇到的bug:
就是获取模板的那步可能会出问题,提示找不到模板。feemarker为我们提供了三种方法
第一种:基于类路径,HttpWeb包下的framemaker.ftl文件
configuration.setClassForTemplateLoading(this.getClass(), "/HttpWeb");
第二种:基于文件系统
configuration.setDirectoryForTemplateLoading(new File("/template"))
第三种:基于Servlet Context,指的是基于WebRoot下的template下的framemaker.ftl文件
HttpServletRequest request = ServletActionContext.getRequest();
configuration.setServletContextForTemplateLoading(request.getSession().getServletContext(), "/template");
因为放在项目中,肯定想设置个相对路径,我就选择了第一种,
项目存放路径
注意:configuration.setClassForTemplateLoading(this.getClass(),"/jasperreports");
这样就可以了,千万别写什么 /resources/jasperreports,因为maven项目打包的时候,resources文件夹就不存在了。 好了到这里,介绍完毕,是不是很简单又美观呢。
java基于feemarker 生成word文档(超级简单)的更多相关文章
- java使用freemarker 生成word文档
java 生成word文档 最近需要做一个导出word的功能, 在网上搜了下, 有用POI,JXL,iText等jar生成一个word文件然后将数据写到该文件中,API非常繁琐而且拼出来的 ...
- java使用freemarker生成word文档
1.原料 开源jar包freemarker.eclipse.一份模板word文档 2.首先设计模板word文档 一般,通过程序输出的word文档的格式是固定的,例如建立一个表格,将表格的标题写好,表格 ...
- Java根据模板生成Word文档
一,首先制作模板 1.先做一个Word文档, 2.打开Word,然后另存为*.xml文件 3.最后修改*.xml文件的后缀名为*.ftl 二,打开项目编辑器Idea,在pom文件中引入相关架包依赖(我 ...
- JSP生成WORD文档,EXCEL文档及PDF文档的方法
转自:https://www.jb51.net/article/73528.htm 本文实例讲述了JSP生成WORD文档,EXCEL文档及PDF文档的方法.分享给大家供大家参考,具体如下: 在web- ...
- PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0),目前只能java生成】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个是<PoiDemo[Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)]>的扩展,上一篇是根 ...
- FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个方案只能在java中运行,无法在Android项目中运行.所以此方案是:APP将表单数据发送给后台,后台通过freemarker ...
- PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能.这里的模板文件是doc文件.如果模板文件是docx文件的话,请阅读 ...
- Java Web项目中使用Freemarker生成Word文档
Web项目中生成Word文档的操作屡见不鲜.基于Java的解决方式也是非常多的,包含使用Jacob.Apache POI.Java2Word.iText等各种方式,事实上在从Office 2003開始 ...
- 使用Java生成word文档(附源码)
当我们使用Java生成word文档时,通常首先会想到iText和POI,这是因为我们习惯了使用这两种方法操作Excel,自然而然的也想使用这种生成word文档.但是当我们需要动态生成word时,通常不 ...
随机推荐
- conduit 安装试用
备注: 测试安装环境使用docker mac 版本(目前版本已经支持kubernetes了) 1. 基本安装 curl https://run.conduit.io/install | bash 配置 ...
- lapis 集成openresty最新版本cjson 问题的解决
备注: 为了解决安装了lapis.同时又希望使用新版nginx 以及openresty 的特性(stream ...) 1. 解决方法 参考: https://github.com/leaf ...
- smarty核心思想 自制模板引擎
<?php $tit = '今天下雨了,淋了半条街'; function tit($file){ //读文件 $h = file_get_contents($file); $h = str_re ...
- 记一笔vue中的中央事件总线的问题,以及解决方案
代码结构:首先HeaderNav组件是被单独拎出来的,router-view中就对应了内容组件,由于有时候i有的界面的header内容是不一样的,因此要用到兄弟组件的相互通信,这个时候我首先选择了bu ...
- 使用maven打包额外的jar
当使用maven打包的时候,部分自己的额外使用的在maven基础库里面是没有的时候: 参考: https://blog.csdn.net/hguisu/article/details/5107268 ...
- Hadoop Map/Reduce的工作流
问题描述 我们的数据分析平台是单一的Map/Reduce过程,由于半年来不断地增加需求,导致了问题已经不是那么地简单,特别是在Reduce阶段,一些大对象会常驻内存.因此越来越顶不住压力了,当前内存问 ...
- Asp.net 的cookie问题
写代码的发现的小问题 如果写入cookie的时候指定了domin域名 那么删除的时候必须也指定domin域名才行,即使你先读取了这个已经存在的cookie,但是还是要指定domin才能删除 /// & ...
- OD 实验(九) - 对一个程序的破解
程序: 运行程序 点击 About 这是要注册的 点击 Register 输入邮箱和注册码,点击 Register Now 逆向: 用 OD 打开程序 右键 -> 查找 -> 所有参考文本 ...
- Julia - 函数的参数传递
不定参数 不定参数的函数也称变参函数 函数的参数可以被定义成任意个 可以在最后一个参数后紧跟省略号“...”来定义变参函数 julia> bar(x, y, z...) = (x, y, z) ...
- sgdisk基本用法
简介 sgdisk是Linux下操作GPT分区的工具,就像fdisk是操作MBR分区的工具.关于GPT和MBR的区别请参考: http://www.anchor.com.au/blog/2012/10 ...