import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;
public class AnnualReportUtil {
private Configuration configuration =null;
public AnnualReportUtil(){
configuration=new Configuration();
configuration.setDefaultEncoding("UTF-8");
}
/**
* 生成插入数据后的Word文件
* @param filename:目标文件名(要带上后缀名)
* @param response:
* @param data:要写入的数据
*/
public void exportAnnualReport(String filename,HttpServletResponse response, Map<String,Object> data){
/**
* 获取年报模板的路径
*/
String annualReportTemplete="test.ftl";
String dir=System.getProperty("user.dir");
String annualReportPath=dir + File.separator+"src"+File.separator+"main"+File.separator+"resources"+File.separator+"templates";
/**
* 流下载
*/
BufferedInputStream inputStream=null;
BufferedOutputStream outputStream=null;
try{
//获取写入数据后的文件
File file=writeAnnualReport(annualReportPath,annualReportTemplete,filename,data);
response.reset();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/msword");//设置内容类型为Word格式
response.setHeader("Content-Disposition","attachment; filename="+ URLEncoder.encode(filename,"UTF-8"));
inputStream=new BufferedInputStream(new FileInputStream(file));
outputStream=new BufferedOutputStream(response.getOutputStream());
byte[] buffer=new byte[inputStream.available()+1024];
int num=0;
/**
* 将数据读取到缓冲区中,再将缓冲区中数据传输出去
*/
while((num=inputStream.read(buffer))!=-1){
outputStream.write(buffer,0,num);
}
inputStream.close();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @param templetePath:模板文件路径
* @param templeteName:模板文件名
* @param filename:目标文件名
* @param data:要写入模板文件的数据
*/
public File writeAnnualReport(String templetePath,String templeteName,String filename,Map<String,Object> data){
/**
* 加载模板
*/
File file=new File(filename);
try {
configuration.setDirectoryForTemplateLoading(new File(templetePath));//设置模板加载路径
Template templete=configuration.getTemplate(templeteName);
//构造一个向目标文件写的流
Writer writer=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"utf-8"));
//将数据填充到模板并写入目标文件
templete.process(data,writer);
//写完关闭流
writer.close();
} catch (IOException e) {
e.printStackTrace();
}catch (TemplateException e){
e.printStackTrace();
}
return file;
}
/**
* 获取图片数据,并对数据进行BASE64编码
* @param url:图片的存储全路径地址
* @return
*/
public static String getImageBase64Code(String url) {
String code = null;
byte[] codeData = null;
BASE64Encoder encoder = new BASE64Encoder();
InputStream in = null;
try {
in = new FileInputStream(url);
codeData = new byte[in.available()];
in.read(codeData);
in.close();
code = encoder.encode(codeData);
} catch (IOException e) {
logger.error(e.getMessage());
} catch (Exception e) {
logger.error(e.getMessage());
}
return code;
}
这是数据格式,其中year就是要插入文档中的${year}.
Map<String,Object> data=new HashMap<>();
data.put("year","2019");
data.put("region","雄安");
注意,需要在pom中导入freemarker依赖的包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
一、将Word另存为xml形式
1、将Word中要替换的数据用“{}”阔起来:如下图所示:
2、所有要替换的数据都改为这种形式(括号中数据为要替换的数据,最好用英文,不要问为什么)。
3、然后,将替换后的Word另存为.xml形式。
二、将xml文件重命名为ftl格式
1、在将另存的xml文件重命名为.ftl格式
2、用文本编辑器(我用的是Notepad++)打开.ftl文件。(使用到了一个格式化的插件,这样阅读起来会比较方便)
3、找到文件中所有用“{}”括起来的数据(你要替换的数据),在{}面前加上“$”符号。如下图:
全部修改后保存即可。对于还要插入图片的,可以将.ftl中图片生成的base64码删除,用同样的格式替换,如${image};
图片的base64码如下图:
替换的格式如下图:
4、将修改好的模板文件(.ftl文件)放入你的工程目录中。(这里笔者用的是spring boot框架,我将模板文件放在了resource/templetes目录下)。