• 使用静态代理模式实现公用的报表导出功能


    先聊一下什么是代理模式?

    代理模式 给某个对象提供一个代理对象,并由代理独享控制对原对象的引用。什么意思呢?代理模式就有点像我们生活中常见的中介。

    举个例子,我想买辆二手车,第一种方式是自己去找车源,但是像质量检测等一系列的车辆过户流程都需要自己去办,我觉得这样太浪费精力和时间了。于是我想到了第二种方式,就是找一个中介公司,他们代替我办理过户流程,我只需要负责选择自己喜欢的汽车,然后付钱就行了,这就简单很多了。

    画个UML图如下。

    在这里插入图片描述
    前面提到了我们选择中介是为了省事,其实在代码中使用代理模式也可以省事,因为不只有我这个对象会去找这个中介,其他需要买二手车的人也需要去找这个中介,那这个中介的作用就做到了重用了。

    下面说在程序中为什么要使用代理模式

    • 中介隔离:在某些情况下,一个客户不想或不能直接引用委托对象。
    • 开闭原则,增加功能:当代码需要增加业务功能时,我们只需要修改代理类就行,符合开闭原则。

    代理模式分为静态代理和动态代理。我们今天着重讲静态代理

    下面进入猎杀时刻!!!!

    使用静态代理模式实现公用的导出功能

    先来一张设计图

    在这里插入图片描述

    先看代理接口

    public interface ReportWithExcelTempAble<T> {
    
        /**
         * 获得报表数据
         * @param searchParam
         * @return
         */
        default List<List<?>> getMultipleSheetData(T searchParam) {
            ArrayList<List<?>> result = Lists.newArrayList();
            result.add(getSingleSheetData(searchParam));
            return result;
        }
    
        default List<?> getSingleSheetData(T searchParam) {
            throw new RuntimeException("Not support method.");
        }
    
        Class<T> getSearchParamType();
    
        /**
         * 需要导出的文件名
         * @return
         */
        default String getReportFileName(String tempName) {
            return tempName;
        }
    }
    

    getMultipleSheetDatagetReportFileName都有默认的实现方法,因为大部分都是一个sheet的报表。

    再看看代理类,代理主要是代理了报表在导出中的一系列操作,比如获取导出模板,设置导出名称等等。

    package com.sf.esg.occp.core.common.support.report;
    
    import com.alibaba.fastjson.JSONObject;
    import com.sf.erui.context.SpringContextUtil;
    import com.sf.erui.util.StringUtil;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.List;
    
    public class ReportProxy implements ReportWithExcelTempAble<JSONObject> {
    
        private static Logger LOG = LoggerFactory.getLogger(ReportProxy.class);
        /**
         * 模板名称
         */
        private String tempName;
    
    
        /**
         * 报表名称
         */
        private String reportFileName;
    
        private ReportWithExcelTempAble delegateInstance;
    
        private ReportProxy() {
        }
    
        public String getReportFileName() {
            return reportFileName;
        }
    
        public static <T> ReportProxy of(String delegateName) {
            ReportProxy director = new ReportProxy();
            director.tempName = delegateName;
            director.delegateInstance = SpringContextUtil.getBean(
                    StringUtil.toLowerCaseFirstOne(director.tempName)
                    , ReportWithExcelTempAble.class);
            director.reportFileName = director.delegateInstance.getReportFileName(director.tempName);
            return director;
        }
    
    
        @Override
        public List<List<?>> getMultipleSheetData(JSONObject searchParam) {
            long start = System.currentTimeMillis();
            Object searchObj = JSONObject.toJavaObject(searchParam, delegateInstance.getSearchParamType());
            LOG.debug("组装数据费时:{}", System.currentTimeMillis() - start);
            return delegateInstance.getMultipleSheetData(searchObj);
        }
    
        @Override
        public Class getSearchParamType() {
            return delegateInstance.getSearchParamType();
        }
    
    }
    

    再来看看委托类:

    public class BankTransactionExport implements ReportWithExcelTempAble<QueryBankTransactionVO> {
    
        @Autowired
        private BankTransactionService bankTransactionService;
    
        @Override
        public List<List<?>> getMultipleSheetData(QueryBankTransactionVO searchParam) {
            List<List<?>> lists = bankTransactionService.exportMultipleSheet(searchParam);
            return lists;
        }
    
        @Override
        public Class<QueryBankTransactionVO> getSearchParamType() {
            return QueryBankTransactionVO.class;
        }
    
        @Override
        public String getReportFileName(String tempName) {
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
            String dateStr = format.format(new Date());
            return "SF银行流水认领明细" + dateStr;
        }
    }
    

    Controller层:

    @RestController
    @RequestMapping("/report/excel")
    public class ReportController {
        public static final String FILE_SUFFIX = ".xlsx";
        public static final String TEMP_BASE_PATH = "temp/";
        public static final String PAGE_SIZE = "pageSize";
        public static final String CURRENT_PAGE = "currentPage";
        public static final int PAGE_SIZE_VALUE = 1000;
    
        private static Logger LOG = LoggerFactory.getLogger(ReportController.class);
    
        @GetMapping(params = {"Action=exportExcelByTemp"})
        public Response exportExcelByTemp(@RequestParam Map<String, Object> searchParam, HttpServletResponse resp) {
            LOG.info("Export report by temp:{}", searchParam);
            String tempName = (String) searchParam.get("tempName");
    
            try {
                ReportProxy reportDirector = ReportProxy.of(tempName);
                String tempPath = TEMP_BASE_PATH + tempName + FILE_SUFFIX;
                String fileName = URLEncoder.encode(reportDirector.getReportFileName(), "UTF-8");
                resp.setHeader("Content-Disposition", "filename=" + fileName + FILE_SUFFIX);
                resp.setContentType("APPLICATION/OCTET-STREAM");
    
                try (InputStream ins = new ClassPathResource(tempPath).getInputStream()) {
                    ExcelWriterBuilder writeBuilder = EasyExcel.write(resp.getOutputStream()).withTemplate(ins);
                    ExcelWriter writer = writeBuilder.autoCloseStream(false).
                            registerConverter(new LocalDateTimeConverter()).build();
                    JSONObject jsonObject = new JSONObject(searchParam);
                    List<List<?>> data = reportDirector.getMultipleSheetData(jsonObject);
                    ExcelUtils.pageExportByTemp(writer, data, tempPath);
                    writer.finish();
                } catch (IOException e) {
                    LOG.error("Excel Export Err : ", e);
                }
                return ResponseHelper.buildOk();
            } catch (IOException e) {
                LOG.error("Response get output stream err:{}", e);
                return ResponseHelper.buildFail("请联系管理员");
            }
        }
    }
    

    在前端使用get请求调用:/report/excel?Action=exportExcelByTemp&tempName="a.xmls"

    最后别忘了,添加a.xmls在项目的 temp/目录下,我用的Spring boot,对应代码中的目录如下

    在这里插入图片描述

  • 相关阅读:
    Github+Jekyll 搭建个人网站详细教程
    github发布博客
    如何在GitHub部署自己的个人网站
    VS2017git 提交提示错误 Git failed with a fatal error.
    CAD 二次开发----- 块
    Updates were rejected because the remote contains work that you do(gitee报错解决方案)
    关于错误CSC : error CS0006:未能找到元数据文件
    js 四舍五入
    spingboot 邮件模板发送;
    springboot 邮件
  • 原文地址:https://www.cnblogs.com/sean-zeng/p/14121701.html
Copyright © 2020-2023  润新知