使用FreeMarker模板导出word
程序员文章站
2022-04-30 09:25:28
...
1.目标:需要导出的word内容如图,其中部分数据是需要程序动态填充的
2.将上述文档另存为xml格式,然后用notepad++(到官网下载,保证能正常安装xml tools插件)打开
3.打开的xml文件会如下显示,需要格式化
4. 为notepad++安装格式化工具插件xml tools
1)点击notepad++的菜单“插件”,接着点击选项“插件管理”,在里面寻找xml tools并安装
2)此时会有此菜单路径: “插件–>xml tools–>pretty print”,点击后会格式化xml文件为:
5.在格式化后的xml文件中定位动态word数据,然后填写相关表达式(对应后面步骤代码中的变量名称),达到的效果大致如下:
比如,在xml中定位到“名称”,然后在它后面填写“${schoolName}”代替“中南大学”,比如:
做完以上操作后,将xml文档重命名为.ftl文档
6.对于两个表格,需要用到循环表达式,比如
此处stuList对应数据为:
7.代码实现
1)引入依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
2)主要代码结构
3)工具栏以及测试函数
public class FreeMarkerUtil {
private static final String ENCODING = "UTF-8";
private static Configuration cfg = new Configuration();
//初始化cfg
static {
//设置模板所在文件夹
cfg.setClassForTemplateLoading(FreeMarkerUtil.class, "/freemarkerTemplate");
// setEncoding这个方法一定要设置国家及其编码,不然在ftl中的中文在生成html后会变成乱码
cfg.setEncoding(Locale.getDefault(), ENCODING);
// 设置对象的包装器
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 设置异常处理器,这样的话就可以${a.b.c.d}即使没有属性也不会出错
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
}
//获取模板对象
public static Template getTemplate(String templateFileName) throws IOException {
return cfg.getTemplate(templateFileName, ENCODING);
}
/**
* 据数据及模板生成文件
*
* @param data Map的数据结果集
* @param templateFileName ftl模版文件名
* @param outFilePath 生成文件名称(可带路径)
*/
public static File crateFile(Map<String, Object> data, String templateFileName, String outFilePath) {
Writer out = null;
File outFile = new File(outFilePath);
try {
// 获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致
Template template = getTemplate(templateFileName);
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
out = new OutputStreamWriter(new FileOutputStream(outFile), ENCODING);
// 处理模版
template.process(data, out);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return outFile;
}
//获得图片的base64码
public static String getImageBase(String src) throws Exception {
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);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
public static void main(String[] args) {
try {
Map<String, Object> data = new HashMap<String, Object>();
data.put("schoolName", "中南大学");
data.put("address", "湖南长沙");
data.put("cultivationLevel", "本科");
data.put("schoolType", "公办");
data.put("principal", "李泽亮");
data.put("remark", "暂无");
//表一
List<Map<String, String>> stuList = new ArrayList();
for (int i = 0; i < 3; i++) {
Map<String, String> paramMap = new HashMap();
paramMap.put("num", String.valueOf(i + 1));
paramMap.put("name", "张三");
paramMap.put("stuNum", "123");
paramMap.put("sex", "男");
paramMap.put("age", "40");
paramMap.put("nj", "一");
paramMap.put("speciality", "软件工程");
stuList.add(paramMap);
}
data.put("stuList", stuList);
// 表二
List<Map<String, String>> teaList = new ArrayList();
for (int i = 0; i < 3; i++) {
Map<String, String> paramMap2 = new HashMap();
paramMap2.put("num", String.valueOf(i + 1));
paramMap2.put("name", "王五");
paramMap2.put("jobNum", "678");
paramMap2.put("sex", "男");
paramMap2.put("age", "45");
paramMap2.put("department", "公共基础部");
teaList.add(paramMap2);
}
data.put("teaList", teaList);
//第二个参数fileName,不是filepath。文件所属path在static块中体现
crateFile(data, "school.ftl", "D:/test.docx");
} catch (Exception e) {
e.printStackTrace();
}
}
}
上一篇: matplotlib画图、标点、打标签