概述

最近一个项目要导出word文档,折腾老半天,发现还是用freemarker的模板来搞比较方便省事,现总结一下关键步骤,供大家参考,这里是一个简单的试卷生成例子。

详细

最近一个项目要导出word文档,折腾老半天,发现还是用freemarker的模板来搞比较方便省事,现总结一下关键步骤,供大家参考,这里是一个简单的试卷生成例子。

一、模板的制作

先用Word做一个模板,如下图:

(注意,上面是有表格的,我设置了边框不可见)然后另存为XML文件,之后用工具打开这个xml文件,有人用firstobject XML Editor感觉还不如notepad++,我这里用notepad++,主要是有高亮显示,和元素自动配对,效果如下:

上面黑色的地方基本是我们之后要替换的地方,比如xytitle替换为${xytitle},对已表格要十分注意,比如选择题下面的表格,我们可以通过<w:tr>查找来定位,一对<w:tr></w:tr>代表一行,也就是一条记录(一道题),我们这里要用一对<#list></#list>来将其包括,以便后续填充数据,具体可参照Freemarker页面语法,例如这里选择题,我们是两行为一条记录,所以要<#list></#list>要包括两行,形如:<#list table1 as plan1><w:tr>题号 题目</w:tr><w:tr>选项</w:tr></#list>,然后在这其中找着对应的xzn,xztest,ans1,ans2,ans3,ans4替换为${plan1.xzn},${plan1.xztest},${plan1.ans1},${plan1.ans2},${plan1.ans3},${plan1.ans4},注意这里的table1及plan1命名,table1后续填充数据要用到,其他的替换同理操作,得到效果如下:

保存后,修改后缀名为ftl,至此模板制作完毕。

二、编程实现

这里用到了freemarker-2.3.13.jar包,代码如下:

package common;  

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Map; import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException; public class DocumentHandler { private Configuration configuration = null; public DocumentHandler() {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
} public void createDoc(Map<String,Object> dataMap,String fileName) throws UnsupportedEncodingException {
//dataMap 要填入模本的数据文件
//设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载,
//这里我们的模板是放在template包下面
configuration.setClassForTemplateLoading(this.getClass(), "/template");
Template t=null;
try {
//test.ftl为要装载的模板
t = configuration.getTemplate("fctestpaper.ftl");
} catch (IOException e) {
e.printStackTrace();
}
//输出文档路径及名称
File outFile = new File(fileName);
Writer out = null;
FileOutputStream fos=null;
try {
fos = new FileOutputStream(outFile);
OutputStreamWriter oWriter = new OutputStreamWriter(fos,"UTF-8");
//这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。
//out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
out = new BufferedWriter(oWriter);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} try {
t.process(dataMap, out);
out.close();
fos.close();
} catch (TemplateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} //System.out.println("---------------------------");
}
}

然后是准备数据调用就行,代码如下:

package com.havenliu.document;  

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class Main { /**
* @param args
* @throws UnsupportedEncodingException
*/
public static void main(String[] args) throws UnsupportedEncodingException {; Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("xytitle", "试卷");
int index = 1;
// 选择题
List<Map<String, Object>> list1 = new ArrayList<Map<String, Object>>();//题目
List<Map<String, Object>> list11 = new ArrayList<Map<String, Object>>();//答案
index = 1;
for (int i = 0; i < 5; i++) { Map<String, Object> map = new HashMap<String, Object>();
map.put("xzn", index + ".");
map.put("xztest",
"( )操作系统允许在一台主机上同时连接多台终端,多个用户可以通过各自的终端同时交互地使用计算机。");
map.put("ans1", "A" + index);
map.put("ans2", "B" + index);
map.put("ans3", "C" + index);
map.put("ans4", "D" + index);
list1.add(map); Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("fuck", index + ".");
map1.put("abc", "A" + index);
list11.add(map1); index++;
}
dataMap.put("table1", list1);
dataMap.put("table11", list11); // 填空题
List<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>();
List<Map<String, Object>> list12 = new ArrayList<Map<String, Object>>();
index = 1;
for (int i = 0; i < 5; i++) { Map<String, Object> map = new HashMap<String, Object>();
map.put("tkn", index + ".");
map.put("tktest",
"操作系统是计算机系统中的一个___系统软件_______,它管理和控制计算机系统中的___资源_________.");
list2.add(map); Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("fill", index + ".");
map1.put("def", "中级调度" + index);
list12.add(map1); index++;
}
dataMap.put("table2", list2);
dataMap.put("table12", list12); // 判断题
List<Map<String, Object>> list3 = new ArrayList<Map<String, Object>>();
List<Map<String, Object>> list13 = new ArrayList<Map<String, Object>>();
index = 1;
for (int i = 0; i < 5; i++) { Map<String, Object> map = new HashMap<String, Object>();
map.put("pdn", index + ".");
map.put("pdtest",
"复合型防火墙防火墙是内部网与外部网的隔离点,起着监视和隔绝应用层通信流的作用,同时也常结合过滤器的功能。");
list3.add(map); Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("judge", index + ".");
map1.put("hij", "对" + index);
list13.add(map1); index++;
}
dataMap.put("table3", list3);
dataMap.put("table13", list13); // 简答题
List<Map<String, Object>> list4 = new ArrayList<Map<String, Object>>();
List<Map<String, Object>> list14 = new ArrayList<Map<String, Object>>();
index = 1;
for (int i = 0; i < 5; i++) { Map<String, Object> map = new HashMap<String, Object>();
map.put("jdn", index + ".");
map.put("jdtest", "说明作业调度,中级调度和进程调度的区别,并分析下述问题应由哪一级调度程序负责。");
list4.add(map); Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("answer", index + ".");
map1.put("xyz", "说明作业调度,中级调度和进程调度的区别,并分析下述问题应由哪一级调度程序负责。");
list14.add(map1); index++;
}
dataMap.put("table4", list4);
dataMap.put("table14", list14); MDoc mdoc = new MDoc();
mdoc.createDoc(dataMap, "E:/outFile.doc");
} }

