freemarker生成excel

1. 做个excel模板

2. 把excel后缀改为xml

3.取消数据,把xml改为ftl,适当修改

4.用工具类生成excel

package com.demo.util;

import com.demo.controller.User;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.junit.jupiter.api.Test;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  模板解析实体类
 *
 */
public class TemplateParseUtil {

    /**
     * 解析模板生成Excel
     * @param templateDir  模板目录
     * @param templateName 模板名称
     * @param excelPath 生成的Excel文件路径
     * @param data 数据参数
     * @throws IOException
     * @throws TemplateException
     */
    public static void parse(String templateDir, String templateName, String excelPath, Map data) throws IOException, TemplateException {
        //初始化工作
        Configuration cfg = new Configuration();
        //设置默认编码格式为UTF-8
        cfg.setDefaultEncoding("gbk");
        //全局数字格式
        cfg.setNumberFormat("0.00");
        //设置模板文件位置
        cfg.setDirectoryForTemplateLoading(new File(templateDir));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
        //加载模板
        Template template = cfg.getTemplate(templateName,"utf-8");
        //OutputStreamWriter writer = null;
        Writer writer = null;
        try{
            //填充数据至Excel
            //writer = new OutputStreamWriter(new FileOutputStream(excelPath),"UTF-8");
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(excelPath),"UTF-8"));
            template.process(data, writer);

            writer.flush();
        }finally{
            if (writer!=null) {
                writer.close();
            }
        }
    }


    /**
     * 解析模板返回字节数组
     * @param templateDir  模板目录
     * @param templateName 模板名称
     * @param data 数据参数
     * @throws IOException
     * @throws TemplateException
     */
    public static byte[] parse(String templateDir,String templateName,Map data) throws TemplateException, IOException{
        Configuration cfg = new Configuration();
        cfg.setDefaultEncoding("UTF-8");
        cfg.setNumberFormat("0.00");
        cfg.setDirectoryForTemplateLoading(new File(templateDir));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
        Template template = cfg.getTemplate(templateName,"utf-8");
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        Writer out = new OutputStreamWriter(outStream,"UTF-8");
        template.process(data, out);
        return outStream.toByteArray();
    }

    /**
     * 自定义模板字符串解析
     * @param templateStr  模板字符串
     * @param data 数据
     * @return 解析后的字符串
     * @throws IOException
     * @throws TemplateException
     */
    public static String parse(String templateStr, Map data)
            throws IOException, TemplateException {
        Configuration cfg = new Configuration();
        cfg.setNumberFormat("#.##");
        //设置装载模板
        StringTemplateLoader stringLoader = new StringTemplateLoader();
        stringLoader.putTemplate("myTemplate", templateStr);
        cfg.setTemplateLoader(stringLoader);
        //加载装载的模板
        Template temp = cfg.getTemplate("myTemplate", "utf-8");
        Writer out = new StringWriter();
        temp.process(data, out);
        return out.toString();
    }

    public static void export(String templatePath, Map dataMap,
                              String buildFile, String newName) {
        try {
            ActionContext ac = ActionContext.getContext();
            HttpServletRequest request = (HttpServletRequest) ac
                    .get(ServletActionContext.HTTP_REQUEST);
            HttpServletResponse response = (HttpServletResponse) ac
                    .get(ServletActionContext.HTTP_RESPONSE);
            ServletContext application = request.getSession()
                    .getServletContext();
            Configuration configuration = new Configuration();
            configuration.setDefaultEncoding("utf-8");
            String path = application.getRealPath("template");
            configuration.setDirectoryForTemplateLoading(new File(path));// 此处是本类Class.getResource()相对于模版文件的相对路径
            Template template = null;
            File outFile = new File(buildFile);
            Writer writer = null;
            template = configuration.getTemplate(templatePath);
            template.setEncoding("utf-8");
            writer = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(outFile), Charset.forName("utf-8")));// 此处为输
            // 出文档编码
            template.process(dataMap, writer);
            writer.flush();
            writer.close();

            // return true;

            // 设置response的编码方式
            response.setContentType("application/x-msdownload");
            // 设置附加文件名
            response.setHeader("Content-Disposition", "attachment;filename="
                    + new String(newName.getBytes("utf-8"), "iso-8859-1"));

            // 读出文件到i/o流
            FileInputStream fis = new FileInputStream(outFile);
            BufferedInputStream buff = new BufferedInputStream(fis);

            byte[] b = new byte[1024];// 相当于我们的缓存

            long k = 0;// 该值用于计算当前实际下载了多少字节

            // 从response对象中得到输出流,准备下载

            OutputStream myout = response.getOutputStream();

            // 开始循环下载

            while (k < outFile.length()) {
                int j = buff.read(b, 0, 1024);
                k += j;
                // 将b中的数据写到客户端的内存
                myout.write(b, 0, j);
            }
            // 将写入到客户端的内存的数据,刷新到磁盘
            myout.flush();
            myout.close();
        } catch (Exception e) {
            LoggerUtils.error(e.getClass(), e.getMessage(), e);
            // return false;
        }

    }

    //    遇到的问题:
//
//            1. 使用xml作为freemarker模板时,一些含有特殊字符的变量会被xml转译,导致导出结果显示错误,此时可以使用apache common lang3包下的工具处理:
//
//            org.apache.commons.lang3.StringEscapeUtils.escapeXml( "<张三>!" )
//            2. 使用freemarker在模板中做日期格式处理时遇到问题,处理年月日时显示正常,但如果传值为null时,显示”1900/1/0“,改成了从后台使用SimpleDateFormat处理。
//            3. 日期处理中时分秒的单独显示未成功,参考使用了以下3中解析方式,都没有解析成功,可能是其他地方错了,改成了从后台使用SimpleDateFormat处理。
//
//    ${reviews.date?string('hh:mm:ss')}
//    ${reviews.date?string('HH:mm:ss')}
//    ${reviews.date?time('hh:mm:ss')}
//4. 给特定格式的日期做判空,为空时不显示,改成如下
//    ${(reviews.createTime?string('yyyy-MM-dd'))!''}

//    5.第一个就根据他的提示:在ftl文件中搜索 row标签,修改ss:Index的值 尽可能大 例如 999
//      6.也修改ftl文件中Table标签ss:ExpandedRowCount的属性 尽可能的大 如9999

    /**
     * 测试Excel文件的生成
     */
    @Test
    public void excelTest(){
        List userList = new ArrayList();
        for(int i = 1 ; i < 10;i ++){
            User user = new User();
            user.setUserName("狗娃" + i);
            user.setRealName("许文强");
            user.setPassWord("123456");
            user.setAddr("上海虎头帮总舵");
            user.setAge("28");
            userList.add(user);
        }
        Map data = new HashMap();
        data.put("userList", userList);
        try {
            TemplateParseUtil.parse("D:\\gitee\\freemarker-page-demo\\", "excel.ftl",
                    "D:\\gitee\\freemarker" + "-page-demo\\excelTest.xls", data);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }

}

你可能感兴趣的:(java)