近日需要将人员的基本信息导出,存储为word文档,查阅了很多资料,最后选择了使用freemarker,网上一共有四种方式,效果都一样,选择它呢是因为使用简单,再次记录一下,一个简单的demo,仅供参考。
1.引入依赖:
org.freemarker
freemarker
2.3.20
2.word工具类
package com.bfd.bose_kotwalee_screen_data.util.word;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.utility.DateUtil;
import org.apache.directory.api.util.DateUtils;
public class WordUtils {
private static Configuration configuration = null;
//class.getResource()可以获取绝对路径和相对路径
private static final String templateFolder = WordUtils.class.getResource("/templates").getPath();
static {
configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
try {
configuration.setDirectoryForTemplateLoading(new File(templateFolder));
} catch (IOException e) {
e.printStackTrace();
}
}
private WordUtils() {
throw new AssertionError();
}
public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map, String title, String ftlFile) throws IOException {
Template freemarkerTemplate = configuration.getTemplate(ftlFile);
File file = null;
InputStream fin = null;
ServletOutputStream out = null;
try {
// 调用工具类的createDoc方法生成Word文档
file = createDoc(map, freemarkerTemplate);
fin = new FileInputStream(file);
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
// 设置浏览器以下载的方式处理该文件名 + DateUtils.getDate("2019-08-29")
String fileName = title + ".doc";
response.setHeader("Content-Disposition", "attachment;filename="
.concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
out = response.getOutputStream();
byte[] buffer = new byte[512]; // 缓冲区
int bytesToRead = -1;
// 通过循环将读入的Word文件的内容输出到浏览器中
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(); // 删除临时文件
}
}
}
private static File createDoc(Map, ?> dataMap, Template template) {
String name = "sellPlan.doc";
File f = new File(name);
Template t = template;
try {
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
t.process(dataMap, w);
w.close();
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
return f;
}
}
3.service代码
public void exportSellPlan(HttpServletRequest request, HttpServletResponse response) {
Calendar calendar = Calendar.getInstance();// 取当前日期。
//图片地址
String imagePath = WordUtils.class.getResource("/img").getPath()+"/test.jpg";
//获得数据
Map map = new HashMap<>();
List> list = new ArrayList<>();
Map m;
for (int i = 0;i<3;i++){
m = new HashMap<>();
m.put("name","张三" + i);
m.put("age","" + 13 + i);
list.add(m);
}
map.put("list",list);
map.put("img",this.getImageBase(imagePath));
try {
//table.ftl为word模板
WordUtils.exportMillCertificateWord(request, response, map, "简历方案", "table.ftl");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//获得图片的base64码
@SuppressWarnings("deprecation")
public String getImageBase(String src) {
if(src==null||src==""){
return "";
}
File file = new File(src);
if(!file.exists()) {
return "";
}
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
try {
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
4.模板制作
1)制作word模板,另存为.xml文件
image.png
2)将.xml文件上传到工程中,并修改为.ftl后缀
image.png
这个路径在下面这行代码设定
private static final String templateFolder = WordUtils.class.getResource("/templates").getPath();
完成以上步骤,导出word功能就完成了。
注意:制作模板的时候,${name}绑定字段的时候在.ftl文件或被默认拆分,需要手动修改一下。封装数据的时候要和模板一一对应,数据为空的话也要添加,模板中的字段名在封装的数据必须有。