import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.lowagie.text.pdf.BaseFont;
import ext.plm.common.CtConstant;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
/**
* ftl 模板专用类
* @author tan
*/
public final class FormTemplateTool {
private final Template template;
private long version;
private File ftl;
private FormTemplateTool(String ftlName) throws Exception {
String ftlPath = CtConstant.getFtlPath() + ftlName;
File file=new File(ftlPath);
if(!file.exists()) {
throw new IOException(ftlPath + "is not exists");
}
this.ftl = file;
Configuration configuration = new Configuration(Configuration.VERSION_2_3_25);// 版本号和jar包保持一致
// 设置模板目录
configuration.setDirectoryForTemplateLoading(new File(CtConstant.getFtlPath()));// 模板所放的路径
// 设置默认编码格式
configuration.setDefaultEncoding("UTF-8");
configuration.setTemplateUpdateDelayMilliseconds(0);
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
template = configuration.getTemplate(ftlName);// 模板名称
version = System.currentTimeMillis();
}
/**
* 后台下载方式
* @param dataModel
* @param writer
* @throws TemplateException
* @throws IOException
*/
public void process(Object dataModel,Writer writer) throws TemplateException, IOException {
template.process(dataModel, writer);
}
public String process(Object dataModel) throws IOException, TemplateException{
return FreeMarkerTemplateUtils.processTemplateIntoString(template, dataModel);
}
private boolean isOutDate(long lastModify) {
return lastModify > version;
}
private static final Map<String, FormTemplateTool> MAP = new HashMap<String, FormTemplateTool>();
/**
* 获取表单模板
* @throws Exception
*/
public static FormTemplateTool getTemplete(String ftlName) throws Exception {
FormTemplateTool mailTemplate = MAP.get(ftlName);
if (mailTemplate == null || mailTemplate.isOutDate(mailTemplate.ftl.lastModified())) {
mailTemplate = new FormTemplateTool(ftlName);
MAP.put(ftlName, mailTemplate);
}
return mailTemplate;
}
/**
* 下载 excel
* @param response 页面响应
* @param dataMap 需要导出的数据源
* @param fileName 文件名称
* @throws TemplateException
* @throws IOException
*/
public void download(HttpServletResponse response, Map<String, Object> dataMap, String fileName)
throws TemplateException, IOException {
response.setContentType("application/msexcel;charset=UTF-8");
response.setHeader("Content-disposition",
"attachment;filename=\"" + new String((fileName + ".xls").getBytes("GBK"), "ISO8859-1") + "\"");
// response字符流转换成字节流,template需要字节流作为输出
OutputStream outputStream = response.getOutputStream();
OutputStreamWriter outputWriter = new OutputStreamWriter(outputStream, "UTF-8");
Writer writer = new BufferedWriter(outputWriter);
template.process(dataMap, writer);
writer.flush();
writer.close();
}
/**
* 通过模板导出pdf文件
* @param data 数据
* @param templateFileName 模板文件名
* @throws Exception
*/
public static ByteArrayOutputStream createPDF(Map<String,Object> data, String templateFileName) throws Exception {
ITextRenderer renderer = new ITextRenderer();
OutputStream out = new ByteArrayOutputStream();
try {
// 1.设置 css中 的字体样式(暂时仅支持宋体和黑体) 必须,不然中文不显示
renderer.getFontResolver().addFont(CtConstant.getFtlPath()+"font/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
// 2.获取模板文件
FormTemplateTool template = getTemplete(templateFileName);
StringWriter writer = new StringWriter();
// 3.将数据输出到html中
template.process(data, writer);
writer.flush();
String html = writer.toString();
// 4.把html代码传入渲染器中
renderer.setDocumentFromString(html);
renderer.layout();
// 5.写PDF文件
renderer.createPDF(out, false);
renderer.finishPDF();
out.flush();
return (ByteArrayOutputStream)out;
} finally {
if(out != null){
out.close();
}
}
}
}