@[TOC]
一、根据模板导出word
1、需要的包
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.32</version>
</dependency>
2、准备word文档
1.用Microsoft Office Word打开word原件;
2.把需要动态修改的内容替换成${XX}的形式,如果有图片,尽量选择较小的图片几十K左右的小图片,并调整好位置,占位(小图片转换的base64数据少,便于修改);如下图
3.另存为,选择保存类型Word 2003 XML 文档(*.xml)【这里说一下为什么用Microsoft Office Word打开且要保存为Word 2003XML,本人亲测,用WPS找不到Word 2003XML选项,如果保存为Word XML,会有兼容问题,避免出现导出的word文档不能用Word 2003打开的问题】,保存的文件名不要是中文
4.用notepad++打开文件;
5.将文档内容中需要动态修改内容的地方,换成freemarker的标识。其实就是Map<String, Object>中key,如${landName};
6.在加入了图片占位的地方,会看到一片base64编码后的代码,把base64替换成${image},也就是Map<String, Object>中key,值必须要处理成base64;
代码如:<w:binData w:name="wordml://自定义.png" xml:space="preserve">${xx}</w:binData>
注意:“>${xx}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。
如果需要循环,则使用:<#list maps as map></#list> maps是Map<String, Object>中key,值为数组,map为自定义;
7.标识替换完之后,模板就弄完了,另存为.ftl后缀文件即可。注意:一定不要用word打开ftl模板文件,否则xml内容会发生变化,导致前面的工作白做了。把最开始得到的doc模板文件和ftl文件放在同一级目录下
3、编码
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.codec.binary.Base64;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WordUtil {
public static void main(String[] args) {
try {
// 创建FreeMarker配置,参数是包版本号
Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
cfg.setClassForTemplateLoading(WordUtil.class, "/"); // 会找到项目路径下
cfg.setDefaultEncoding("UTF-8");
// 加载模板文件
Template template = cfg.getTemplate("template/test.ftl");
Map<String, Object> data = new HashMap<>();
data.put("name", "张三");
data.put("age", "18");
data.put("weather", "晴朗");
// 图片需要转为base64
data.put("img", getImgStr("E:\\netty.png"));
data.put("major", "打电玩");
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> m1 = new HashMap<>();
m1.put("like", "篮球");
list.add(m1);
Map<String, String> m2 = new HashMap<>();
m2.put("like", "足球");
list.add(m2);
data.put("list", list);
// 生成Word文件
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
// utf-8是一定要加的!
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\\output.doc"), "utf-8"));
template.process(data, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将图片转换成Base64编码
*
* @param imgFile
* 待处理图片
* @return
*/
public static String getImgStr(String imgFile) {
// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
InputStream in = null;
byte[] data = null;
// 读取图片字节数组
try {
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return new String(Base64.encodeBase64(data));
}
}
4、坑
注意,要按照顺序生成ftl文件!否则会有兼容性问题!
https://blog.csdn.net/qq_35222232/article/details/100337967
生成的文件扩展名为doc!不是docx!如果扩展名改为docx的话,office打不开,但是wps能打开!
【重磅推荐!免费简单内网穿透神器!支持linux+windows】
推荐内网穿透神器【cpolar】www.cpolar.com/ 点击【免费注册】之后,输入自己的个人信息就可以注册一个账号啦! 本地web项目如何使用外网访问?教你轻松使用cpolar在windows搭建内网穿透 linux虚拟机部署的web项目如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透 linux虚拟机部署的MySQL如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透