From 7a5ef040bb8cf18d037e9f0f976d9b76379a7dd4 Mon Sep 17 00:00:00 2001 From: wr <1754607820@qq.com> Date: Fri, 6 Feb 2026 15:09:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=80=E5=8C=97=E6=95=B0=E6=8D=AE=E5=91=A8?= =?UTF-8?q?=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pq/pojo/vo/LineInfoMonitorIdVO.java | 52 ++++ .../pq/pojo/vo/dataClean/CityDataExcel.java | 44 +++ .../pq/pojo/vo/dataClean/LineDataExcel.java | 54 ++++ .../device/pq/utils/DataLineExcelUtil.java | 107 +++++++ .../pq/utils/FixedDynamicExcelExport.java | 61 ++-- .../pq/controller/DataVerifyController.java | 3 + .../impl/PqDataVerifyBakServiceImpl.java | 268 +++++++++++++++--- .../njcn/device/line/mapper/LineMapper.java | 2 + .../device/line/mapper/mapping/LineMapper.xml | 78 +++++ 9 files changed, 621 insertions(+), 48 deletions(-) create mode 100644 pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/LineInfoMonitorIdVO.java create mode 100644 pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/dataClean/CityDataExcel.java create mode 100644 pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/dataClean/LineDataExcel.java create mode 100644 pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/utils/DataLineExcelUtil.java diff --git a/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/LineInfoMonitorIdVO.java b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/LineInfoMonitorIdVO.java new file mode 100644 index 000000000..0e203e9c9 --- /dev/null +++ b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/LineInfoMonitorIdVO.java @@ -0,0 +1,52 @@ +package com.njcn.device.pq.pojo.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author wr + * @description + * @date 2026/2/2 15:16 + */ +@Data +public class LineInfoMonitorIdVO { + + @ApiModelProperty(name = "lineId",value = "监测点id") + private String lineId; + + @ApiModelProperty(name = "gdName",value = "供电公司名称") + private String gdName; + + @ApiModelProperty(name = "lineName",value = "监测点名称") + private String lineName; + + @ApiModelProperty(name = "loadType",value = "干扰源类型") + private String loadType; + + @ApiModelProperty(name = "objName",value = "对象名称") + private String objName; + + @ApiModelProperty(name = "subName",value = "变电站名称") + private String subName; + + @ApiModelProperty(name = "powerSubstationName", value = "电网侧变电站") + private String powerSubstationName; + + @ApiModelProperty(name = "deviceId",value = "装置Id") + private String deviceId; + + @ApiModelProperty(name = "deviceName",value = "装置名称") + private String deviceName; + + @ApiModelProperty(name = "ip",value = "装置ip") + private String ip; + + @ApiModelProperty(name = "manufacturer",value = "供应商名称") + private String manufacturer; + + @ApiModelProperty(name = "monitorId",value = "国网ID") + private String monitorId; + + @ApiModelProperty(name = "powerFlag",value = "电网标志(0-电网侧;1-非电网侧)") + private Integer powerFlag; +} diff --git a/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/dataClean/CityDataExcel.java b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/dataClean/CityDataExcel.java new file mode 100644 index 000000000..04996d498 --- /dev/null +++ b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/dataClean/CityDataExcel.java @@ -0,0 +1,44 @@ +package com.njcn.device.pq.pojo.vo.dataClean; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * @version 1.0.0 + * @author: chenchao + * @date: 2022/07/18 11:04 + */ +@Getter +@Setter +@EqualsAndHashCode +public class CityDataExcel implements Serializable { + + + @ExcelProperty(value = "单位") + private String deptName; + + @ExcelProperty(value = "监测终端数量") + private BigDecimal deviceNum; + + @ExcelProperty(value = "监测点个数") + private BigDecimal lineNum; + + @ExcelProperty(value = "在线率(%)") + private BigDecimal onlineRate; + + @ExcelProperty(value = "完整率(%)") + private BigDecimal integrity; + + @ExcelProperty(value = "问题监测点") + private BigDecimal abnormalNum; + + @ExcelProperty(value = "问题监测点") + private List abnormalList; + +} diff --git a/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/dataClean/LineDataExcel.java b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/dataClean/LineDataExcel.java new file mode 100644 index 000000000..7be6f2a4f --- /dev/null +++ b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/pojo/vo/dataClean/LineDataExcel.java @@ -0,0 +1,54 @@ +package com.njcn.device.pq.pojo.vo.dataClean; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * @version 1.0.0 + * @author: chenchao + * @date: 2022/07/18 11:04 + */ +@Getter +@Setter +@EqualsAndHashCode +public class LineDataExcel implements Serializable { + + @ExcelProperty(value = "序号") + private BigDecimal lineNum; + + @ExcelProperty(value = "监测点名称") + private String lineName; + + @ExcelProperty(value = "所属部门") + private String deptName; + + @ExcelProperty(value = "接入电网侧变电站名") + private String powerSubstationName; + + @ExcelProperty(value = "监测点对象名称") + private String objName; + + @ExcelProperty(value = "装置编号") + private String deviceName; + + @ExcelProperty(value = "IP地址") + private String ip; + + @ExcelProperty(value = "终端厂家") + private String manufacturer; + + @ExcelProperty(value = "在线率") + private BigDecimal onlineRate; + + @ExcelProperty(value = "数据完整性") + private BigDecimal integrity; + + @ExcelProperty(value = "国网ID") + private BigDecimal monitorId; + +} diff --git a/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/utils/DataLineExcelUtil.java b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/utils/DataLineExcelUtil.java new file mode 100644 index 000000000..e8750a5c0 --- /dev/null +++ b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/utils/DataLineExcelUtil.java @@ -0,0 +1,107 @@ +package com.njcn.device.pq.utils; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjUtil; +import com.alibaba.nacos.shaded.com.google.common.collect.Lists; +import com.njcn.device.pq.pojo.vo.dataClean.CityDataExcel; +import com.njcn.device.pq.pojo.vo.dataClean.LineDataExcel; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author wr + * @description + * @date 2026/2/2 10:13 + */ +public class DataLineExcelUtil { + + /** + * 创建监测点信息表头 + * @param FlyMonitorId + * @return + */ + public static List> lineHeader(Boolean FlyMonitorId) { + List> header = new ArrayList<>(); + header.add(Collections.singletonList("序号")); + header.add(Collections.singletonList("监测点名称")); + header.add(Collections.singletonList("所属部门")); + header.add(Collections.singletonList("接入电网侧变电站名")); + header.add(Collections.singletonList("监测点对象名称")); + header.add(Collections.singletonList("装置编号")); + header.add(Collections.singletonList("IP地址")); + header.add(Collections.singletonList("终端厂家")); + header.add(Collections.singletonList("在线率")); + header.add(Collections.singletonList("数据完整性")); + if(FlyMonitorId){ + header.add(Collections.singletonList("国网ID")); + } + return header; + } + + /** + * 监测点信息表头数据写入 + * @param data + * @return + */ + public static List> lineBody(List data) { + List> result = new ArrayList<>(); + if(CollUtil.isNotEmpty(data)){ + for (LineDataExcel datum : data) { + ArrayList row = Lists.newArrayList(datum.getLineNum(), + datum.getLineName(), + datum.getDeptName(), + datum.getPowerSubstationName(), + datum.getObjName(), + datum.getDeviceName(), + datum.getIp(), + datum.getManufacturer(), + datum.getOnlineRate(), + datum.getIntegrity()); + if(ObjUtil.isNotNull(datum.getMonitorId())){ + row.add(datum.getMonitorId()); + } + result.add(row); + } + } + // 插入一个空行 + result.add(Collections.emptyList()); + return result; + } + + /** + * 创建地市信息表头 + * @return + */ + public static List> cityHeader() { + List> header = new ArrayList<>(); + header.add(Collections.singletonList("单位")); + header.add(Collections.singletonList("监测终端数量")); + header.add(Collections.singletonList("监测点个数")); + header.add(Collections.singletonList("在线率(%)")); + header.add(Collections.singletonList("完整率(%)")); + header.add(Collections.singletonList("问题监测点")); + return header; + } + + public static List> cityBody(List data) { + List> result = new ArrayList<>(); + if(CollUtil.isNotEmpty(data)){ + for (CityDataExcel datum : data) { + ArrayList row = Lists.newArrayList(datum.getDeptName(), + datum.getDeviceNum(), + datum.getLineNum(), + datum.getOnlineRate(), + datum.getIntegrity(), + datum.getAbnormalNum()); + result.add(row); + } + } + // 插入一个空行 + result.add(Collections.emptyList()); + return result; + } + + +} diff --git a/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/utils/FixedDynamicExcelExport.java b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/utils/FixedDynamicExcelExport.java index 9b75b0510..e075a2179 100644 --- a/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/utils/FixedDynamicExcelExport.java +++ b/pqs-device/pq-device/pq-device-api/src/main/java/com/njcn/device/pq/utils/FixedDynamicExcelExport.java @@ -4,12 +4,17 @@ import com.alibaba.excel.EasyExcel; import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; +import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy; import com.njcn.device.pq.pojo.vo.dataClean.DataVerifyExcel; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.VerticalAlignment; import java.io.FileOutputStream; -import java.io.OutputStream; import java.lang.reflect.Field; import java.util.*; @@ -57,23 +62,13 @@ public class FixedDynamicExcelExport { } } - public static void exportExcelByDataSize(List dataList, OutputStream outputStream) { - // 步骤1:统计每个字段的有效数据量 + public static Map exportExcelByDataSize(List dataList) { + Map map = new HashMap<>(2); Map fieldCount = countValidData(dataList); - // 步骤2:按数据量降序排序字段名 List sortedFields = sortFields(fieldCount); - // 步骤3:构建正确的动态表头 - List> head = buildCorrectHead(sortedFields); - // 步骤4:构建对应顺序的行数据 - List> data = buildRowData(dataList, sortedFields); - - // 步骤5:导出Excel(含列宽设置) - EasyExcel.write(outputStream) - .head(head) - .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20)) - .registerWriteHandler(new FreezeHeaderHandler()) // 用修复后的表头 - .sheet("数据统计") - .doWrite(data); + map.put("head", buildCorrectHead(sortedFields)); + map.put("data", buildRowData(dataList, sortedFields)); + return map; } public static class FreezeHeaderHandler implements SheetWriteHandler { @@ -91,6 +86,40 @@ public class FixedDynamicExcelExport { } } + public static HorizontalCellStyleStrategy writeCenterStyle() { + // 内容的策略 + WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); + //设置 自动换行 + contentWriteCellStyle.setWrapped(true); + //设置 垂直居中 + contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + //设置 水平居中 + contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + //设置边框样式 + contentWriteCellStyle.setBorderLeft(BorderStyle.THIN); + contentWriteCellStyle.setBorderTop(BorderStyle.THIN); + contentWriteCellStyle.setBorderRight(BorderStyle.THIN); + contentWriteCellStyle.setBorderBottom(BorderStyle.THIN); + + WriteFont bodyWriteFont = new WriteFont(); + bodyWriteFont.setFontHeightInPoints((short) 11); + bodyWriteFont.setBold(false); + bodyWriteFont.setFontName("宋体"); + contentWriteCellStyle.setWriteFont(bodyWriteFont); + + // 头部 + WriteCellStyle headWriteCellStyle = new WriteCellStyle(); + // 设置字体居中 + headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); + WriteFont headWriteFont = new WriteFont(); + // 设置字体大小为20 + headWriteFont.setFontHeightInPoints((short) 11); + headWriteFont.setBold(false); + headWriteFont.setFontName("宋体"); + headWriteCellStyle.setWriteFont(headWriteFont); + + return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); + } // ★ 修复点1:构建正确的表头(每个列名独立成List) private static List> buildCorrectHead(List allFields) { List> head = new ArrayList<>(); diff --git a/pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/controller/DataVerifyController.java b/pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/controller/DataVerifyController.java index e48088520..336ccfce9 100644 --- a/pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/controller/DataVerifyController.java +++ b/pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/controller/DataVerifyController.java @@ -1,6 +1,7 @@ package com.njcn.device.pq.controller; +import cn.hutool.core.date.DateUtil; import com.njcn.common.pojo.annotation.OperateInfo; import com.njcn.common.pojo.enums.common.LogEnum; import com.njcn.common.pojo.enums.response.CommonResponseEnum; @@ -155,6 +156,8 @@ public class DataVerifyController extends BaseController { public void dataVerifyExcel(HttpServletResponse response, MonitorBaseParam monitorBaseParam) throws IOException { response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); + monitorBaseParam.setSearchBeginTime(DateUtil.beginOfDay(DateUtil.parse(monitorBaseParam.getSearchBeginTime())).toString()); + monitorBaseParam.setSearchEndTime(DateUtil.endOfDay(DateUtil.parse(monitorBaseParam.getSearchEndTime())).toString()); iPqDataVerifyBakService.dataVerifyExcel(response, monitorBaseParam); } diff --git a/pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/service/impl/PqDataVerifyBakServiceImpl.java b/pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/service/impl/PqDataVerifyBakServiceImpl.java index 4a9a17e05..6024a3098 100644 --- a/pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/service/impl/PqDataVerifyBakServiceImpl.java +++ b/pqs-device/pq-device/pq-device-boot/src/main/java/com/njcn/device/pq/service/impl/PqDataVerifyBakServiceImpl.java @@ -4,6 +4,7 @@ package com.njcn.device.pq.service.impl; import cn.hutool.core.codec.Base64; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.*; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONArray; @@ -11,29 +12,39 @@ import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONTokener; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.alibaba.excel.write.metadata.WriteTable; +import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.njcn.common.pojo.dto.SimpleDTO; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.dataProcess.api.PqReasonableRangeFeignClient; import com.njcn.dataProcess.enums.DataCleanEnum; import com.njcn.dataProcess.param.DataCleanParam; import com.njcn.dataProcess.pojo.dto.PqReasonableRangeDto; +import com.njcn.device.common.mapper.onlinerate.OnLineRateMapper; +import com.njcn.device.common.service.GeneralDeviceService; import com.njcn.device.line.mapper.LineMapper; import com.njcn.device.line.service.DeptLineService; import com.njcn.device.pq.constant.Param; import com.njcn.device.pq.enums.LineBaseEnum; import com.njcn.device.pq.mapper.PqDataVerifyBakMapper; +import com.njcn.device.pq.pojo.dto.GeneralDeviceDTO; +import com.njcn.device.pq.pojo.param.DeviceInfoParam; +import com.njcn.device.pq.pojo.param.OnlineRateParam; import com.njcn.device.pq.pojo.param.dataClean.MonitorBaseParam; import com.njcn.device.pq.pojo.po.DeptLine; import com.njcn.device.pq.pojo.po.PqDataVerifyBak; -import com.njcn.device.pq.pojo.vo.AreaLineInfoVO; -import com.njcn.device.pq.pojo.vo.LineDetailDataVO; +import com.njcn.device.pq.pojo.vo.*; import com.njcn.device.pq.pojo.vo.dataClean.*; import com.njcn.device.pq.service.CommTerminalService; import com.njcn.device.pq.service.IPqDataVerifyBakService; +import com.njcn.device.pq.utils.DataLineExcelUtil; +import com.njcn.device.rstatintegrity.mapper.RStatIntegrityDMapper; import com.njcn.oss.utils.FileStorageUtil; -import com.njcn.poi.excel.ExcelUtil; import com.njcn.supervision.api.UserLedgerFeignClient; import com.njcn.system.api.DictTreeFeignClient; import lombok.RequiredArgsConstructor; @@ -43,6 +54,7 @@ import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; +import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; @@ -52,6 +64,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import static com.njcn.device.pq.utils.FixedDynamicExcelExport.exportExcelByDataSize; +import static com.njcn.device.pq.utils.FixedDynamicExcelExport.writeCenterStyle; /** *

@@ -75,6 +88,9 @@ public class PqDataVerifyBakServiceImpl extends ServiceImpl monitorIds = commTerminalService.getRunMonitorByDept(monitorBaseParam); - monitorBaseParam.setMonitorIds(monitorIds); - } - List dataVerifyExcels = this.baseMapper.selectDataVerifySum(monitorBaseParam); - List ids = dataVerifyExcels.stream().map(DataVerifyExcel::getLineId).collect(Collectors.toList()); - List areaLineInfoVOList = lineMapper.getBaseLineAreaInfo(ids, null, null); - Map map = areaLineInfoVOList.stream().collect(Collectors.toMap(AreaLineInfoVO::getLineId, Function.identity())); - for (DataVerifyExcel dataVerifyExcel : dataVerifyExcels) { - if (map.containsKey(dataVerifyExcel.getLineId())) { - AreaLineInfoVO areaLineInfoVO = map.get(dataVerifyExcel.getLineId()); - dataVerifyExcel.setCity(areaLineInfoVO.getGdName()); - dataVerifyExcel.setLineName(areaLineInfoVO.getLineName()); - dataVerifyExcel.setLoadType(areaLineInfoVO.getLoadType()); - dataVerifyExcel.setObjName(areaLineInfoVO.getObjName()); - dataVerifyExcel.setStationName(areaLineInfoVO.getSubName()); - dataVerifyExcel.setPowerSubstationName(areaLineInfoVO.getPowerSubstationName()); - dataVerifyExcel.setDevName(areaLineInfoVO.getDeviceName()); - dataVerifyExcel.setIp(areaLineInfoVO.getIp()); - dataVerifyExcel.setManufacturer(areaLineInfoVO.getManufacturer()); + DeviceInfoParam param = new DeviceInfoParam(); + param.setDeptIndex(monitorBaseParam.getDeptId()); + param.setStatisticalType(new SimpleDTO()); + //获取终端台账类信息 + List deviceInfo = deviceService.getDeviceInfo(param, Arrays.asList(0), Arrays.asList(1)); + List lineIds = deviceInfo.stream().flatMap(x -> x.getLineIndexes().stream()).distinct().collect(Collectors.toList()); + List devIds = deviceInfo.stream().flatMap(x -> x.getDeviceIndexes().stream()).distinct().collect(Collectors.toList()); + List areaLineInfoVOList = lineMapper.getBaseLineInfoMonitorIdInfo(lineIds); + List monitorLine = areaLineInfoVOList.stream().filter(x -> StrUtil.isNotBlank(x.getMonitorId())).collect(Collectors.toList()); + List gridSide = areaLineInfoVOList.stream().filter(x -> x.getPowerFlag() == 0).collect(Collectors.toList()); + List nonGridSide = areaLineInfoVOList.stream().filter(x -> x.getPowerFlag() == 1).collect(Collectors.toList()); + + OnlineRateParam onlineRateParam = new OnlineRateParam(); + onlineRateParam.setIds(devIds); + onlineRateParam.setStartTime(monitorBaseParam.getSearchBeginTime()); + onlineRateParam.setEndTime(monitorBaseParam.getSearchEndTime()); + //完整率 + List integrityList = integrityDMapper.getLineIntegrityRateInfo(lineIds, + monitorBaseParam.getSearchBeginTime(), + monitorBaseParam.getSearchEndTime()); + //获取所有终端在线率 + List onlineRateByDev = onLineRateMapper.getOnlineRateByDevIds(onlineRateParam); + List cityData1 = new ArrayList<>(); + List cityData2 = new ArrayList<>(); + List cityData3 = new ArrayList<>(); + for (GeneralDeviceDTO dto : deviceInfo) { + cityData1.add(addCityDataExcel(dto, monitorLine, onlineRateByDev, integrityList)); + cityData2.add(addCityDataExcel(dto, gridSide, onlineRateByDev, integrityList)); + cityData3.add(addCityDataExcel(dto, nonGridSide, onlineRateByDev, integrityList)); } + monitorBaseParam.setMonitorIds(lineIds); + List dataVerifyExcels = this.baseMapper.selectDataVerifySum(monitorBaseParam); + Map lineInfomap = areaLineInfoVOList.stream().collect(Collectors.toMap(LineInfoMonitorIdVO::getLineId, Function.identity())); + for (DataVerifyExcel dataVerifyExcel : dataVerifyExcels) { + if (lineInfomap.containsKey(dataVerifyExcel.getLineId())) { + LineInfoMonitorIdVO areaLineInfoVO = lineInfomap.get(dataVerifyExcel.getLineId()); + dataVerifyExcel.setCity(areaLineInfoVO.getGdName()); + dataVerifyExcel.setLineName(areaLineInfoVO.getLineName()); + dataVerifyExcel.setLoadType(areaLineInfoVO.getLoadType()); + dataVerifyExcel.setObjName(areaLineInfoVO.getObjName()); + dataVerifyExcel.setStationName(areaLineInfoVO.getSubName()); + dataVerifyExcel.setPowerSubstationName(areaLineInfoVO.getPowerSubstationName()); + dataVerifyExcel.setDevName(areaLineInfoVO.getDeviceName()); + dataVerifyExcel.setIp(areaLineInfoVO.getIp()); + dataVerifyExcel.setManufacturer(areaLineInfoVO.getManufacturer()); + } + } + dataVerifyExcels.sort(Comparator + .comparing(DataVerifyExcel::getAllTime, Comparator.reverseOrder()) + .thenComparing((DataVerifyExcel item) -> item.getCity() + "_" + item.getStationName() + "_" + item.getDevName()) + ); + Map map = exportExcelByDataSize(dataVerifyExcels); + // 步骤5:导出Excel(含列宽设置) + ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()) + .registerWriteHandler(new SimpleColumnWidthStyleStrategy(20)) + .registerWriteHandler(writeCenterStyle()).build(); + WriteSheet writeSheet0 = EasyExcel.writerSheet("监测点异常指标统计").build(); + WriteTable writeTable0 = EasyExcel.writerTable(0).needHead(Boolean.TRUE).head(map.get("head")).build(); + excelWriter.write(map.get("data"), writeSheet0, writeTable0); + + Map> cityData = new HashMap<>(); + cityData.put(1, cityData1); + cityData.put(2, cityData2); + cityData.put(3, cityData3); + + Map> lineData = new HashMap<>(); + addLineDataExcel(cityData1, areaLineInfoVOList, onlineRateByDev, integrityList, lineData, 1); + addLineDataExcel(cityData2, areaLineInfoVOList, onlineRateByDev, integrityList, lineData, 2); + addLineDataExcel(cityData3, areaLineInfoVOList, onlineRateByDev, integrityList, lineData, 3); + + excelExtracted(excelWriter, "数据质量", new HashMap<>(), cityData, true); + excelExtracted(excelWriter, "数据质量表格", lineData, new HashMap<>(), false); + excelWriter.finish(); + } + } + + private void addLineDataExcel(List cityData1, List areaLineInfoVOList, List onlineRateByDev, List integrityList, Map> lineData, Integer num) { + List lineDataExcels1 = new ArrayList<>(); + List lineData1 = cityData1.stream().flatMap(x -> x.getAbnormalList().stream()).collect(Collectors.toList()); + List lineInfoData1 = areaLineInfoVOList.stream().filter(x -> lineData1.contains(x.getLineId())).collect(Collectors.toList()); + LineDataExcel lineDataExcel; + for (int i = 0; i < lineInfoData1.size(); i++) { + LineInfoMonitorIdVO dto = lineInfoData1.get(i); + lineDataExcel = new LineDataExcel(); + lineDataExcel.setLineNum(BigDecimal.valueOf((i + 1))); + lineDataExcel.setLineName(dto.getLineName()); + lineDataExcel.setDeptName(dto.getDeviceName()); + lineDataExcel.setPowerSubstationName(dto.getPowerSubstationName()); + lineDataExcel.setObjName(dto.getObjName()); + lineDataExcel.setDeviceName(dto.getDeviceName()); + lineDataExcel.setIp(dto.getIp()); + lineDataExcel.setManufacturer(dto.getManufacturer()); + lineDataExcel.setOnlineRate(onLineRate(onlineRateByDev, Arrays.asList(dto.getDeviceId()))); + lineDataExcel.setIntegrity(integrity(integrityList, Arrays.asList(dto.getLineId()))); + if (num == 1) { + lineDataExcel.setMonitorId(new BigDecimal(dto.getMonitorId())); + } + lineDataExcels1.add(lineDataExcel); + } + lineData.put(num, lineDataExcels1); + } + + + private CityDataExcel addCityDataExcel(GeneralDeviceDTO dto, List monitorLine, List onlineRateByDev, List integrityList) { + CityDataExcel data = new CityDataExcel(); + List monitorLineList = monitorLine.stream() + .filter(x -> dto.getLineIndexes().contains(x.getLineId())) + .map(LineInfoMonitorIdVO::getLineId) + .distinct() + .collect(Collectors.toList()); + List devList = monitorLine.stream() + .filter(x -> dto.getDeviceIndexes().contains(x.getDeviceId())) + .map(LineInfoMonitorIdVO::getDeviceId) + .distinct() + .collect(Collectors.toList()); + data.setDeptName(dto.getName()); + data.setDeviceNum(BigDecimal.valueOf(devList.size())); + data.setLineNum(BigDecimal.valueOf(monitorLineList.size())); + data.setOnlineRate(onLineRate(onlineRateByDev, devList)); + data.setIntegrity(integrity(integrityList, monitorLineList)); + List abnormalList = integrityList.stream() + .filter(x -> ObjUtil.isNotNull(x.getIntegrityRate())) + .filter(x -> x.getIntegrityRate().compareTo(BigDecimal.ZERO) == 0) + .filter(x -> monitorLineList.contains(x.getLineIndex())) + .map(RStatIntegrityVO::getLineIndex) + .distinct() + .collect(Collectors.toList()); + data.setAbnormalNum(BigDecimal.valueOf(abnormalList.size())); + data.setAbnormalList(abnormalList); + return data; + } + + private BigDecimal integrity(List integrityList, List lineIds) { + //监测完整率 + List integrityDS = integrityList.stream().filter(x -> lineIds.contains(x.getLineIndex())).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(integrityDS)) { + double realTime = integrityDS.stream().mapToDouble(RStatIntegrityVO::getRealTime).sum(); + double dueTime = integrityDS.stream().mapToDouble(RStatIntegrityVO::getDueTime).sum(); + if (dueTime == 0) { + return new BigDecimal(0); + } + return NumberUtil.round(Math.min(realTime * 100.0 / dueTime, 100), 2); + } else { + return new BigDecimal(0); + } + } + + private BigDecimal onLineRate(List onlineRateByDev, List devIds) { + //终端在线率 + List onlineRateDS = onlineRateByDev.stream().filter(x -> devIds.contains(x.getDevIndex())).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(onlineRateDS)) { + double onlineTime = onlineRateDS.stream().mapToDouble(RStatOnlineRateVO::getOnlineMin).sum(); + double offlineTime = onlineRateDS.stream().mapToDouble(RStatOnlineRateVO::getOfflineMin).sum(); + if ((onlineTime + offlineTime) == 0) { + return new BigDecimal(0); + } + return NumberUtil.round(Math.min(onlineTime * 100.0 / (onlineTime + offlineTime), 100), 2); + } else { + return new BigDecimal(0); + } + } + + private void excelExtracted(ExcelWriter excelWriter, String sheetName, Map> lineData, Map> cityData, Boolean fly) { + // 构建sheet页--表示不加表头 + WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).needHead(Boolean.FALSE).build(); + // 表头的数量 + int num = 0; + Boolean first = false; + // 模拟写5张表 + for (int i = 1; i < 4; i++) { + String name = ""; + if (i == 1) { + if (fly) { + name = "一类监测点"; + } else { + name = "冀北公司一类监测点数据质量问题"; + } + first = true; + } + if (i == 2) { + if (fly) { + name = "电网侧"; + } else { + name = "冀北公司电网侧监测点数据质量问题(不包含一类监测点)"; + } + first = false; + } + if (i == 3) { + if (fly) { + name = "非电网侧"; + } else { + name = "冀北公司非电网侧问题监测点(不包含一类监测点)"; + } + first = false; + } + String finalName = name; + List> contentHeader; + if (fly) { + contentHeader = DataLineExcelUtil.cityHeader(); + } else { + contentHeader = DataLineExcelUtil.lineHeader(first); + } + List> nameHeader = contentHeader.stream().map(item -> Collections.singletonList(finalName)).collect(Collectors.toList()); + // 这里必须指定需要头,table 会继承sheet的配置,sheet配置了不需要,table 默认也是不需要 + // 创建一个表头 + WriteTable writeTable1 = EasyExcel.writerTable(num).needHead(Boolean.TRUE).head(nameHeader).build(); + excelWriter.write(new ArrayList<>(), writeSheet, writeTable1); + //创建数据 + WriteTable writeTable2 = EasyExcel.writerTable(num + 1).needHead(Boolean.TRUE).head(contentHeader).build(); + List> body; + if (fly) { + body = DataLineExcelUtil.cityBody(cityData.get(i)); + } else { + body = DataLineExcelUtil.lineBody(lineData.get(i)); + } + excelWriter.write(body, writeSheet, writeTable2); + // 插入两次表头加2 + num = num + 2; } - dataVerifyExcels.sort(Comparator - .comparing(DataVerifyExcel::getAllTime, Comparator.reverseOrder()) - .thenComparing((DataVerifyExcel item) -> item.getCity() + "_" + item.getStationName()+"_"+item.getDevName()) - ); - exportExcelByDataSize(dataVerifyExcels,response.getOutputStream()); -// Set excludeColumnFiledNames = new HashSet<>(1); -// excludeColumnFiledNames.add("lineId"); -// EasyExcel.write(response.getOutputStream(), DataVerifyExcel.class) -// .excludeColumnFiledNames(excludeColumnFiledNames).sheet("sheet") -// .doWrite(dataVerifyExcels); } diff --git a/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/line/mapper/LineMapper.java b/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/line/mapper/LineMapper.java index 8d93ea0b3..28b879968 100644 --- a/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/line/mapper/LineMapper.java +++ b/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/line/mapper/LineMapper.java @@ -216,6 +216,8 @@ public interface LineMapper extends BaseMapper { */ List getBaseLineAreaInfo(@Param("list") List lineIndex, @Param("searchValue") String searchValue, @Param("comFlag") Integer comFlag); + List getBaseLineInfoMonitorIdInfo(@Param("list") List lineIndex); + /** * 返回监测点信息及通讯状态 * diff --git a/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/line/mapper/mapping/LineMapper.xml b/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/line/mapper/mapping/LineMapper.xml index 3831aff44..edf504cd6 100644 --- a/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/line/mapper/mapping/LineMapper.xml +++ b/pqs-device/pq-device/pq-device-com/src/main/java/com/njcn/device/line/mapper/mapping/LineMapper.xml @@ -1948,5 +1948,83 @@ +