前言

最近做了一个调查问卷导出的功能,需求是将维护的题目,答案,导出成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");

结语

至此已经结束了,十分的好用,有疑问的话,可以评论交流。

最新文章

  1. Gulp基础
  2. java实现支付宝接口--文档..转载
  3. 2016huasacm暑假集训训练四 _排列
  4. Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0
  5. BitTorrent Sync - 神奇的文件同步软件,无需服务器让多台电脑互相同步!
  6. Python For Data Analysis -- NumPy
  7. Win7下 httpRequest带证书请求https网站
  8. ASP.NET MVC 从IHttp到页面输出
  9. SqlServer 由于未在SqlServer的此实例上安装复制组件解决方法
  10. easyui combobox赋值
  11. EOF 空格问题
  12. android开发中应该注意的问题
  13. sql语句中生成0-10随机数
  14. mysql数据库导入sql文件时提示“Error Code: 1153 - Got a packet bigger than &#39;max_allowed_packet&#39; bytes”解决办法
  15. php 计算两点地理坐标的距离
  16. Yii2.0调用sql server存储过程并获取返回值
  17. JavaScript使用jsonp实现跨域
  18. Android学习指南之三十八:Android手势操作编程[转]
  19. 月薪20K软件测试自动化岗必问面试题:验证码识别与处理
  20. 使用XML Publisher导出PDF报表

热门文章

  1. ride.py打不开RF,而是打开pycharm
  2. MOOC C++笔记(七)输入输出流
  3. 在.Net Core 3.0中尝试新的System.Text.Json API
  4. R的安装
  5. 设计模式C++描述----06.适配器(Adapter)模式
  6. vue中改变数组的值视图无变化
  7. day4-01 流程控制
  8. 【原创】go语言学习(十一)package简介
  9. 《Effective Java》 读书笔记(四) 使用私有构造方法执行非实例化
  10. 【XSY2495】余数