<!--freemarker word export-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
以上,pom文件
package com.eying.pcss.workflow.util;
import freemarker.core.ParseException;
import freemarker.log.Logger;
import freemarker.template.*;
import sun.misc.BASE64Encoder;
import java.io.*;
import java.util.Map;
/**
* @ClassName WordExport
* @Author wuyukun
* @Date 2022/8/10
* @Description 使用FreeMarker导出Word
**/
public class WordExport {
private Logger log = Logger.getLogger(WordExport.class.toString());
private Configuration config = null;
public WordExport() {
config = new Configuration(Configuration.VERSION_2_3_28);
config.setDefaultEncoding("utf-8");
}
/**
* FreeMarker生成Word
*
* @param dataMap 数据
* @param templateName 目标名(模板名称)
* @param saveFilePath 要保存的文件存放地址:全路径+文件名
*/
public File createWord(Map<String, Object> dataMap, String templateName, String saveFilePath) {
//加载模板(路径)数据
config.setClassForTemplateLoading(this.getClass(), "");
//设置异常处理器 这样的话 即使没有属性也不会出错 如:${list.name}...不会报错
config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
Template template = null;
if (templateName.endsWith(".ftl")) {
templateName = templateName.substring(0, templateName.indexOf(".ftl"));
}
try {
template = config.getTemplate(templateName + ".ftl");
} catch (TemplateNotFoundException e) {
log.error("模板文件未找到", e);
e.printStackTrace();
} catch (MalformedTemplateNameException e) {
log.error("模板类型不正确", e);
e.printStackTrace();
} catch (ParseException e) {
log.error("解析模板出错,请检查模板格式", e);
e.printStackTrace();
} catch (IOException e) {
log.error("IO读取失败", e);
e.printStackTrace();
}
File outFile = new File(saveFilePath);
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
Writer out = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outFile);
} catch (FileNotFoundException e) {
log.error("输出文件时未找到文件", e);
e.printStackTrace();
}
out = new BufferedWriter(new OutputStreamWriter(fos));
//将模板中的预先的代码替换为数据
try {
template.process(dataMap, out);
} catch (TemplateException e) {
log.error("填充模板时异常", e);
e.printStackTrace();
} catch (IOException e) {
log.error("IO读取时异常", e);
e.printStackTrace();
}
log.info("由模板文件:" + templateName + ".ftl" + " 生成文件 :" + saveFilePath + " 成功!!");
try {
out.close();//web项目不可关闭
} catch (IOException e) {
log.error("关闭Write对象出错", e);
e.printStackTrace();
}
return outFile;
}
/**
* 获得图片的Base64编码
*
* @param imgFile
* @return
* @Author
*/
public static String getImageStr(String imgFile) {
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(imgFile);
} catch (FileNotFoundException e) {
System.out.println("加载图片未找到");
// log.error("加载图片未找到", e);
e.printStackTrace();
}
try {
data = new byte[in.available()];
//注:FileInputStream.available()方法可以从输入流中阻断由下一个方法调用这个输入流中读取的剩余字节数
in.read(data);
in.close();
} catch (IOException e) {
System.out.println("IO操作图片错误");
// log.error("IO操作图片错误", e);
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
String encode = encoder.encode(data);
return encode;
}
// public static void main(String[] args) {
// WordExport emw = new WordExport();
// Map<String, Object> dataMap = new HashMap<String, Object>();
// dataMap.put("年", "2022");
// dataMap.put("季", "三");
// dataMap.put("申请部门", "中安");
// dataMap.put("人数", 10);
// dataMap.put("月份", "8");
// dataMap.put("计划费用", "10000");
// dataMap.put("费用标准", "1000");
// dataMap.put("经办人", "武昱坤");
// List<Map<String, Object>> detailList = new ArrayList<>();
// Map<String, Object> a = new HashMap<>();
// a.put("办公用品名称", "显示器");
// a.put("规格", "24寸");
// a.put("数量", "10");
// a.put("单位", "台");
// a.put("单价", "900");
// a.put("总金额", "9000");
// detailList.add(a);
// Map<String, Object> b = new HashMap<>();
// b.put("办公用品名称", "鼠标");
// b.put("规格", "逻辑G502");
// b.put("数量", "10");
// b.put("单位", "个");
// b.put("单价", "100");
// b.put("总金额", "1000");
// detailList.add(b);
// dataMap.put("detailList", detailList);
//
//
// List<Map<String, Object>> flowList = new ArrayList<>();
// String imageStr = getImageStr("C:\\Users\\武\\Desktop\\f2c8912207514b879bb3312c669b09db.jpg");
// String imageStr2 = getImageStr("C:\\Users\\武\\Desktop\\微信截图_20220811190844.jpg");
dataMap.put("签字", imageStr);
// Map<String, Object> c = new HashMap<>();
// c.put("节点名称", "部门负责人、项目总监签字");
// c.put("签字", imageStr);
// c.put("日期", "2022年8月11日10:37:39");
// flowList.add(c);
// Map<String, Object> d = new HashMap<>();
// d.put("节点名称", "办公室审核意见");
// d.put("签字", "");
// d.put("日期", "2022年8月11日10:38:01");
// flowList.add(d);
// Map<String, Object> e = new HashMap<>();
// e.put("节点名称", "分管领导意见");
// e.put("签字", "");
// e.put("日期", "2022年8月11日10:38:25");
// flowList.add(e);
// Map<String, Object> f = new HashMap<>();
// f.put("节点名称", "总经理意见");
// f.put("签字", imageStr);
// f.put("日期", "2022年8月11日10:38:45");
// flowList.add(f);
// dataMap.put("flowList", flowList);
// dataMap.put("附件", "");
// dataMap.put("备注", "这里边写的是备注");
// emw.createWord(dataMap, "办公用品购置计划表.ftl", "C:/Users/武/Desktop/最新办公用品购置表.doc");
// }
public static void main(String[] args) throws IOException {
// String imageStr = getImageStr("C:\\Users\\武\\Desktop\\f2c8912207514b879bb3312c669b09db.jpg");
// try {
// BufferedImage image = (BufferedImage)ImgUtil.rotate(ImageIO.read(FileUtil.file("C:\\Users\\武\\Desktop\\f2c8912207514b879bb3312c669b09db.jpg")), 90);
// ImgUtil.write(image, FileUtil.file("C:\\Users\\武\\Desktop\\xin.jpg"));
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
}
}
以上,工具类。
仅作为工具类备份使用。
示例DOC文件:https://download.csdn.net/download/wu1300874474/86497483
示例FTL文件:https://download.csdn.net/download/wu1300874474/86497483
导出模板制作 导出为XML后修改为 ftl 格式
1.导出方式 推荐使用.XML(包含图片情况下)。
模板内图片使用任意图片占位即可,之后修改ftl文件里边的base64 为${}占位符即可。java后台获取 base64存放至该占位处。
2.纯文字两种xml格式都可以。
3.模板内容 使用${xxx} 内容占位(可使用中文)。
4.循环标签 (多用于<tr> 标签外)
<#list detailList as item>
</#list>
5.多图片情况下注意 标签的 图片名称不能相同,否则所有图片会显示为最后一个轮循的图片。图片格式没有硬性要求。
以下为例子