zoukankan      html  css  js  c++  java
  • jxls -excel模板报表生成工具

    关于java对于导出excel的工具有很多,如Apache poi、alibaba的easyexcel、jxl、hutool等,但是对于表头的映射,比较麻烦,如果数据是Map,通过注解的方法就没法处理表头。

    在不关注如何映射表头是,想到有模板的方式,那就是用 jxls 工具。

    各种工具的效率问题先不讨论。

    JXLS

    jxls是一个简单的、轻量级的excel导出库,使用特定的标记在excel模板文件中来定义输出格式和布局。

    jxls是通过预制excel模板,然后通过jxls相应API将我们应用程序的数据结合模板格式输出到相应的excel文件中,从而形成报表。

    示例如下:

    1、导出如下报表数据

    2、excel模板

    说明:其中C列和H列,使用了自定义方法;C列方法的作用是将字典code转换为name文字值,H列方法的作用是计算D->G列的和。

    数据如下:

    {
        "list": [
            {
                "saleId": 1347929495306274,
                "saleName": "测试业绩目标-教务",
                "schoolId": 31,
                "schoolName": "绍兴本部校",
                "svList": [
                    {
                        "data": {
                            "1": 2,
                            "2": 0,
                            "3": 0,
                            "4": 0
                        },
                        "svType": 1
                    },
                    {
                        "data": {
                            "1": 1,
                            "2": 0,
                            "3": 0,
                            "4": 0
                        },
                        "svType": 2
                    },
                    {
                        "data": {
                            "1": 1,
                            "2": 0,
                            "3": 0,
                            "4": 0
                        },
                        "svType": 4
                    },
                    {
                        "data": {
                            "1": 0.50,
                            "2": 0,
                            "3": 0,
                            "4": 0
                        },
                        "svType": 3
                    },
                    {
                        "data": {
                            "1": 0.50,
                            "2": 0,
                            "3": 0,
                            "4": 0
                        },
                        "svType": 5
                    }
                ]
            },
            {
                "schoolName": "总计",
                "svList": [
                    {
                        "data": {
                            "1": 37,
                            "2": 0,
                            "3": 2,
                            "4": 0
                        },
                        "svType": 1
                    },
                    {
                        "data": {
                            "1": 33,
                            "2": 0,
                            "3": 2,
                            "4": 0
                        },
                        "svType": 2
                    },
                    {
                        "data": {
                            "1": 38,
                            "2": 0,
                            "3": 2,
                            "4": 0
                        },
                        "svType": 4
                    },
                    {
                        "data": {
                            "1": 0.89,
                            "2": 0,
                            "3": 1.00,
                            "4": 0
                        },
                        "svType": 3
                    },
                    {
                        "data": {
                            "1": 1.03,
                            "2": 0,
                            "3": 1.00,
                            "4": 0
                        },
                        "svType": 5
                    }
                ]
            }
        ]
    }
    View Code

    3、导出方法代码片段

    项目引入jxls

    <!-- jxls -->
    <dependency>
        <groupId>org.jxls</groupId>
        <artifactId>jxls</artifactId>
        <version>2.4.6</version>
    </dependency>
    <dependency>
        <groupId>org.jxls</groupId>
        <artifactId>jxls-poi</artifactId>
        <version>1.0.15</version>
    </dependency>
    View Code

    该示例以HttpServletResponse response返回文件流,前端直接下载

    controller方法:

    @RequestMapping("/record/clue/saler")
    public void exportSalerResource(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> reqMap) {
        //获取数据
        PageInfo<Map<String, Object>> pageInfo = clueRecordService.querySalerClueReport(reqMap);
        List<Map<String, Object>> dataList = pageInfo.getList();
        
        Map<String , Object> model=new HashMap<String , Object>();
        model.put("dataList", dataList);
        
        //模板
        String templatePath = "classpath:temp/resource_saler.xlsx";
        //导出文件名称
        String exportFileName = "咨询师资源报表.xlsx";
        
        //导出
        JxlsExportUtils.doExcelExport(request, response, model, templatePath, exportFileName);
    }
    View Code

    JxlsExportUtils:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.lang.ObjectUtils;
    import org.jxls.common.Context;
    import org.jxls.expression.JexlExpressionEvaluator;
    import org.jxls.transform.Transformer;
    import org.jxls.util.JxlsHelper;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;
    import org.springframework.util.ResourceUtils;
    
    import com.sy.common.conts.CommonConts.BillStateEnum;
    import com.sy.common.conts.CommonConts.ClueFromTypeEnum;
    import com.sy.common.conts.CommonConts.ClueSV;
    import com.sy.common.conts.CommonConts.ClueSourceEnum;
    import com.sy.common.conts.CommonConts.OrderStateEnum;
    import com.sy.common.conts.CommonConts.PayTypeEnum;
    import com.sy.common.conts.CommonConts.UserTypeEnum;
    
    import cn.hutool.core.io.IoUtil;
    
    @Slf4j
    public class JxlsExportUtils {
        /**
         * 导出执行方法
         * @param request
         * @param response
         * @param model
         * @param templatePath 模板
         * @param selfFileName 导出文件名
         */
        public static void doExcelExport(HttpServletRequest request, HttpServletResponse response,
                                    Map<String, Object> model, String templatePath, String exportFileName) {
            //导出文件名重编码
            String fileName = FileExportProcess.processFileName(exportFileName, request, response);
            
            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8"); //设置文件类型
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            
            OutputStream outputStream = null;
            InputStream inputStream = null;
            try {
                //输出流为请求响应
                outputStream = response.getOutputStream();
                //模板文件流
                inputStream = getTemplateInputStream(templatePath); //getTemplateStream(templatePath);
                //模板数据构建
                exportExcel(inputStream, outputStream, model);
            } catch (IOException e) {
                log.info("模板填充异常:{}", e);
            } finally {
                //释放资源
                if (outputStream != null) {
                    IoUtil.flush(outputStream);
                    IoUtil.close(outputStream);
                }
                if (inputStream != null) {
                    IoUtil.close(inputStream);
                }
            }
        }
    
        /**
         * 模板处理方法
         * @param is
         * @param os
         * @param model
         * @throws IOException
         */
        public static void exportExcel(InputStream is, OutputStream os, Map<String, Object> model) throws IOException {
            if (is == null) {
                log.info("获取模板异常,模板文件流为空!");
            }
            
            Context context = new Context();
            if (model != null) {
                for (String key : model.keySet()) {
                    context.putVar(key, model.get(key));
                }
            }
            
            JxlsHelper jxlsHelper = JxlsHelper.getInstance();
            Transformer transformer = jxlsHelper.createTransformer(is, os);
            JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
            
            Map<String, Object> funcs = new HashMap<String, Object>();
            funcs.put("utils", new JxlsExportUtils()); // 添加自定义功能,可在excel模板中,可直接使用该自定义对象的方法
            evaluator.getJexlEngine().setFunctions(funcs);
            
            jxlsHelper.processTemplate(context, transformer);
        }
    
        public static InputStream getTemplateInputStream(String path) throws IOException {
            log.info("模板路径为:{}", path);
            Resource resource = new ClassPathResource(path);
            InputStream templateInputStream = resource.getInputStream();
            return templateInputStream;
        }
        
        /* 统计量(应该使用枚举) */
        public String descResourceSV(Integer code) {
            String str = "";
            if (code == 1) {
                str = "新增资源量";
            } else if (code == 2) {
                str = "新增成交量";
            } else if (code == 3){
                str = "新增转化率";
            } else if (code == 4){
                str = "总成交量";
            } else {
                str = "总转化率";
            }
            return str;
        }
        
        /* map中value求和 */
        public BigDecimal doSum(Map<String, Object> items) {
            BigDecimal sum = BigDecimal.ZERO;
            if (items != null) {
                for (Entry<String, Object> entry  : items.entrySet()) {
                    String value = ObjectUtils.toString(entry.getValue());
                    sum = sum.add(new BigDecimal(value));
                }
            }
            return sum;
        }
    }
    View Code

    注意:模板中使用的自定义方法

    Map<String, Object> funcs = new HashMap<String, Object>();
    funcs.put("utils", new JxlsExportUtils()); // 添加自定义功能,可在excel模板中,可直接使用该自定义对象的方法
    evaluator.getJexlEngine().setFunctions(funcs);

    4、导出结果

    标签语法逻辑还可参考:https://yq.aliyun.com/articles/628239

  • 相关阅读:
    类的加载过程
    算法模板之基数排序
    算法模板之Dijkstra
    算法模板之SPFA
    算法模板之树状数组
    算法模板之排序
    深入JVM-自动内存管理(读书笔记)
    VMware Fault-Tolerant Virtual Machine 论文总结
    深入JVM--高效并发(读书笔记)
    欧拉素数筛
  • 原文地址:https://www.cnblogs.com/super-yu/p/12987878.html
Copyright © 2011-2022 走看看