diff --git a/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/govorg/result/GridInfoResultDTO.java b/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/govorg/result/GridInfoResultDTO.java index 45618fbff5..a4e155231f 100644 --- a/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/govorg/result/GridInfoResultDTO.java +++ b/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/govorg/result/GridInfoResultDTO.java @@ -37,5 +37,6 @@ public class GridInfoResultDTO implements Serializable { */ private String gridId = ""; private String gridName = ""; + private String pids = ""; } \ No newline at end of file diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/excel/GridLivelyDetailExcel.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/excel/GridLivelyDetailExcel.java new file mode 100644 index 0000000000..ce6d2b5365 --- /dev/null +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/excel/GridLivelyDetailExcel.java @@ -0,0 +1,81 @@ +/** + * Copyright 2018 人人开源 https://www.renren.io + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.epmet.dataaggre.excel; + +import cn.afterturn.easypoi.excel.annotation.Excel; +import cn.afterturn.easypoi.excel.annotation.ExcelIgnore; +import lombok.Data; + +import java.util.LinkedList; +import java.util.List; + +/** + * @Description 网格活跃度文件导出-活跃网格sheet-接口返参 + * @Author sun + */ +@Data +public class GridLivelyDetailExcel { + + LinkedList livelyExcelList; + List livelyGrid; + List ordinaryGrid; + List lazyGrid; + + //活跃网格 + @Data + public static class LivelyGrid { + @ExcelIgnore + private String agencyId; + @Excel(name = "所属组织", width = 20, mergeVertical = true) + private String agencyName; + @ExcelIgnore + private String gridId; + @Excel(name = "活跃网格名称",width = 20) + private String gridName; + @Excel(name = "活跃天数",width = 20) + private Integer datyNum; + } + //正常网格 + @Data + public static class OrdinaryGrid { + @ExcelIgnore + private String agencyId; + @Excel(name = "所属组织", width = 20, mergeVertical = true) + private String agencyName; + @ExcelIgnore + private String gridId; + @Excel(name = "正常运行网格名称", width = 20) + private String gridName; + @Excel(name = "活跃天数", width = 20) + private Integer datyNum; + } + //僵尸网格 + @Data + public static class LazyGrid { + @ExcelIgnore + private String agencyId; + @Excel(name = "所属组织", width = 20, mergeVertical = true) + private String agencyName; + @ExcelIgnore + private String gridId; + @Excel(name = "僵尸网格名称",width = 20) + private String gridName; + @Excel(name = "活跃天数",width = 20) + private Integer datyNum; + } +} diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/excel/GridLivelyExcel.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/excel/GridLivelyExcel.java index 331511dbe6..39740aa2a2 100644 --- a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/excel/GridLivelyExcel.java +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/excel/GridLivelyExcel.java @@ -18,7 +18,7 @@ package com.epmet.dataaggre.excel; import cn.afterturn.easypoi.excel.annotation.Excel; -import com.alibaba.excel.annotation.ExcelIgnore; +import cn.afterturn.easypoi.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import lombok.Data; @@ -66,7 +66,7 @@ public class GridLivelyExcel { //正常运行网格数占比 - @Excel(name = "正常运行网格数占比",width = 15) + @Excel(name = "正常运行网格数占比",width = 20) @ExcelProperty("正常运行网格数占比") @ColumnWidth(15) private String gridOrdinaryRatio; diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/govorg/impl/GovOrgServiceImpl.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/govorg/impl/GovOrgServiceImpl.java index 7acb871048..6b2cb560fe 100644 --- a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/govorg/impl/GovOrgServiceImpl.java +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/govorg/impl/GovOrgServiceImpl.java @@ -2,9 +2,7 @@ package com.epmet.dataaggre.service.govorg.impl; import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; -import com.alibaba.excel.EasyExcel; -import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.write.metadata.WriteSheet; +import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import com.alibaba.fastjson.JSON; import com.dingtalk.api.request.OapiRobotSendRequest; import com.epmet.commons.dynamic.datasource.annotation.DataSource; @@ -16,10 +14,11 @@ import com.epmet.commons.tools.dto.result.CustomerStaffInfoCacheResult; import com.epmet.commons.tools.exception.EpmetErrorCode; import com.epmet.commons.tools.exception.ExceptionUtils; import com.epmet.commons.tools.exception.RenException; +import com.epmet.commons.tools.redis.common.CustomerOrgRedis; import com.epmet.commons.tools.redis.common.CustomerStaffRedis; +import com.epmet.commons.tools.redis.common.bean.AgencyInfoCache; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.utils.ConvertUtils; -import com.epmet.commons.tools.utils.ExcelUtils; import com.epmet.commons.tools.utils.HttpClientManager; import com.epmet.commons.tools.utils.Result; import com.epmet.dataaggre.constant.DataSourceConstant; @@ -31,6 +30,7 @@ import com.epmet.dataaggre.dto.govorg.form.*; import com.epmet.dataaggre.dto.govorg.result.*; import com.epmet.dataaggre.dto.resigroup.result.OrgInfoCommonDTO; import com.epmet.dataaggre.entity.govorg.CustomerAgencyEntity; +import com.epmet.dataaggre.excel.GridLivelyDetailExcel; import com.epmet.dataaggre.excel.GridLivelyExcel; import com.epmet.dataaggre.service.commonservice.AreaCodeService; import com.epmet.dataaggre.service.datastats.DataStatsService; @@ -51,6 +51,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.commons.CommonsMultipartFile; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; @@ -677,13 +678,131 @@ public class GovOrgServiceImpl implements GovOrgService { return subList; } + private GridLivelyDetailExcel gridActiveList(GridLivelyFormDTO formDTO) { + GridLivelyDetailExcel result = new GridLivelyDetailExcel(); + LinkedList livelyExcelList = new LinkedList<>(); + List livelyGrid = new ArrayList<>(); + List ordinaryGrid = new ArrayList<>(); + List lazyGrid = new ArrayList<>(); + //用于存放存在例行工作或上报事件的网格Id,供后边寻找活跃度为0的僵尸网格使用 + Set gridSet = new HashSet<>(); + //0.查询当前组织的直属下级组织列表及组织下的网格总数 + LinkedList subList = customerAgencyDao.subAgencyListAndGridSumNum(formDTO.getAgencyId()); + //1.查询当前组织下所有网格列表 + List gridList = customerGridDao.selectAgencyGridList(formDTO.getAgencyId()); + Map gridMap = gridList.stream().collect(Collectors.toMap(GridInfoResultDTO :: getGridId, v -> v, (v1, v2) -> v1)); + //2.查询直属下级组织下网格在查询时间段内存在例行工作次数的网格,一天一条 + List workList = epmetUserService.getGridDateRoutineWorkList(formDTO); + //3.查询直属下级组织下网格在查询时间段内存在上报事件(直接立项)数的网格,一天一条 + List projectList = dataStatsService.getGridDateProjectIncrList(formDTO); + //4.汇总数据,一个网格一天只记录一条数据,这条数据可能是例行工作的也可能是上报事件的,也可能某一天两个数都有,但只记录一条 + Set map = workList.stream().map(o -> o.getGridId() + o.getDateId()).collect(Collectors.toSet()); + projectList.stream().filter(pro -> !map.contains(pro.getGridId() + pro.getDateId())).forEach(p -> workList.add(p)); + //5.按组织封装数据 + //计算百分比使用,保留小数点后两位 + NumberFormat numberFormat = NumberFormat.getInstance(); + numberFormat.setMaximumFractionDigits(NumConstant.TWO); + subList.forEach(sub -> { + //5-1.组装存在活跃度的数据【网格活跃天数大于0的】 + Map hash = new HashMap<>(); + workList.forEach(w -> { + if (w.getPids().contains(sub.getAgencyId())) { + if (hash.containsKey(w.getGridId())) { + hash.put(w.getGridId(), hash.get(w.getGridId()) + NumConstant.ONE); + } else { + hash.put(w.getGridId(), NumConstant.ONE); + } + } + }); + //活跃网格数、普通网格数、僵尸网格数 + int gridLivelyNum = 0; + int gridOrdinaryNum = 0; + for (Map.Entry ma : hash.entrySet()){ + gridSet.add(ma.getKey()); + if (ma.getValue() >= NumConstant.FIVE) {//活跃网格 + gridLivelyNum++; + GridLivelyDetailExcel.LivelyGrid lively = new GridLivelyDetailExcel.LivelyGrid(); + lively.setAgencyId(sub.getAgencyId()); + lively.setAgencyName(sub.getAgencyName()); + lively.setGridId(ma.getKey()); + lively.setGridName(null!=gridMap.get(ma.getKey())?gridMap.get(ma.getKey()).getGridName():""); + lively.setDatyNum(ma.getValue()); + livelyGrid.add(lively); + } else if (ma.getValue() >= NumConstant.TWO && ma.getValue() < NumConstant.FIVE) {//正常网格 + gridOrdinaryNum++; + GridLivelyDetailExcel.OrdinaryGrid ordinary = new GridLivelyDetailExcel.OrdinaryGrid(); + ordinary.setAgencyId(sub.getAgencyId()); + ordinary.setAgencyName(sub.getAgencyName()); + ordinary.setGridId(ma.getKey()); + ordinary.setGridName(null!=gridMap.get(ma.getKey())?gridMap.get(ma.getKey()).getGridName():""); + ordinary.setDatyNum(ma.getValue()); + ordinaryGrid.add(ordinary); + }else if (ma.getValue() < NumConstant.TWO) {//部分僵尸网格[这是活跃天数为1的,还有部分活跃天数为0的] + GridLivelyDetailExcel.LazyGrid lazy = new GridLivelyDetailExcel.LazyGrid(); + lazy.setAgencyId(sub.getAgencyId()); + lazy.setAgencyName(sub.getAgencyName()); + lazy.setGridId(ma.getKey()); + lazy.setGridName(null!=gridMap.get(ma.getKey())?gridMap.get(ma.getKey()).getGridName():""); + lazy.setDatyNum(ma.getValue()); + lazyGrid.add(lazy); + } + } + GridLivelyExcel gridLively = new GridLivelyExcel(); + gridLively.setAgencyId(sub.getAgencyId()); + gridLively.setAgencyName(sub.getAgencyName()); + gridLively.setGridSumNum(sub.getGridSumNum()); + gridLively.setGridLivelyNum(gridLivelyNum); + gridLively.setGridLivelyRatio((sub.getGridSumNum() == 0 || gridLivelyNum > sub.getGridSumNum()) ? "0%" : numberFormat.format(((float) gridLivelyNum / (float) sub.getGridSumNum()) * 100) + "%"); + gridLively.setGridOrdinaryNum(gridOrdinaryNum); + gridLively.setGridOrdinaryRatio((sub.getGridSumNum() == 0 || gridOrdinaryNum > sub.getGridSumNum()) ? "0%" : numberFormat.format(((float) gridOrdinaryNum / (float) sub.getGridSumNum()) * 100) + "%"); + int gridLazyNum = sub.getGridSumNum() - gridLivelyNum - gridOrdinaryNum; + gridLively.setGridLazyNum(gridLazyNum < 0 ? 0 : gridLazyNum); + gridLively.setGridLazyRatio((sub.getGridSumNum() == 0 || gridLazyNum < 0) ? "0%" : numberFormat.format(((float) gridLazyNum / (float) sub.getGridSumNum()) * 100) + "%"); + livelyExcelList.add(gridLively); + + //5-2.组装不存在活跃度的数据【网格活跃天数为0的】 + gridList.forEach(g->{ + if(g.getPids().contains(sub.getAgencyId())&&!gridSet.contains(g.getGridId())){ + GridLivelyDetailExcel.LazyGrid lazy = new GridLivelyDetailExcel.LazyGrid(); + lazy.setAgencyId(sub.getAgencyId()); + lazy.setAgencyName(sub.getAgencyName()); + lazy.setGridId(g.getGridId()); + lazy.setGridName(null!=gridMap.get(g.getGridId())?gridMap.get(g.getGridId()).getGridName():""); + lazy.setDatyNum(NumConstant.ZERO); + lazyGrid.add(lazy); + } + }); + }); + //5-3.网格运行情况合计 + if (!CollectionUtils.isEmpty(livelyExcelList)){ + GridLivelyExcel gridLively = new GridLivelyExcel(); + gridLively.setAgencyName("合计"); + gridLively.setGridSumNum(livelyExcelList.stream().mapToInt(GridLivelyExcel::getGridSumNum).sum()); + gridLively.setGridLivelyNum(livelyExcelList.stream().mapToInt(GridLivelyExcel::getGridLivelyNum).sum()); + gridLively.setGridLivelyRatio((gridLively.getGridSumNum() == 0 || gridLively.getGridLivelyNum() > gridLively.getGridSumNum()) ? "0%" : numberFormat.format(((float) gridLively.getGridLivelyNum() / (float) gridLively.getGridSumNum()) * 100) + "%"); + gridLively.setGridOrdinaryNum(livelyExcelList.stream().mapToInt(GridLivelyExcel::getGridOrdinaryNum).sum()); + gridLively.setGridOrdinaryRatio((gridLively.getGridSumNum() == 0 || gridLively.getGridOrdinaryNum() > gridLively.getGridSumNum()) ? "0%" : numberFormat.format(((float) gridLively.getGridOrdinaryNum() / (float) gridLively.getGridSumNum()) * 100) + "%"); + gridLively.setGridLazyNum(livelyExcelList.stream().mapToInt(GridLivelyExcel::getGridLazyNum).sum()); + gridLively.setGridLazyRatio((gridLively.getGridSumNum() == 0 || gridLively.getGridLazyNum() > gridLively.getGridSumNum()) ? "0%" : numberFormat.format(((float) gridLively.getGridLazyNum() / (float) gridLively.getGridSumNum()) * 100) + "%"); + livelyExcelList.add(gridLively); + } + + //6.封装并返回 + result.setLivelyExcelList(livelyExcelList); + result.setLivelyGrid(livelyGrid); + result.setOrdinaryGrid(ordinaryGrid); + result.setLazyGrid(lazyGrid); + return result; + } + /** * @Author sun * @Description 查询组织的直属下级组织下网格活跃度统计--文件导出 **/ @Override public void grdiLivelyExport(HttpServletResponse response, GridLivelyFormDTO formDTO) { - ExcelWriter excelWriter = null; + //easyExcel导出 + /*ExcelWriter excelWriter = null; try { excelWriter = EasyExcel.write(ExcelUtils.getOutputStreamForExcel("网格活跃度统计表.xlsx", response)).build(); WriteSheet writeSheet = EasyExcel.writerSheet(excelSheetName(formDTO)).build(); @@ -696,7 +815,73 @@ public class GovOrgServiceImpl implements GovOrgService { if (excelWriter != null) { excelWriter.finish(); } + }*/ + //easyPoi导出 + //1.获取当前组织缓存信息 + AgencyInfoCache agencyInfo = CustomerOrgRedis.getAgencyInfo(formDTO.getAgencyId()); + if (null == agencyInfo) { + throw new RenException(String.format("获取组织缓存信息失败%s", formDTO.getAgencyId())); + } + //2.查询网格活跃度数据 + GridLivelyDetailExcel resultDTO = gridActiveList(formDTO); + if(null==resultDTO||CollectionUtils.isEmpty(resultDTO.getLivelyExcelList())){ + log.warn(String.format("网格员活跃度统计数据为空,入参【%s】", JSON.toJSONString(formDTO))); + return; + } + //3.生成多sheet页excel文件并写入数据导出文件 + List> headerList = new ArrayList<>(); + String titleName = excelTitleName(formDTO.getStartTime(), formDTO.getEndTime(), agencyInfo.getOrganizationName()+"网格活跃度统计表"); + headerList.add(getHaderMap(resultDTO.getLivelyExcelList(), titleName, "各街镇网格运行情况", GridLivelyExcel.class)); + titleName = excelTitleName(formDTO.getStartTime(), formDTO.getEndTime(), agencyInfo.getOrganizationName()+"活跃网格明细"); + headerList.add(getHaderMap(resultDTO.getLivelyGrid(), titleName, "活跃网格统计", GridLivelyDetailExcel.LivelyGrid.class)); + titleName = excelTitleName(formDTO.getStartTime(), formDTO.getEndTime(), agencyInfo.getOrganizationName()+"正常运行网格明细"); + headerList.add(getHaderMap(resultDTO.getOrdinaryGrid(), titleName, "正常运行网格统计", GridLivelyDetailExcel.OrdinaryGrid.class)); + titleName = excelTitleName(formDTO.getStartTime(), formDTO.getEndTime(), agencyInfo.getOrganizationName()+"僵尸网格明细"); + headerList.add(getHaderMap(resultDTO.getLazyGrid(), titleName, "僵尸网格统计", GridLivelyDetailExcel.LazyGrid.class)); + try { + Workbook workbook = ExcelExportUtil.exportExcel(headerList, ExcelType.XSSF); + response.setCharacterEncoding("UTF-8"); + response.setHeader("content-Type", "application/vnd.ms-excel"); + String fileName = excelTitleName(formDTO.getStartTime(), formDTO.getEndTime(), agencyInfo.getOrganizationName()+"网格活跃度统计.xls"); + response.setHeader("Content-Disposition", "attachment;filename=" +fileName); + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + out.close(); + } catch (IOException e) { + log.error("网格活跃度导出失败", e); + } + } + /** + * @Author sun + * data 业务数据集合 + * title sheet页主标题 + * name sheet页名称 + * cl sheet页列头对应实体类 + * @Description 生成多sheet页excel文件模板数据 + **/ + private Map getHaderMap(Collection data, String title, String name, Class cl){ + Map map = new HashMap<>(); + map.put("data",data); + ExportParams param1 = new ExportParams(title, name); + map.put("title", param1); + map.put("entity", cl); + return map; + } + /** + * @Author sun + * @Description excel文件sheet页主标题拼接 + **/ + private String excelTitleName(String startTime, String endTime, String name){ + StringBuilder titleName = new StringBuilder(); + SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMdd"); + SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月dd日"); + try{ + titleName.append("(").append(format2.format(format1.parse(startTime))).append("至").append(format2.format(format1.parse(endTime))).append(")").append(name); + } catch (Exception e) { + e.printStackTrace(); } + return titleName.toString(); } private String excelSheetName(GridLivelyFormDTO formDTO){ diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/resources/mapper/govorg/CustomerGridDao.xml b/epmet-module/data-aggregator/data-aggregator-server/src/main/resources/mapper/govorg/CustomerGridDao.xml index 60350c7a1e..adc659eae6 100644 --- a/epmet-module/data-aggregator/data-aggregator-server/src/main/resources/mapper/govorg/CustomerGridDao.xml +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/resources/mapper/govorg/CustomerGridDao.xml @@ -6,12 +6,14 @@