打开word写word 模板
将此模板另存为 xml
关闭word用notepad++打开精工发货通知单.xml格式化
搜索替换变量字段为${变量字段},图片部分base64值删掉也替换
替换后如下:
额外部分(懒得找遍历):
如果有表格需要遍历显示的,找到对应需要遍历的行,在外层用<#list ? as row ></#list>进行包围,遍历的行用 ${row.?}来替换,如下图所示:
将发货通知单.xml改成pfmb.ftl,并存放在项目templates下
引入freemarker依赖
书写WordUtil 工具类
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import sun.misc.BASE64Encoder;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class WordUtil {
private Configuration configuration = null;
public WordUtil() {
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
}
/**
* 导出word 并提供下载
* @param response
*/
public void download(HttpServletResponse response) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
File file = createDoc();
String fileName = "发货通知单.doc";
response.setContentType("application/msword;charset=utf-8");
response.addHeader("Content-Disposition", "attachment; filename=\""
+ new String(fileName.getBytes(),"iso-8859-1") + "\"");
bis = new BufferedInputStream(new FileInputStream(file));
bos = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[10240];
int bytesRead;
while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
bis.close();
bos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将文本信息转为word输出
* @throws Exception
*/
public File createDoc() throws Exception {
Map<String,Object> dataMap = new HashMap<>();
getData(dataMap); //创建数据
// configuration.setClassForTemplateLoading(this.getClass(), "templates"); //模板文件所在路径
configuration.setDirectoryForTemplateLoading(new File(WordUtil.class
.getProtectionDomain().getCodeSource().getLocation().getPath() + "templates"));
Template t = null;
String fileName = "发货通知单.doc";
File file = new File(fileName);
try {
t = configuration.getTemplate("pfmb.ftl"); //获取模板文件
t.setEncoding("utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName),"utf-8"));
t.process(dataMap, out); //将填充数据填入模板文件并输出到目标文件
out.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
return file;
}
//获得数据
private void getData(Map<String,Object> dataMap) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:SS");
dataMap.put("djbh", "PF1000001");
dataMap.put("rq", sdf.format(new Date()));
dataMap.put("khdm", "wh01");
dataMap.put("khmc", "武汉一号");
String image = getBase64("C:\\Users\\Minco\\Desktop\\photo\\1.jpg");
dataMap.put("img", image);
}
/***
* 处理图片
* @param watermarkPath 图片路径
* @return
*/
private String getBase64(String watermarkPath) {
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(watermarkPath);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
//对图片进行编码
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
}
控制层调用
@ResponseBody
@RequestMapping(value = "/download")
public void downloadInfo(HttpServletResponse response) throws Exception{
WordUtil wd = new WordUtil();
wd.download(response);
}
完成,展示成果
小经验:
notepad++是插件化的工具,很多功能需要下载插件使用
复制文件到IDEAresources目录下,target里是不会自动去加载的,除非是clean重新发布,或者是CTRAL+F9加载资源文件
word模板制作的时候${}这个是不好先打上的,wordXML会把他们拆分开,就不符合freemarker的模板规范,所以只有在wordxml生成之后再进行替换