一、前言
1、本教程主要内容
- 一般情况下项目在docke环境上部署会出现路径找不到的情况,解决项目打包后模板文件路径丢失找不到,通过结合FreeMarker进行模板文件下载。
- 主要解决过于复杂的模板文件通过动态生成较难实现
- 可用于模板文件下载
- 通过一个报告模板转成模板文件对数据进行填充转换下载
2、需要用到的包
- 环境信息
软件 | 版本 |
---|---|
freemarker | 2.3.26-incubating |
- 适用范围
二、操作流程
1、准备模板文件
- 可以是word,excel等可以转换为xml格式的文件
转xml文件后将文件名后缀格式改为.ftl格式,用与FreeMarker转换
2、读取模板文件进行下载
public void downTemplate(HttpServletResponse response){
Map<String,Object> dataModel=new HashMap<>();
try{
Map<String,Object> dataModel=new HashMap<>();
//此处需要对模板中填充数据就给dataModel加值
//下载后显示的文件名称和格式
String fileName= "下载模板.xls";
//指定文件类型 此项可不设置
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding(Charsets.UTF_8.name());
response.setHeader("Content-Disposition","attachment;filename="+fileName);
//加载模板
Template template= WordTool.generateWord("template.ftl");
//response的writer不需要外面手动关闭,tomcat会帮外面关闭
template.process(dataModel,response.getWriter());
}catch (Exception e){
log.error(BizCodeEnume.DOWNLOAD_TEMPLATE_READ_FAILED.getMsg()+e.getMessage());
throw new SOException(BizCodeEnume.DOWNLOAD_TEMPLATE_READ_FAILED);
}
}
2、所用到的工具类
package com.south.common.utils;
import com.south.common.exception.BizCodeEnume;
import com.south.common.exception.SOException;
import freemarker.core.XMLOutputFormat;
import freemarker.template.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* Word文档工具类
*/
@Slf4j
public final class WordTool {
private WordTool(){
}
/**
* 使用FreeMarker自动生成Word文档
* @param tempFileName
* @return
*/
public static Template generateWord(String tempFileName){
//设置FreeMarker的版本和编码格式
Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
configuration.setDefaultEncoding("UTF-8");
//设置加载模板(路径)数据
configuration.setClassForTemplateLoading(WordTool.class,"/templates");
configuration.setLogTemplateExceptions(false);
configuration.setOutputFormat(XMLOutputFormat.INSTANCE);
//设置异常处理器这样的话即使没有属性也不会出错如:${list.name}...不会报错
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
//设置FreeMarker生成Word文档所需要的模板
Template template=null;
if(tempFileName.endsWith(".ftl")){
tempFileName=tempFileName.substring(0,tempFileName.indexOf(".ftl"));
}
try{
template=configuration.getTemplate(tempFileName+".ftl","UTF-8");
}catch (TemplateNotFoundException e){
e.printStackTrace();
throw new SOException(BizCodeEnume.DOWNLOAD_TEMPLATE_NOTFOUND);
}catch (MalformedTemplateNameException e){
e.printStackTrace();
throw new SOException(BizCodeEnume.DOWNLOAD_TEMPLATE_TYPE_ERROR);
}catch (IOException e){
e.printStackTrace();
throw new SOException(BizCodeEnume.DOWNLOAD_TEMPLATE_READ_FAILED);
}
return template;
}
public static String getImageStr(String imgFile){
InputStream in =null;
byte[] data=null;
try{
in=new FileInputStream(imgFile);
}catch (FileNotFoundException e){
log.error("加载图片未找到",e);
e.printStackTrace();
}
try{
data=new byte[in.available()];
//FileInputStream.available()方法可以从输入流中阻断由下一方法调用这个输入流中读取的剩余字节数
in.read(data);
in.close();
}catch (IOException e){
log.error("IO操作图片错误",e);
e.printStackTrace();
}
return Base64.encodeBase64String(data);
}
}
注意这里读取的是resource下templates位置下的文件
三、生成报告文件实列
Controller
模板转换方法
制作ftl模板文件
1.首先通过world制作一个world格式的模板文件
2.将world格式模板文件另存为xml
3.将xml格式后缀名改为ftl格式
4.编辑里面的内容将数据按指定格式替换
读取生成数据列表形式