模版导出excel、word

记录一下上周弄的一个模版导出,解决导出样式难以控制的问题。

常规导出,需要人为的判定各种样式,遇到表头合并之类的更麻烦,于是就想到现在比较火的模版导出。

然后,网上的资料大多都是复制粘贴,甚至直接就是转载,而且大多都是直接指定保存路劲,没有实现导出下载功能,这里我记录下自己的一些操作步骤,希望对大家有用。

第一步:导出freemarker的依赖(我的所有项目都是基于maven)

<!-- freemarker -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>${freemarker-version}</version>
        </dependency>
第二步:构建导出后的模版(.ftl文件,例如:export.ftl)(按照习惯,在根目录创建一个template文件夹存放模版文件)
<table border="1">
    <tr>
        <th class="text-center" rowspan="2">序号</th>
        <th class="text-center" rowspan="2">姓名</th>
    <#if docTypeNums??&&docTypeNums?size>0>
        <#list docTypeNums as obj>
            <th class="text-center" colspan="${obj["num"]!}">${obj["type_name"]!}</th>
        </#list>
    </#if>
    </tr>
    <tr>
    <#if docTypes??>
        <#list docTypes as obj>
            <th class="text-center">${obj.typeName!}</th>
        </#list>
    </#if>
    </tr>
    <tbody>
    <#if obj??&&(obj?size>0)>
        <#list obj?keys as key>
        <tr>
            <td>${1+key_index}</td>
            <td>${obj[key][key]!}(${key})</td>
            <#assign map = obj[key]>
            <#if docTypes??>
                <#list docTypes as ob>
                    <td>${map[ob.id]!"0"}</td>
                </#list>
            </#if>
        </tr>
        </#list>
    </#if>
    </tbody>
</table>
一个模版用一个table进行构建,当然,如果你又特殊需求,可以使用多个table进行构建。

如果不懂freemarker标签的可以百度,这里我不解释了,我的业务有特殊需求,所以不用看我的数据是怎么操作的,看不懂的(看懂也没用)。

第三步:获取数据(上面模版中的参数,均由map传递)

Map<String,Object> map1 = new HashMap<>();
        map1.put("docTypes",docTypes);
        map1.put("obj",maps);
        map1.put("docTypeNums",docTypeNums);

第四步:渲染模版并导出(渲染时,freemarker会将map解析,获取每一个key,在模版中,我们直接调用key进行操作就可以了)

/***
     * 通用导出Excel模版
     * @param map       模版需要的数据
     * @param filePath  模版所在项目路劲,如:"\\template\\statistics",表示在项目根路劲去找该路劲
     * @param fileName  文件名
     * @param response  用于输出
     * @param request   用于获取项目根目录
     * @throws Exception
     */
    public void exportExcel(Map<String, Object> map,String filePath,String fileName,HttpServletResponse response,HttpServletRequest request) throws Exception{
        //创建一个文件流
        File file = new File(request.getSession().getServletContext().getRealPath("/")+filePath);
        //初始化freemarker模版引擎的设置
        Configuration configuration = new Configuration();
<span style="white-space:pre">	configuration.setDefaultEncoding("UTF-8");</span>
        configuration.setDirectoryForTemplateLoading(file);
        //获取模版
        Template template = configuration.getTemplate(fileName+".ftl","UTF-8");<span style="font-family: Arial, Helvetica, sans-serif; color: rgb(169, 183, 198);"></span>
        //创建输出文件流
        File outfile = new File(request.getSession().getServletContext().getRealPath("/")+filePath+"/"+fileName+".xlsx");
        //创建输出流
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outfile),"UTF-8"));
        //渲染模版
        template.process(map, out);

        out.flush();
        out.close();
        //用response进行导出
        String fileName1 = fileName+".xlsx";
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName1, "UTF-8"));
        /*创建输入流*/
        FileInputStream in = new FileInputStream(outfile);
        BufferedInputStream buff = new BufferedInputStream(in);
        IOUtils.copy(buff, response.getOutputStream());

        response.flushBuffer();
        in.close();
        outfile.delete();
    }
最后总结:这种方式有一个弊端,就是每次都会在服务器保存一个文件,最后由程序去删除。如果能够做到临时文件流存储,那就圆满了,大大减少服务器的负担。我对文件流不熟悉,如果有大神能够搞定这个功能,还请不吝赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值