java中freemarker使用FTL模版导出word文档

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基本语法

猜你喜欢

转载自blog.csdn.net/Temp_1998_H/article/details/128821536