Freemarker + xml 实现Java导出word
前言
最近做了一个调查问卷导出的功能,需求是将维护的题目,答案,导出成word,参考了几种方案之后,选择功能强大的freemarker+固定格式之后的wordxml实现导出功能。导出word的代码是可以直接复用的,于是在此贴出,并进行总结,方便大家拿走。
实现过程概览
先在word上,调整好自己想要的样子。然后存为xml文件。保存为freemarker模板,以ftl后缀结尾。将需要替换的变量使用freemarker的语法进行替换。最终将数据准备好,和模板进行渲染,生成文件并返回给浏览器流。
详细的实现过程
准备好word的样式
我们新建一个word,我们应该使用Microsoft office,如果使用wps可能会造成样式有些不兼容。在新建的office中,设置好我们的表格样式。我们的调查问卷涉及到四种类型,单选,多选,填空,简答。我们做出四种类型的示例。

样式没有问题后,我们选择另存为word xml 2003版本。将会生成一个xml文件。

格式化xml,并用freemarker语法替换xml
我们可以先下载一个工具 firstobject xml editor,这个可以帮助我们查看xml,同时方便我们定位我们需要改的位置。
复制过去之后,按f8可以将其进行格式化,左侧是标签,右侧是内容,我们只需要关注w:body即可。

像右侧的调查问卷这个就是个标题,我们实际渲染的时候应该将其进行替换,比如我们的程序数据map中,有title属性,我们想要这里展示,我们就使用语法${title}即可。

