关于通过Java来生成word文档的代码实现,使用的技术为FreeMarker
1 动态生成Word
1.1 数据准备
- 准备需要的数据,封装为一个Map集合
- 例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44public class MetaData {
//类
public static class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* 获取数据
* @return Map<String, Object>
*/
public static Map<String, Object> getData() {
Map<String, Object> data = new HashMap<>();
data.put("single", "歪比巴卜");
data.put("class", new Person("莱特雷", 18));
List<String> arr = new ArrayList<>();
arr.add("hello");
arr.add("world");
arr.add("!");
data.put("arr", arr);
return data;
}
}
1.2 根据数据创建模板
- (1)创建word模板,用
${数据名(key)}
,来动态获取数据
- (2)另存为xml格式
1.3 修改xml
- (1)格式化xml
- 导出的xml都挤在一起,十分的难看,可以对xml进行格式化(本人使用VS Code来对xml进行格式化)
- (2)修改xml
- word文档转xml会将我们的
${xxxx}
数据进行拆分,需要我们自己合并回去
- (3)特殊处理List集合数据
- (4)修改后缀名为ftl
- xml文件修改完毕后,将后缀名修改为ftl文件即可
1.4 创建Word工具类
- (1)依赖导入
1
2
3
4
5
6<!-- FreeMarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
- (2)word工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51public class WordUtil {
//编码格式
private static final String ENCODING = "UTF-8";
//模板路径(按自己实际情况填写)
private static final String TEMPLATE = "/ftl/templates/word";
//模板配置
private static final Configuration CFG = new Configuration(Configuration.VERSION_2_3_22);
//初始化
static {
//设置模板所在文件夹
CFG.setClassForTemplateLoading(WordUtil.class, TEMPLATE);
// setEncoding这个方法一定要设置国家及其编码,不然在ftl中的中文在生成html后会变成乱码
CFG.setEncoding(Locale.getDefault(), ENCODING);
// 设置异常处理器,这样的话就可以${a.b.c.d}即使没有属性也不会出错
CFG.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
}
/**
* 根据数据及模板生成word文件写入输出流
* @param data Map的数据结果集
* @param templateFileName ftl模版文件名
* @param outputStream 生成文件名称(可带路径)
*/
public static void create(Map<String, Object> data, String templateFileName, OutputStream outputStream) throws Exception {
//获取自定义ftl模板
Template template = CFG.getTemplate(templateFileName, ENCODING);
//封装输出流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
//动态生成word,写入输出流
template.process(data, outputStreamWriter);
}
/**
* 设置response为下载word文件格式
* @param response 响应
* @param fileName 文件名
*/
// public static void setWordResponse(HttpServletResponse response, String fileName) throws Exception{
// //设置response格式
// response.setCharacterEncoding(ENCODING);
// response.setContentType("application/msword");
// fileName = URLEncoder.encode(fileName, "UTF-8"); // 防止中文乱码
// response.setHeader("content-disposition", "attachment;filename=" + fileName + ".doc");
// }
}
- (3)测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void wordTest() throws Exception{
//模板名
String ftlName = "wordTemplate.ftl";
//导出word路径
String outputFile = "./src/main/resources/my.doc";
//数据
Map<String, Object> data = MetaData.getData();
//输出流
OutputStream outputStream = new FileOutputStream(outputFile);
//调用工具类生成word文档
WordUtil.create(data, ftlName, outputStream);
}