数据报表功能化实现

208 阅读2分钟

背景说明

运营小姐姐每半个月都会找我拉一份数据文件,表头是固定的,就那么几列。里面的逻辑就是关联多张表,分别取到相应的字段写入Excel导出来给到小姐姐就结束了。

一开始呢,是每次小姐姐来找我的时候,我咧,就手动给她拉一份。一般上午和我说,午饭的时候我发给她。

大概在三四十万的量,跑脚本也要跑一会会,还有就是那些表是分开在两个库里面的,一个 MongoDB ,一个 MySQL 。除了一个需要匹配的字段是从 MySQL 里取出来的,其它字段都是从 MongoDB 里拿的。

先是在 MongoDB 里面执行 js 脚本。跑的时间比较久。跑完要人工手动导出来,再导入到 MySQL 里面,sql 的执行就简单了,手动关联下表,取到目标字段,这份数据报表就可以导出来交差了。

但是呢,这么有规律的事情应该是让机器去执行。

自动化功能

做这份报表自动化功能涉及两个接口,一个接口( dataSync )让定时任务调用的,一个接口( download )是给小姐姐下载使用的。每个月的 1 号和 16 号凌晨执行定时任务进行数据的同步。白天的时候小姐姐直接用浏览器就可以下载数据文件了。 dataSync 接口做的事情其实没什么好多介绍的。就是用项目语言将前面提到的那些 js 脚本和 sql 脚本转成功能模块。要注意的是这里涉及到两种数据库,所以需要配置多数据源。

下载文件

文件下载用的是 EasyExcel 。直接用 HttpServletResponse response 就可以直接通过浏览器链接下载了。

    @GetMapping("/dataList/download")
    public void download(HttpServletResponse response) throws IOException {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("数据-" + LocalDate.now(), "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            List<Entity> dataList = repository.findAll();
            logger.info("data size = {}", dataList.size());
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            headWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
            WriteFont headWriteFont = new WriteFont();
            headWriteFont.setFontHeightInPoints((short)12);
            headWriteCellStyle.setWriteFont(headWriteFont);
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
            contentWriteCellStyle.setFillPatternType(FillPatternType.NO_FILL);
            HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                    new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

            EasyExcel.write(response.getOutputStream(), Entity.class).autoCloseStream(Boolean.FALSE).sheet(LocalDate.now().toString()).registerWriteHandler(horizontalCellStyleStrategy)
                    .doWrite(dataList);
        } catch (Exception e) {
            logger.error("下载 失败 ERROR MSG => ", e);
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }

```