ftl是Freemarker模板的文件后缀名
FreeMarker其实是一种比较简单的网页展示技术,说白了就是网页模板和数据模型的结合体。这种结合模式的好处就是,分离了网页界面设计人员和编程人员的工作,让他们各司其职。
FreeMarker大致的工作方式是,网页模板里面嵌入了数据模型中的数据、FreeMarker自定义流程控制语言、FreeMarker自定义的操作函数等等,在装载网页的时候,FreeMarker模板自动从数据模型中提取数据,并解释整个网页为我们熟知的HTML页面。
在B/S程式设计中,常常有美工和程序员二个角色,他们具有不同专业技能:美工专注于表现——创建页面、风格、布局、效果等等可视元素;而程序员则忙于创建程式的商业流程,生成设计页面要显示的数据等等。
模板引擎就是为了解决上面的问题而产生的。在设计HTML的时候,我们加入一些特定指令来指定要插入哪些数据,这些加了特殊指令的HTML或者其他文本,称为模板(Template)。而模板引擎会在输出页面时,用适当的数据替代这些代码,模板和嵌入JSP的HTML是不同的,模板指令只有很有限的编程能力,可以避免混入商业逻辑。
.doc转为xml文件
文字
图片
图片只要把binaryData中的字符流改为${变量名}就可以。
package com.model.controller;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import sun.misc.BASE64Encoder;
import sun.net.www.protocol.http.HttpURLConnection;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
* word 下载
* Created by xxx on 2018/11/6.
*/
@Controller
@RequestMapping("/project")
public class ProjectController {
private static Logger logger=Logger.getLogger(ProjectController.class);
/**
* 下载
* @param response
*/
@RequestMapping(value="/download")
public void download(HttpServletResponse response){
try{
Map map=new HashMap(6);
//组装返回数据
completeData(map);
//建立下载文件名称
String fileName = Long.toString(System.currentTimeMillis()) + RandomStringUtils.randomNumeric(10) + ".doc";
//修改文件模板
File file=writeFileTemplate(fileName,map);
//导出文件
exportFile(response,file);
}catch(Exception e){
logger.error(" download file error",e);
}
}
/**
* 导出文件
* @param response
* @param file
*/
public void exportFile(HttpServletResponse response,File file){
try{
ServletOutputStream out=response.getOutputStream();
BufferedInputStream in=new BufferedInputStream(new FileInputStream(file));
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
byte[] buffer=new byte[1024];
int count=0;
while((count=in.read(buffer))!=-1){
out.write(buffer,0,count);
}
out.flush();
out.close();
}catch(Exception e){
logger.error("export word error",e);
}finally{
file.delete();
}
}
/**
* 修改文件模板
* @param fileName
* @param map
* @return
* @throws Exception
*/
public File writeFileTemplate(String fileName,Map map) throws Exception{
try{
//设置freemarker模板编码、路径、模板名称
Configuration configuration=new Configuration();
configuration.setDefaultEncoding("utf-8");
String tempPath=this.getClass().getResource("").getPath().substring(0,this.getClass().getResource("").getPath().indexOf("WEB-INF"));
String templatePath=tempPath+"WEB-INF/exportTemplates/trademark/";
configuration.setDirectoryForTemplateLoading(new File(templatePath));
Template template=configuration.getTemplate("model.ftl");
//设置输出文件路径
String outPath=tempPath+"WEB-INF/tempFile/"+fileName;
File outFile=new File(outPath);
Writer writer=null;
try{
writer=new OutputStreamWriter(new FileOutputStream(outFile), "utf-8");
template.process(map,writer);
}catch(Exception e){
logger.error("template write data error",e);
throw e;
}finally{
writer.close();
}
return outFile;
}catch(Exception e){
logger.error("ProjectController.writeFileTemplate error",e);
throw e;
}
}
/**
* 组装返回数据
* @param map
* @return
* @throws Exception
*/
public Map completeData(Map map)throws Exception{
try{
map.put("name","张三");
map.put("department","技术部");
map.put("projectName","灿烂");
map.put("year","2018");
map.put("month","11");
map.put("day","8");
File file=saveToFile("http://mm.yh31.com:88/tp/sdj/201712241958292972.jpg");
String imageBase64 = encodeBase64File(file);
map.put("picture",imageBase64);
}catch(Exception e){
logger.error("ProjectController.completeData error",e);
throw e;
}
return map;
}
/**
* 通过url获取文件
* @param destUrl
*/
public File saveToFile(String destUrl) {
FileOutputStream fos = null;
BufferedInputStream bis = null;
HttpURLConnection httpUrl = null;
URL url = null;
int BUFFER_SIZE = 1024;
byte[] buf = new byte[BUFFER_SIZE];
int size = 0;
//在填写文件路径时,一定要写上具体的文件名称(xx.txt),否则会出现拒绝访问。
File file = new File("E:\\download\\picture.png");
if(!file.exists()){
//先得到文件的上级目录,并创建上级目录,在创建文件
file.getParentFile().mkdir();
try {
//创建文件
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
url = new URL(destUrl);
httpUrl = (HttpURLConnection) url.openConnection();
httpUrl.connect();
bis = new BufferedInputStream(httpUrl.getInputStream());
fos = new FileOutputStream(file);
while ((size = bis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
fos.flush();
} catch (IOException e) {
} catch (ClassCastException e) {
logger.error("url transfer to http url error",e);
throw e;
} finally {
try {
fos.close();
bis.close();
httpUrl.disconnect();
} catch (IOException e) {
} catch (NullPointerException e) {
}
}
return file;
}
/**
* 将文件转化为Base64编码
* @param file
* @return
* @throws Exception
*/
public static String encodeBase64File(File file) throws Exception {
//File file = new File(path);;
FileInputStream inputFile = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
inputFile.read(buffer);
inputFile.close();
return new BASE64Encoder().encode(buffer);
}
}
4.1 方法public File saveToFile(String destUrl)中的 httpUrl = (HttpURLConnection) url.openConnection();因为HttpUrl与Url引用的java包不一致,Url是.net而HttpURL是apache,为此统一改为.net包
4.2 获取文件路径的问题,详见博文https://blog.csdn.net/weixin_41926301/article/details/83818927
4.3 方法public File writeFileTemplate(String fileName,Map
writer=new OutputStreamWriter(new FileOutputStream(outFile), "utf-8")错误的写法
writer=new OutputStreamWriter(new FileOutputStream(outFile))会造成文件输出的编码不是utf-8的格式,从而造成下载后的文件不可读。