1.word模板转xml文件再换ftl文件(可参考网上教程,再格式化一下)
2.将文件放入resource目录
3.使用${}替换原有的数据
列如:${(weatherReportDto.propertyRightUnitName)}
4.添加依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
5.创建工具类
package com.thinkgem.jeesite.modules.weather.utils;
import cn.afterturn.easypoi.word.WordExportUtil;
import com.google.common.collect.Lists;
import com.thinkgem.jeesite.common.pdf.component.PDFHeaderFooter;
import com.thinkgem.jeesite.common.pdf.component.PDFKit;
import com.thinkgem.jeesite.common.pdf.component.chart.model.XYLine;
import com.thinkgem.jeesite.common.pdf.component.chart.model.XYScatter;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FileCopyUtils;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* @Description: ftl工具类
* @Author: xiaohui
* @Date: 2022-12-17 10:07
* @Version: 1.0
*/
@Slf4j
public class PdfBeanUitl {
@Value("${userfiles.basedir.linux}")
private String prefix;
@Autowired
private PDFKit pdfKit;
private static final String ENCODING = "UTF-8";
private static Configuration cfg = new Configuration();
public String createPDF(String template,String templatePath,Object data, String fileName){
//pdf保存路径
try {
//设置自定义PDF页眉页脚工具类
PDFHeaderFooter headerFooter=new PDFHeaderFooter();
PDFKit kit=new PDFKit();
kit.setHeaderFooterBuilder(headerFooter);
//设置输出路径
// kit.setSaveFilePath("D:\\"+fileName);
// String classpath = this.getClass().getResource("/").getPath().replaceFirst("/", "");
// String filePath = classpath.replaceAll("WEB-INF/classes/", "static/pdf");
// String filePath=docRoot+ "/" + fileName;
// getRealPath("/WEB-INF/db.xml");
String filePath = templatePath +"/pdf/"+fileName;
// String filePath=pdfKit.getDefaultSavePath(fileName);
kit.setSaveFilePath(filePath);
String saveFilePath=kit.exportToFile(template,filePath,fileName,data);
return saveFilePath;
} catch (Exception e) {
log.error("PDF生成失败{}", ExceptionUtils.getFullStackTrace(e));
return null;
}
}
/**
* @description:
* @author: xiaoHui
* @create: 2022/11/17
* @param data 数据
* @param templateFileName 模板名字 ftl
* @param outFilePath 输出路径
* @param fileName 输出名
* @param response 响应
* @return String 输出名
**/
public String createWord(Object data,String templateFileName, String outFilePath,
String fileName, HttpServletResponse response) throws IOException {
Writer out = null;
File outFile = new File(outFilePath);
try {
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
out = new OutputStreamWriter(new FileOutputStream(outFile), ENCODING);
// 获取模板,并设置编码方式,这个编码必须要与页面中的编码格式一致
Template template = getTemplate(templateFileName);
//下载到本地
template.process(data, out);
out.flush();
log.info("由模板文件" + templateFileName + "生成" + outFilePath + "成功.");
} catch (Exception e) {
log.error("由模板文件" + templateFileName + "生成" + outFilePath + "出错");
} finally {
out.close();
}
// 获取服务器本地的文件位置
File file = new File(outFilePath);
if (file.exists()) {
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
// 清除buffer缓存
response.reset();
// 指定下载的文件名
response.setHeader("Content-Disposition",
"attachment;filename=" + new String(fileName.getBytes("utf-8"),"iso-8859-1"));
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setCharacterEncoding("UTF-8");
FileInputStream inputStream = new FileInputStream(file);
// FileCopyUtils.copy(inputStream, response.getOutputStream());
bufferedInputStream = new BufferedInputStream(inputStream); //缓冲流加速读
OutputStream outputStream = response.getOutputStream();
bufferedOutputStream = new BufferedOutputStream(outputStream); //缓冲流加速写
int n;
while ((n = bufferedInputStream.read()) != -1) {
bufferedOutputStream.write(n);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bufferedOutputStream.close();
bufferedInputStream.close();
file.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
throw new RuntimeException("文件在本地服务器不存在");
}
return fileName;
}
// 初始化cfg
static {
// 设置模板所在文件夹
cfg.setClassForTemplateLoading(FtlUtils.class, "/template");
// 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);
}
public static void main(String[] args) {
PdfBeanUitl kit=new PdfBeanUitl();
TemplateBO templateBO=new TemplateBO();
templateBO.setReportName("freemarker! 测试模板");
templateBO.setStationCode("ABCDDNDNFEFNEFEN");
templateBO.setStationName("成都市XXX值");
templateBO.setCreateDate("2018-10-22");
templateBO.setImageUrl("https://bkimg.cdn.bcebos.com/pic/9825bc315c6034a852660f9dc513495409237621");
List<TemplateBO> scores=new ArrayList<TemplateBO>();
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
scores.add(templateBO);
templateBO.setScores(scores);
//折线图
// List<XYLine> lineList=getTemperatureLineList();
// DefaultLineChart lineChart=new DefaultLineChart();
// lineChart.setHeight(500);
// lineChart.setWidth(300);
// String picUrl=lineChart.draw(lineList,0);
// templateBO.setPicUrl(picUrl);
//散点图
// String scatterUrl= ScatterPlotChart.draw(getData(),1,"他评得分(%)","自评得分(%)");
// templateBO.setScatterUrl(scatterUrl);
// String templatePath="/Users/fgm/workspaces/fix/pdf-kit/src/test/resources/templates";
String templatePath="weather_station/src/main/webapp/test";
String path= kit.createPDF("",templatePath,templateBO,"hello.pdf");
System.out.println(path);
}
}
6.初始化cfg
// 初始化cfg
static {
// 设置模板所在文件夹
cfg.setClassForTemplateLoading(FtlUtils.class, "/template");
// setEncoding这个方法一定要设置国家及其编码,不然在ftl中的中文在生成html后会变成乱码
cfg.setEncoding(Locale.getDefault(), ENCODING);
// 设置对象的包装器
cfg.setObjectWrapper(new DefaultObjectWrapper());
// 设置异常处理器,这样的话就可以${a.b.c.d}即使没有属性也不会出错
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
}
7.获取模板对象
// 获取模板对象
public static Template getTemplate(String templateFileName) throws IOException {
return cfg.getTemplate(templateFileName, ENCODING);
}
8.封装方法,下载文件
工具类中 createWord
9.数据封装(数据库查询),调用封装方法
工具类中方法可以自己封装 也可以一个类中使用,核心调用createWord方法
注意:模板文件目录
// 设置模板所在文件夹
cfg.setClassForTemplateLoading(FtlUtils.class, "/templates/report");
FTL基本语法
附:ftl基本语法