freemarker的具体语法,可以参考freemarker的问题,在这里我给出几个简单的例子。
比如我们将所有的数据放置在dataList中,所以我们需要判断,dataList是不是空,是空,我们不应该进行下面的逻辑,不是空,我们应该先循环题目是必须的,答案是需要根据类型进行再次循环的。语法参考文档,这里不再赘述。
程序端引入freemarker
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
将我们的flt文件放在resources下的templates下。
后端代码实现
此代码可以复用,在此贴出
public class WordUtils {
private static Configuration configuration = null;
private static final String templateFolder = WordUtils.class.getClassLoader().getResource("").getPath()+"/templates/word";
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
configuration.setDirectoryForTemplateLoading(new File(templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Description:导出word,传入request,response,map就是值,title是导出问卷名,ftl是你要使用的模板名
*/
public static void exportWord(HttpServletRequest request, HttpServletResponse response, Map map, String title, String ftlFile) throws Exception {
Template freemarkerTemplate = configuration.getTemplate(ftlFile);
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
file = createDocFile(map,freemarkerTemplate);
fin = new FileInputStream(file);
String fileName = title + ".doc";
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
response.setHeader("Content-Disposition", "attachment;filename="
+fileName);
out = response.getOutputStream();
byte[] buffer = new byte[512];
int bytesToRead = -1;
while((bytesToRead = fin.read(buffer)) != -1) {
out.write(buffer, 0, bytesToRead);
}
}finally {
if(fin != null) fin.close();
if(out != null) out.close();
if(file != null) file.delete();
}
}
/**
* @Description:创建doc文件
*/
private static File createDocFile(Map<?, ?> dataMap, Template template) {
File file = new File("init.doc");
try {
Writer writer = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
template.process(dataMap, writer);
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
}
有了工具类后,我们准备好我们的map数据。map里面的数据大家可以自行定义。然后调用utils中的导出方法即可。
WordUtils.exportWord(request, response, dataMap, "word", "demo.ftl");
结语
至此已经结束了,十分的好用,有疑问的话,可以评论交流。
Freemarker + xml 实现Java导出word的更多相关文章
- java导出word的6种方式(复制来的文章)
来自: http://www.cnblogs.com/lcngu/p/5247179.html 最近做的项目,需要将一些信息导出到word中.在网上找了好多解决方案,现在将这几天的总结分享一下. 目前 ...
- java导出word文件
java导出word文件 test5.ftl文件生存方法, 第一步:用word新建test5.doc,填写完整模板,将需导出数据用${}代替 第二步:将test5.doc另存为test5.xml 第三 ...
- [转载]java导出word的5种方式
在网上找了好多天将数据库中信息导出到word中的解决方案,现在将这几天的总结分享一下.总的来说,java导出word大致有5种解决方案: 1:Jacob是Java-COM Bridge的缩写,它在Ja ...
- [原创]java导出word的5种方式
在网上找了好多天将数据库中信息导出到word中的解决方案,现在将这几天的总结分享一下.总的来说,java导出word大致有5种解决方案: 1:Jacob是Java-COM Bridge的缩写,它在Ja ...
- java导出word的6种方式(转发)
来自: http://www.cnblogs.com/lcngu/p/5247179.html 最近做的项目,需要将一些信息导出到word中.在网上找了好多解决方案,现在将这几天的总结分享一下. 目前 ...
- java对word文档的操作(提取标题和内容等)-直接操作或poi工具包或freemarker+xml或html转word
1,java自带工具包实现对word的排版和写入 import java.awt.Color; import java.io.FileNotFoundException; import java.io ...
- java导出word直接下载
导出word工具类 package util; import java.io.IOException; import java.io.Writer; import java.util.Map; imp ...
- WordUtil java导出word工具类
import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedWriter ...
- java 导出word 并下载
记录一下导出操作 源码: /************ * 导出word 并下载 * @param id 房号记录编号 * ***********************/ @RequestMappin ...
随机推荐
- 个人考场VIM配置
前言 这个是我个人使用的Vim配置.双引号杠掉的部分是关于光标行列高亮(觉得难受而杠)和输入左括号同时打上右括号的(不习惯),如果要启用的话去掉引号即可. 将以下要启用的输入到$“./vimrc”$中 ...
- ElasticSearch - ElasticSearch和kinaba的简单使用
ElasticSearch和kinaba的简单使用 ElasticSeatch 文档推荐 ElasticSearch 下载 (端口 9200) 安装好es,可以访问 http://localhost: ...
- windows设置本地域名解析
1.首先找到host文件:C:\Windows\System32\drivers\etc 2.打开host文件: # Copyright (c) 1993-2009 Microsoft Corp. # ...
- Veins(车载通信仿真框架)入门教程
Veins入门教程——教你如何下手研究 目录 Veins入门教程——教你如何下手研究 目录 废话少说! 讲解omnetpp.ini!(挑关键的) 讲解RSUExampleScnario.ned! 注意 ...
- 死磕 java线程系列之线程池深入解析——普通任务执行流程
(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...
- 设计模式C++描述----06.适配器(Adapter)模式
一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...
- 怎么用Vuecli 3.0快速创建项目
一.安装 1.安装node.js,这里需要注意的是,Vue CLI 3需要 nodeJs ≥ 8.9,所以我们去中文官方下载地址:http://nodejs.cn/download/,下载最新版本即可 ...
- 面经-VIVO
面试时间:2019.09.26 现场面试 面试岗位:广告推荐算法工程师/一面/正式批 面试时长:50Min 面试内容: 自我介绍 阶乘与阶乘和(复杂度高) 文本-视频论文讲解 视频排序讲解 概率题(2 ...
- 知否知否,VS Code 不止开源
VS Code, 昨夜始于“开源”,如今“开源”深处渡. 读者看到这句话,也许会有疑惑,为什么两个“开源”都加上了双引号? 其实是笔者有意为之,因为这个两个“开源”的意义有着很大的差别,第一个“开源” ...
- 前端与算法 leetcode 26. 删除排序数组中的重复项
目录 # 前端与算法 leetcode 26. 删除排序数组中的重复项 题目描述 概要 提示 解析 算法 # 前端与算法 leetcode 26. 删除排序数组中的重复项 题目描述 26. 删除排序数 ...