注意上面map中的key必须和模板中的对应,否则会报错。

三、项目导入

下载附件后,解压后,看到如下目录

将Document项目导入eclipse即可。导入后的效果如下:

会在e盘生成文件

四、运行效果

打开生成的outFile.doc则看到如下的样子:

五、freemarker语法

Freemarker页面语法:http://blog.csdn.net/thismonth/article/details/5194982

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

Java用freemarker导出word的更多相关文章

  1. Java使用freemarker导出word文档

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

  2. Java用freemarker导出Word 文档

    1.用Microsoft Office Word打开word原件: 2.把需要动态修改的内容替换成***,如果有图片,尽量选择较小的图片几十K左右,并调整好位置: 3.另存为,选择保存类型Word 2 ...

  3. Java使用freemarker导出word和excel

    www.linxiaosheng.com/post/2013-12-05/40060346181 https://github.com/upyun/java-sdk

  4. java用freemarker导出数据到word(含多图片)

    一.制作word模版 新建word文档,按照需要设置好字体等各种格式:这里为了显得整齐使用了无边框的表格. 将word文档另存为xml文件(注意不是word xml文档,我吃了这家伙的大亏了) 然后用 ...

  5. 关于使用freemarker导出word

    java使用FreeMarker导出word 一.      先做一个word模板 二.      将该word文件另存为xml格式(注意是另存为,不是直接改扩展名) 三.     打开xml文件把要 ...

  6. freemarker导出word带图片

    导出word带图片 如果你需要在word中添加图片,那你就在第一步制作模板时,加入一张图片占位,然后打开xml文档,可以看到如下的一片base64编码后的代码: <w:binData w:nam ...

  7. freemarker导出word档

    1.word另存为xml:2.xml文件后缀名改成ftl:3.编写完整json字符串备用:4.修改ftl中动态字段为json中对应字段名:5.编写java代码自动生成word文件:(注意:换行用< ...

  8. 使用Freemarker导出Word文档(包含图片)代码实现及总结

    .personSunflowerP { background: rgba(51, 153, 0, 0.66); border-bottom: 1px solid rgba(0, 102, 0, 1); ...

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

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

随机推荐

  1. QT TCP网络编程

    首先介绍一下TCP:(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议.相比而言UDP,就是开放式.无连接.不可靠的传输层 ...

  2. 第二章 IOC + AOP 底层原理

    <精通Spring4.x 企业应用开发实战>读书笔记 一.概念 IOC: 假设B类调用了A类,那么A类的对象的创建是由B类来实现: IOC是指将A对象的创建由容器来完成,并且将创建好的对象 ...

  3. C#窗体读取EXCEL存入SQL数据库

    windows窗体上放了一个Textbox1,2个按钮button1和button2~按button1选择excel文件~按button2进行相关处理 Code Snippet private  vo ...

  4. .NET 常用加密、解密& 数字签名算法

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Run ...

  5. wifidog接口文档(转)

    目录(?)[-] 网关心跳协议 请求信息 回复格式 例子 用户状态心跳协议 请求格式 注意 回复格式 状态码 例子 跳转协议 请求格式 例子 注册协议 请求格式 例子 wifidog是搭建无线热点认证 ...

  6. 一个ActiveX control的创建过程

    创建 根据这篇文章的介绍:http://www.cnblogs.com/time-is-life/p/6354152.html 来创建,里面包含了创建的基本过程以及属性事件方法的使用. 使用: 参考文 ...

  7. BitNami

    BitNami 提供wordpress.joomla.drupal.bbpress等开源程序的傻瓜式安装包下载,所有的安装包内置了服务器环境,就是说,不需要在本地 电脑上另外搭建服务器,就可以一次性傻 ...

  8. [Angular] Use Angular components in AngularJS applications with Angular Elements

    When migrating AngularJS (v1.x) applications to Angular you have different options. Using Angular El ...

  9. Asp.NET websocket,Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)

    ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及 ...

  10. 大量带BPM的跑步歌曲/跑步音乐下载

    20150110停止更新告知:不知不觉本帖更新有近半年了.从最开始跑步已经四年多,一直是听着音乐跑的,音乐支持.陪伴.丰富着我的跑步之旅.直到上个月因一次觉得音乐吵,我开始有意地摘掉耳机去跑步,并开始 ...