diff --git a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/ReportServiceImpl.java b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/ReportServiceImpl.java index 07105a673..a27eb88b0 100644 --- a/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/ReportServiceImpl.java +++ b/pqs-event/event-boot/src/main/java/com/njcn/event/service/majornetwork/Impl/ReportServiceImpl.java @@ -2021,7 +2021,7 @@ public class ReportServiceImpl implements ReportService { @Override public Page getEventReport(WaveTypeParam deviceInfoParam) { Page page = new Page<>(deviceInfoParam.getPageNum(), deviceInfoParam.getPageSize()); - List generalDeviceDTOList = generalDeviceInfoClient.getPracticalAllDeviceInfo(deviceInfoParam).getData(); + List generalDeviceDTOList = generalDeviceInfoClient.getPracticalRunDeviceInfo(deviceInfoParam).getData(); List lineIds = generalDeviceDTOList.stream().flatMap(dto -> dto.getLineIndexes().stream()).collect(Collectors.toList()); if (CollUtil.isEmpty(lineIds)) { return page; diff --git a/pqs-event/event-common/src/main/java/com/njcn/event/common/pojo/dto/EventEigDetail.java b/pqs-event/event-common/src/main/java/com/njcn/event/common/pojo/dto/EventEigDetail.java new file mode 100644 index 000000000..b0f878909 --- /dev/null +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/pojo/dto/EventEigDetail.java @@ -0,0 +1,69 @@ +package com.njcn.event.common.pojo.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @description: 暂降事件特征幅值 + * @author: denghuajun + * @time: 2019-10-17 13:59:51 + **/ +@Data +public class EventEigDetail implements Serializable { + /** + * 输出参数 + * 持续时间(单位秒) + * hold_time_rms 有效值算法持续时间 + * hold_time_dq dq变换算法持续时间 + * 波形起始点(单位度) + * POW_a A相波形起始点 + * POW_b B相波形起始点 + * POW_c C相波形起始点 + * 跳变段电压变化率(单位V/S) + * Voltagechange_Va A相跳变段电压变化率 + * Voltagechange_Vb B相跳变段电压变化率 + * Voltagechange_Vc C相跳变段电压变化率 + * 分段信息 + * SEG_T_num 分段数目 + * SEG_T0_idx 原始分段位置 + * SEG_T_idx 修正分段位置 + * 有效值分段信息 + * SEG_RMS_T_num 分段数目 + * SEG_RMS_T_idx 分段位置 + * 特征幅值(单位V) + * u_min_num 特征值个数 + * ua_min A相电压特征值 + * ub_min B相电压特征值 + * uc_min C相电压特征值 + * u3_min 三相电压特征值 + * order_min_idx 最小值位置 + * 相位跳变(单位度) + * angle_diff_ap A相相位正跳变 + * angle_diff_bp B相相位正跳变 + * angle_diff_cp C相相位正跳变 + * angle_diff_an A相相位负跳变 + * angle_diff_bn B相相位负跳变 + * angle_diff_cn C相相位负跳变 + * bph_max_value 不平衡度(单位%) + */ + public float hold_time_dq; + public float pow_a; + public float pow_b; + public float pow_c; + public float voltagechange_Va; + public float voltagechange_Vb; + public float voltagechange_Vc; + public float ua_min; + public float ub_min; + public float uc_min; + public float angle_diff_ap; + public float angle_diff_bp; + public float angle_diff_cp; + public float bph_max_value; + public String sagReason; // 暂降原因描述,数据库获取 + public String sagType; // 暂降类型描述,数据库获取 + private Integer pttype; + + +} \ No newline at end of file diff --git a/pqs-event/event-common/src/main/java/com/njcn/event/common/service/CommMonitorEventReportService.java b/pqs-event/event-common/src/main/java/com/njcn/event/common/service/CommMonitorEventReportService.java index ae6a98d5d..6bb850fdd 100644 --- a/pqs-event/event-common/src/main/java/com/njcn/event/common/service/CommMonitorEventReportService.java +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/service/CommMonitorEventReportService.java @@ -15,4 +15,7 @@ public interface CommMonitorEventReportService { void getLineExport(ExportParam exportParam, LineDetailDataCommDTO lineDetailDataCommDTO, HttpServletResponse response); + + + } diff --git a/pqs-event/event-common/src/main/java/com/njcn/event/common/service/WaveService.java b/pqs-event/event-common/src/main/java/com/njcn/event/common/service/WaveService.java new file mode 100644 index 000000000..50622d209 --- /dev/null +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/service/WaveService.java @@ -0,0 +1,14 @@ +package com.njcn.event.common.service; + +import com.njcn.advance.pojo.dto.waveAnalysis.WaveData; + +/** + * @Author: cdf + * @CreateTime: 2026-02-26 + * @Description: + */ +public interface WaveService { + + //通过优化后的方式获取波形数据 + WaveData getWavedata(String eventIndex, int flag); +} diff --git a/pqs-event/event-common/src/main/java/com/njcn/event/common/service/impl/CommMonitorEventReportServiceImpl.java b/pqs-event/event-common/src/main/java/com/njcn/event/common/service/impl/CommMonitorEventReportServiceImpl.java index dbb68f628..11a51c4d8 100644 --- a/pqs-event/event-common/src/main/java/com/njcn/event/common/service/impl/CommMonitorEventReportServiceImpl.java +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/service/impl/CommMonitorEventReportServiceImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.njcn.advance.pojo.dto.waveAnalysis.WaveData; import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.exception.BusinessException; import com.njcn.device.pms.api.MonitorClient; @@ -11,11 +12,15 @@ import com.njcn.device.pq.api.LineFeignClient; import com.njcn.echarts.pojo.constant.PicCommonData; import com.njcn.echarts.util.DrawPicUtil; import com.njcn.event.common.mapper.RmpEventDetailMapper; +import com.njcn.event.common.pojo.dto.EventEigDetail; import com.njcn.event.common.pojo.dto.LineDetailDataCommDTO; import com.njcn.event.common.service.CommMonitorEventReportService; import com.njcn.event.common.service.EventAnalysisService; import com.njcn.event.common.service.EventReportService; +import com.njcn.event.common.service.WaveService; +import com.njcn.event.common.utils.WordUtil; import com.njcn.event.common.utils.WordUtils; +import com.njcn.event.file.pojo.bo.WaveDataDetail; import com.njcn.event.pojo.param.ExportParam; import com.njcn.event.pojo.param.StatisticsParam; import com.njcn.event.pojo.po.EventDetail; @@ -35,12 +40,15 @@ import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; +import javax.servlet.http.HttpSession; +import java.io.*; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; @@ -63,16 +71,16 @@ import java.util.stream.Collectors; public class CommMonitorEventReportServiceImpl implements CommMonitorEventReportService { - private final LineFeignClient lineFeignClient; - private final DicDataFeignClient dicDataFeignClient; private final EventReportService eventReportService; //调用暂降密度接口 private final EventAnalysisService eventAnalysisService; - private final MonitorClient monitorClient; + private final RmpEventDetailMapper rmpEventDetailMapper; + private final WaveService waveService; + private final DrawPicUtil drawPicUtil; /** @@ -591,4 +599,93 @@ public class CommMonitorEventReportServiceImpl implements CommMonitorEventReport return BeanUtil.copyToList(info, EventDetail.class); } + + + /* *//** + * 生成暂降事件报告 + *//* + public void createEventReport(List index) { + try { + WordUtil wordUtil = new WordUtil(); + for (int i = 0; i < index.size(); i++) { + WaveData waveData = waveService.getWavedata(index.get(i), 1); + //数据筛选,如果是双路电压的话,会存在2个波形数据 + List waveDataDetails = waveService.filteWaveData(waveData); + if (waveData.getSunData().isEmpty()) { + throw new BusinessException(CommonResponseEnum.FAIL,"没有波形数据"); + } else { + String time = waveData.getTime(); + time = time.replace(" ", "%20"); + String title = "监测点名称:" + waveData.getLineName() + "%20发生时刻:" + time + "%20特征幅值:" + waveData.getEventValue() + "%25%20持续时间:" + waveData.getPersistTime() + "s"; + + List shun = new ArrayList<>(); + List rms = new ArrayList<>(); + if (waveDataDetails.size() == 1) { + shun.add(waveService.createShunTitle(title, waveDataDetails.get(0))); + rms.add(waveService.createRMSTitle(title, waveDataDetails.get(0))); + } else { + shun.add(waveService.createShunTitle(title, waveDataDetails.get(0))); + rms.add(waveService.createRMSTitle(title, waveDataDetails.get(0))); + for (int n = 1; n < waveDataDetails.size(); n++) { + shun.add(waveService.createShun(waveDataDetails.get(n))); + rms.add(waveService.createRMS(waveDataDetails.get(n))); + } + } + wordUtil.translateShun(i, shun); + wordUtil.translateRms(i, rms); + List eventDetailEigenvalue = eventDetailService.eventDetailEigenvalue(index.get(i)); + wordUtil.setEventDetailEigenvalue(i, eventDetailEigenvalue); + EventInfoDetail eventInfoList = .eventDetailBaseInfoByIndex(index.get(i)); + wordUtil.setEventInfoList(i, eventInfoList); + } + } + wordUtil.createReport(index.size()); + + SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmm");// 报告时分秒格式 + String fileName = "暂降事件报告_" + formatter.format(new Date()) + ".docx"; + //读取配置文件 + Properties pros = PubUtils.readProperties(getClass().getClassLoader(), "java.properties"); + String tmpPath = pros.get("TMP_PATH").toString() + File.separator + "eventreoprt"; + tmpPath = ClearPathUtil.cleanString(tmpPath); + OutputStream os = null; + File tmpfile = new File(tmpPath); + if (!tmpfile.exists()) { + tmpfile.mkdir(); + } + tmpPath = tmpPath + File.separator + fileName; + tmpPath = ClearPathUtil.cleanString(tmpPath); + File tmp = new File(tmpPath); + if (tmp.exists()) { + tmp.delete(); + } + PubUtils.createFile(tmpPath); + try { + os = new FileOutputStream(tmpPath); + if (null != wordUtil.getDocument()) { + wordUtil.getDocument().write(os); + session.setAttribute("eventFilePath", tmpPath); + session.setAttribute("eventFileName", fileName); + } + } catch (Exception e) { + session.setAttribute("eventFilePath", ""); + session.setAttribute("eventFileName", ""); + logger.error("输出暂态事件报告异常,原因为:" + e.toString()); + } finally { + try { + if (os != null) { + os.close(); + } + } catch (Exception e) { + logger.error("关闭流异常,原因为:" + e.toString()); + } + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("生成事件报告失败,方法名为:getEventReport,异常为:" + e.toString()); + result = PubUtils.assignmentResult(null, 500, "生成事件报告出错,请联系管理员"); + } + + return result; + }*/ + } diff --git a/pqs-event/event-common/src/main/java/com/njcn/event/common/service/impl/WaveServiceImpl.java b/pqs-event/event-common/src/main/java/com/njcn/event/common/service/impl/WaveServiceImpl.java new file mode 100644 index 000000000..14ff45118 --- /dev/null +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/service/impl/WaveServiceImpl.java @@ -0,0 +1,213 @@ +//package com.njcn.event.common.service.impl; +// +//import cn.hutool.core.util.StrUtil; +//import com.njcn.advance.pojo.dto.waveAnalysis.AnalyWave; +//import com.njcn.advance.pojo.dto.waveAnalysis.WaveData; +//import com.njcn.common.config.GeneralInfo; +//import com.njcn.common.pojo.exception.BusinessException; +//import com.njcn.device.pq.api.LineFeignClient; +//import com.njcn.device.pq.pojo.po.line.LineInfoVO; +//import com.njcn.device.pq.pojo.vo.AreaLineInfoVO; +//import com.njcn.event.common.mapper.RmpEventDetailMapper; +//import com.njcn.event.common.service.WaveService; +//import com.njcn.event.file.component.WaveFileComponent; +//import com.njcn.event.file.pojo.dto.WaveDataDTO; +//import com.njcn.event.file.pojo.enums.WaveFileResponseEnum; +//import com.njcn.event.file.utils.WaveUtil; +//import com.njcn.event.pojo.po.RmpEventDetailPO; +//import com.njcn.oss.constant.GeneralConstant; +//import com.njcn.oss.constant.OssPath; +//import com.njcn.oss.utils.FileStorageUtil; +//import lombok.RequiredArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.stereotype.Service; +// +//import java.io.File; +//import java.io.InputStream; +//import java.math.BigDecimal; +//import java.math.RoundingMode; +//import java.text.SimpleDateFormat; +//import java.util.List; +//import java.util.Objects; +//import java.util.stream.Collectors; +//import java.util.stream.Stream; +// +///** +// * @Author: cdf +// * @CreateTime: 2026-02-26 +// * @Description: +// */ +//@Service +//@RequiredArgsConstructor +//@Slf4j +//public class WaveServiceImpl implements WaveService { +// +// private final RmpEventDetailMapper rmpEventDetailMapper; +// +// private final WaveFileComponent waveFileComponent; +// +// private final GeneralInfo generalInfo; +// +// private final FileStorageUtil fileStorageUtil; +// private final LineFeignClient lineFeignClient; +// +// +// /** +// * 根据暂降事件索引获取波形数据 +// * 注:当前只考虑本地的波形文件 +// * +// * @param eventIndex 事件索引 +// * @param flag 抽点方式 +// */ +// @Override +// public WaveData getWavedata(String eventIndex, int flag) { +// WaveData waveData = new WaveData(); +// RmpEventDetailPO eventDetail = rmpEventDetailMapper.selectById(eventIndex); +// if (Objects.nonNull(eventDetail)) { +// //获取PT变比 +// List lineInfoVOList = lineFeignClient.getBaseLineAreaInfo(Stream.of(eventDetail.getLineId()).collect(Collectors.toList())).getData(); +// AreaLineInfoVO line = lineInfoVOList.get(0); +// waveData.setLineName(line.getLineName()); +// /*********** Modify by xuyang 添加变电站名称---Start **************/ +// waveData.setSubName(line.getSubName()); +// /*********** Modify by xuyang ---End **************/ +// waveData.setEventValue(BigDecimal.valueOf(eventDetail.getFeatureAmplitude()*100).setScale(2, RoundingMode.HALF_UP).floatValue()); +// waveData.setPersistTime(BigDecimal.valueOf(eventDetail.getDuration()*100).setScale(3, RoundingMode.HALF_UP).floatValue()); +// waveData.setTrigeTime(AnalyWave.getTimeWave()); +// if (Objects.nonNull(line)) { +// float pt1 = line.getPt1(); +// float pt2 = line.getPt2(); +// float pt = (pt1) / (pt2); +// waveData.setPt(pt); +// float ct1 = line.getCt1(); +// float ct2 = line.getCt2(); +// float ct = (ct1) / (ct2); +// waveData.setCt(ct); +// //获取接线方式 +// if (line.getVHarmonicValue() != 0) { +// //赋值abc三相名称 +// if (lineDetail.getPtType() == 2) { +// waveData.setOpen(true); +// } +// } +// } +// //严重度 +// Float yzd = eventDetail.getSeverity(); +// if (null == yzd || yzd == 0.0) { +// // 前去计算严重度 +// yzd = Float.parseFloat(getYzd(eventDetail.getPersistTime(), eventDetail.getEventValue())); +// eventDetail.setSeverity(yzd); +// //回填严重度到数据库中 +// updateEventDeatilYzd(eventDetail); +// } +// waveData.setYzd(yzd); +// //暂降发生时间 +// String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(eventDetail.getTimeId()) + "." + PubUtils.getMs(eventDetail.getMs()); +// waveData.setTime(time); +// //暂降类型 +// // 获取暂降类型的数据字典 暂降类型 +// List voltageType = redisCacheUtil.getVoltageType(); +// for (DicData dicData : voltageType) { +// if (dicData.getDicIndex().equals(eventDetail.getEventType())) { +// waveData.setWaveType(dicData.getDicName()); +// break; +// } +// } +// if (Integer.parseInt(eventDetail.getFileFlag()) == 1) { +// //根据暂降事件,返回波形文件名 +// LineInfoVO ip = lineFeignClient.getLineInfoVO(eventIndex); +// if (StringUtils.isBlank(ip)) { +// return waveData; +// } +// String path = appConfig.getWavePath(); +// path = path + File.separator + ip; +// String waveName = getWaveName(eventDetail, path); +// String pathTemp = path + File.separator + waveName; +// File file = new File(pathTemp); +// // 判断文件是否存在 +// if (file.isFile() && file.exists()) { +// System.out.println(pathTemp + "路径下,文件找到了"); +// //CFG文件路径 pathTemp +// //获取波形的瞬时值、RMS值数据 +// AnalyWave analyWave = new AnalyWave(); +// WaveDataDTO tagDataValue = waveRead(eventDetail.getWavePath(),ip); +// List> shunWave = tagDataValue.getListWaveData();//获取瞬时波形值 +// List> rmsWave = tagDataValue.getListRmsData();//RMS值波形 +// waveData.setnOneWaveNum(analyWave.getnOneWaveNum()); +// waveData.setSunData(shunWave); +// waveData.setTmpWaveTitle(tagDataValue.getWaveTitle()); +// waveData.setFirstMs(analyWave.getFirstMs()); +// waveData.setFirstTime(analyWave.getFirstTime()); +// waveData.setRmsData(rmsWave); +// waveData.setRatesCfg(analyWave.getRatesCfg()); +// /*********** Modify by yexibao ---Start **************/ +// waveData.setiPhasic(tagDataValue.getIPhasic()); +// /*********** Modify by yexibao ---End **************/ +// List tmpWaveTitle = tagDataValue.getWaveTitle(); +// /*********** Modify by yexibao ---Start **************/ +// for (int i = 0; i < tagDataValue.getIPhasic(); i++) { +// if (tmpWaveTitle.get(i + 1).substring(1).indexOf("A") > -1) +// waveData.setA(tmpWaveTitle.get(i + 1).substring(1)); +// if (tmpWaveTitle.get(i + 1).substring(1).indexOf("B") > -1) +// waveData.setB(tmpWaveTitle.get(i + 1).substring(1)); +// if (tmpWaveTitle.get(i + 1).substring(1).indexOf("C") > -1) +// waveData.setC(tmpWaveTitle.get(i + 1).substring(1)); +// } +// /*********** Modify by yexibao ---End **************/ +// +// } else { +// System.out.println(pathTemp + "路径下,文件找不到了"); +// } +// } +// } +// return waveData; +// } +// +// +// +// public WaveDataDTO waveRead(String waveName,String ip){ +// WaveDataDTO waveDataDTO; +// String cfgPath, datPath, cfgPath2, datPath2; +// if (generalInfo.getBusinessWaveFileStorage() == GeneralConstant.LOCAL_DISK) { +// cfgPath = generalInfo.getBusinessWavePath() + File.separator + ip + File.separator + waveName + GeneralConstant.CFG; +// datPath = generalInfo.getBusinessWavePath() + File.separator + ip + File.separator + waveName + GeneralConstant.DAT; +// log.info("本地磁盘波形文件路径----" + cfgPath); +// InputStream cfgStream = waveFileComponent.getFileInputStreamByFilePath(cfgPath); +// InputStream datStream = waveFileComponent.getFileInputStreamByFilePath(datPath); +// if (Objects.isNull(cfgStream) || Objects.isNull(datStream)) { +// throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND); +// } +// waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 1); +// } else { +// cfgPath = OssPath.WAVE_DIR + ip + StrUtil.SLASH + waveName + GeneralConstant.CFG; +// datPath = OssPath.WAVE_DIR + ip + StrUtil.SLASH + waveName + GeneralConstant.DAT; +// //适配文件后缀小写 +// cfgPath2 = OssPath.WAVE_DIR + ip + StrUtil.SLASH + waveName + GeneralConstant.CFG.toLowerCase(); +// datPath2 = OssPath.WAVE_DIR + ip + StrUtil.SLASH + waveName + GeneralConstant.DAT.toLowerCase(); +// log.info("文件服务器波形文件路径----" + cfgPath); +// try ( +// InputStream cfgStream = fileStorageUtil.getFileStream(cfgPath); +// InputStream datStream = fileStorageUtil.getFileStream(datPath) +// ) { +// if (Objects.isNull(cfgStream) || Objects.isNull(datStream)) { +// throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND); +// } +// waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0); +// } catch (Exception e) { +// try { +// InputStream cfgStream = fileStorageUtil.getFileStream(cfgPath2); +// InputStream datStream = fileStorageUtil.getFileStream(datPath2); +// if (Objects.isNull(cfgStream) || Objects.isNull(datStream)) { +// throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND); +// } +// waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0); +// } catch (Exception e1) { +// throw new BusinessException(WaveFileResponseEnum.WAVE_DATA_INVALID); +// } +// +// } +// } +// return waveDataDTO; +// } +//} diff --git a/pqs-event/event-common/src/main/java/com/njcn/event/common/utils/WordUtil.java b/pqs-event/event-common/src/main/java/com/njcn/event/common/utils/WordUtil.java new file mode 100644 index 000000000..e0191a272 --- /dev/null +++ b/pqs-event/event-common/src/main/java/com/njcn/event/common/utils/WordUtil.java @@ -0,0 +1,684 @@ +package com.njcn.event.common.utils; + + +import com.njcn.event.common.pojo.dto.EventEigDetail; +import com.njcn.event.pojo.po.RmpEventDetailPO; +import net.sf.json.JSONArray; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.util.Units; +import org.apache.poi.xwpf.usermodel.*; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; +import sun.misc.BASE64Decoder; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.text.SimpleDateFormat; +import java.util.*; + +public class WordUtil { + private Map> listShunPic = new HashMap<>(); + private Map> listRmsPic = new HashMap<>(); + private XWPFDocument document; + private Map> eventDetailEigenvalue = new HashMap<>(); + private Map eventInfoList = new HashMap<>(); + + public void setEventInfoList(Integer index, RmpEventDetailPO eventInfoList) { + RmpEventDetailPO tmp = eventInfoList == null ? new RmpEventDetailPO() : eventInfoList; + this.eventInfoList.put(index, tmp); + } + + public void setEventDetailEigenvalue(Integer index, List eventDetailEigenvalue) { + List tmp = eventDetailEigenvalue == null ? new ArrayList<>() : eventDetailEigenvalue; + this.eventDetailEigenvalue.put(index, tmp); + } + + public XWPFDocument getDocument() { + return document; + } + + public WordUtil() { + this.document = new XWPFDocument(); + } + + public void translateShun(Integer index, List strPic) { + BASE64Decoder decoder = new BASE64Decoder(); + List tmp = new ArrayList<>(); + + for (int i = 0; i < strPic.size(); i++) { + try { + byte[] buffer = decoder.decodeBuffer(strPic.get(i)); + tmp.add(buffer); + } catch (Exception e) { + } + } + listShunPic.put(index, tmp); + } + + public void translateRms(Integer index, List strPic) { + BASE64Decoder decoder = new BASE64Decoder(); + List tmp = new ArrayList<>(); + + for (int i = 0; i < strPic.size(); i++) { + try { + byte[] buffer = decoder.decodeBuffer(strPic.get(i)); + tmp.add(buffer); + } catch (Exception e) { + } + } + listRmsPic.put(index, tmp); + } + + public void createReport(Integer length) throws IOException, InvalidFormatException { + setHeadingStyle(this.document); + + // 添加标题 + XWPFParagraph titleParagraph = getCenterParagraph(this.document); + addLine(titleParagraph, 11); + // 设置段落居中 + XWPFRun titleParagraphBigRun = titleParagraph.createRun(); + addParagraph(titleParagraphBigRun, "宋体", 28, "000000", "暂降事件报告", true); + addLine(titleParagraph, 17); + XWPFRun titleParagraphDateRun = titleParagraph.createRun(); + addParagraph(titleParagraphDateRun, "宋体", 16, "000000", "南京灿能电力自动化股份有限公司", false); + addLine(titleParagraph, 1); + titleParagraphDateRun = titleParagraph.createRun(); + addParagraph(titleParagraphDateRun, "宋体", 14, "000000", "生成时间:" + getRightNow(), false); + addLine(titleParagraph, 8); + titleParagraph = getLeftParagraph(this.document); + titleParagraphDateRun = titleParagraph.createRun(); + addParagraph(titleParagraphDateRun, "宋体", 10, "000000", "【申明】本公司保留对报告的修改权,恕不另行通知,敬请关注最新版本。", false); + for (int m = 0; m < length; m++) { + List eventDetailEigenvaluetmp = this.eventDetailEigenvalue.get(m); + + SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + String time = sdfs.format(eventInfoList.get(m).getStartTime()); + createTitle(document, String.valueOf(m+1) + ". " +time, "标题 1", 0, 20); + createTitle(document, String.valueOf(m+1) + "." +"1. 基本信息", "标题 2", 0, 15); + XWPFParagraph introductionContentParagraph = getLeftParagraph(document); + introductionContentParagraph.setIndentationFirstLine(200); + XWPFRun introductionContentRun = introductionContentParagraph.createRun(); + addParagraph(introductionContentRun, "宋体", 11, "000000", + eventInfoList.get(m).getGdName() + "," + eventInfoList.get(m).getBdzName() + ",网络参数:" + eventInfoList.get(m).getIp() + + "," + eventInfoList.get(m).getLineName() + "于" + time + "发生暂降事件,特征幅值:" + + String.valueOf(eventInfoList.get(m).getEventValue()) + "%,持续时间:" + eventInfoList.get(m).getPersistTime() + + "s。", + false); + createTitle(document, String.valueOf(m+1) + "." +"2. 波形图", "标题 2", 0, 15); + createTitle(document, String.valueOf(m+1) + "." +"2.1 瞬时波形图", "标题 3", 200, 11); + for(int shun = 0;shun< listShunPic.get(m).size();shun++){ + createPic(document, "瞬时波形"+String.valueOf(shun), listShunPic.get(m).get(shun)); + } + createTitle(document, String.valueOf(m+1) + "." +"2.2 RMS波形图", "标题 3", 200, 11); + for(int rms = 0;rms< listRmsPic.get(m).size();rms++){ + createPic(document, "RMS波形"+String.valueOf(rms), listRmsPic.get(m).get(rms)); + } + createTitle(document, String.valueOf(m+1) + "." +"3. 多特征值", "标题 2", 0, 15); + + XWPFParagraph value = getLeftParagraph(document); + XWPFRun valuex = value.createRun(); + addParagraph(valuex, "宋体", 11, "000000", "事件总分段数:" + eventDetailEigenvaluetmp.size(), false); + addLine(value, 1); + + if (eventDetailEigenvaluetmp.size() == 0) { + continue; + } + valuex = value.createRun(); + addParagraph(valuex, "宋体", 11, "000000", "暂降原因:" + eventDetailEigenvaluetmp.get(0).getSagReason(), false); + addLine(value, 1); + + for (int i = 0; i < eventDetailEigenvaluetmp.size(); i++) { + valuex = value.createRun(); + addParagraph(valuex, "宋体", 11, "000000", "分段" + (i + 1) + "多特征值", true); + addLine(value, 1); + valuex = value.createRun(); + addParagraph(valuex, "宋体", 11, "000000", + "波形起始点相位(°):" + (eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "A" : "AB") + "相" + + eventDetailEigenvaluetmp.get(i).getPow_a() + " " + + (eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "B" : "BC") + "相" + + eventDetailEigenvaluetmp.get(i).getPow_b() + " " + + ((eventDetailEigenvaluetmp.get(0).getPttype() == 2) ? "" + : ((eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "C" : "CA") + "相" + + eventDetailEigenvaluetmp.get(i).getPow_c())), + false); + addLine(value, 1); + valuex = value.createRun(); + addParagraph(valuex, "宋体", 11, "000000", + "跳变段电压变化率(V/ms):" + (eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "A" : "AB") + "相" + + eventDetailEigenvaluetmp.get(i).getVoltagechange_Va() + " " + + (eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "B" : "BC") + "相" + + eventDetailEigenvaluetmp.get(i).getVoltagechange_Vb() + " " + + ((eventDetailEigenvaluetmp.get(0).getPttype() == 2) ? "" + : ((eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "C" : "CA") + "相" + + eventDetailEigenvaluetmp.get(i).getVoltagechange_Vc())), + false); + addLine(value, 1); + valuex = value.createRun(); + addParagraph(valuex, "宋体", 11, "000000", + "相位跳变(°):" + (eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "A" : "AB") + "相" + + eventDetailEigenvaluetmp.get(i).getAngle_diff_ap() + " " + + (eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "B" : "BC") + "相" + + eventDetailEigenvaluetmp.get(i).getAngle_diff_bp() + " " + + ((eventDetailEigenvaluetmp.get(0).getPttype() == 2) ? "" + : ((eventDetailEigenvaluetmp.get(0).getPttype() == 0 ? "C" : "CA") + "相" + + eventDetailEigenvaluetmp.get(i).getAngle_diff_cp())), + false); + /* + * addLine(value, 1); valuex = value.createRun(); + * addParagraph(valuex, "宋体", 11, "000000", "特征幅值(V):A相" + + * this.eventDetailEigenvalue.get(i).getUa_min() + " B相" + + * this.eventDetailEigenvalue.get(i).getUb_min() + " C相" + + * this.eventDetailEigenvalue.get(i).getUc_min(), false); + */ + /* + * addLine(value, 1); valuex = value.createRun(); + * addParagraph(valuex, "宋体", 11, "000000", "持续时间(ms):" + + * this.eventDetailEigenvalue.get(i).getHold_time_dq(), false); + */ + addLine(value, 1); + valuex = value.createRun(); + addParagraph(valuex, "宋体", 11, "000000", + "不平衡度(%):" + eventDetailEigenvaluetmp.get(i).getBph_max_value(), false); + addLine(value, 1); + valuex = value.createRun(); + addParagraph(valuex, "宋体", 11, "000000", "暂降类型:" + eventDetailEigenvaluetmp.get(i).getSagType(), + false); + addLine(value, 1); + } + } + } + + public void createPic(XWPFDocument document, String name, byte[] base64Info) + throws IOException, InvalidFormatException { + XWPFParagraph picParagraph = getCenterParagraph(document); + XWPFRun createRun = picParagraph.createRun(); + InputStream in = new ByteArrayInputStream(base64Info); + createRun.addPicture(in, 5, name, Units.toEMU(410), Units.toEMU(170)); + } + + public void createTitle(XWPFDocument document, String message, String style, int line, int fontSize) { + XWPFParagraph summaeTableParagraph = getLeftParagraph(document); + summaeTableParagraph.setStyle(style); + summaeTableParagraph.setIndentationFirstLine(line); + XWPFRun summaeTableRun = summaeTableParagraph.createRun(); + addParagraph(summaeTableRun, "宋体", fontSize, "000000", message, false); + } + + public void setParagraphStyle(XWPFParagraph paragraph) { + paragraph.setSpacingBefore(100); + paragraph.setSpacingAfter(100); + } + + /** + * 返回指定格式的段落 居中型 + * + * @param document + * 文档对象 + */ + public XWPFParagraph getCenterParagraph(XWPFDocument document) { + XWPFParagraph paragraph = document.createParagraph(); + setParagraphStyle(paragraph); + paragraph.setAlignment(ParagraphAlignment.CENTER); + paragraph.setVerticalAlignment(TextAlignment.CENTER); + return paragraph; + } + + /** + * 返回指定格式的段落 居左型 + * + * @param document + * 文档对象 + */ + public XWPFParagraph getLeftParagraph(XWPFDocument document) { + XWPFParagraph paragraph = document.createParagraph(); + setParagraphStyle(paragraph); + paragraph.setAlignment(ParagraphAlignment.LEFT); + return paragraph; + } + + /** + * 添加换行符 + * + * @param paragraph + * 指定段落 + * @param amount + * 行数 + */ + public void addLine(XWPFParagraph paragraph, Integer amount) { + XWPFRun run = paragraph.createRun(); + run.setFontSize(11); + for (int i = 0; i < amount; i++) { + run.addCarriageReturn(); + } + } + + /** + * 添加段落文本 + * + * @param run + * 文本执行对象 + * @param fontFamily + * 字体类型 + * @param fontSize + * 字体大小 + * @param backgroundColor + * 字体颜色 + * @param bold + * 是否加粗 + */ + public void addParagraph(XWPFRun run, String fontFamily, Integer fontSize, String backgroundColor, String message, + boolean bold) { + run.setText(message); + run.setColor(backgroundColor); + run.setFontSize(fontSize); + run.setFontFamily(fontFamily); + run.setBold(bold); + } + + /** + * 增加自定义标题样式。这里用的是stackoverflow的源码 + * + * @param docxDocument + * 目标文档 + * @param strStyleId + * 样式名称 + * @param headingLevel + * 样式级别 + */ + public void addCustomHeadingStyle(XWPFDocument docxDocument, String strStyleId, int headingLevel) { + + CTStyle ctStyle = CTStyle.Factory.newInstance(); + ctStyle.setStyleId(strStyleId); + + CTString styleName = CTString.Factory.newInstance(); + styleName.setVal(strStyleId); + ctStyle.setName(styleName); + + CTDecimalNumber indentNumber = CTDecimalNumber.Factory.newInstance(); + indentNumber.setVal(BigInteger.valueOf(headingLevel)); + + // lower number > style is more prominent in the formats bar + ctStyle.setUiPriority(indentNumber); + + CTOnOff onoffnull = CTOnOff.Factory.newInstance(); + ctStyle.setUnhideWhenUsed(onoffnull); + + // style shows up in the formats bar + ctStyle.setQFormat(onoffnull); + + // style defines a heading of the given level + CTPPr ppr = CTPPr.Factory.newInstance(); + ppr.setOutlineLvl(indentNumber); + ctStyle.setPPr(ppr); + + XWPFStyle style = new XWPFStyle(ctStyle); + + // is a null op if already defined + XWPFStyles styles = docxDocument.createStyles(); + + style.setType(STStyleType.PARAGRAPH); + styles.addStyle(style); + + } + + /** + * 设置文档中标题格式 + */ + public void setHeadingStyle(XWPFDocument document) { + addCustomHeadingStyle(document, "标题 1", 1); + addCustomHeadingStyle(document, "标题 2", 2); + addCustomHeadingStyle(document, "标题 3", 3); + addCustomHeadingStyle(document, "标题 4", 4); + addCustomHeadingStyle(document, "标题 5", 5); + addCustomHeadingStyle(document, "标题 6", 6); + addCustomHeadingStyle(document, "标题 7", 7); + } + + /** + * 给表格添加一行数据 + * + * @param paragraph + * 段落对象 + * @param row + * 行对象 + * @param data + * 不定长度的数据 + */ + public void setExcelContent(XWPFParagraph paragraph, XWPFTableRow row, String... data) { + for (int i = 0; i < data.length; i++) { + XWPFRun run = paragraph.createRun(); + run.setFontFamily("宋体"); + run.setText(data[i]); + row.getCell(i).setParagraph(paragraph); + paragraph.removeRun(0); + } + } + + /** + * 添加表头标题一行数据 + * + * @param paragraph + * 段落对象 + * @param row + * 行对象 + * @param data + * 不定长度的数据 + */ + public void setExcelHeadContent(XWPFParagraph paragraph, XWPFTableRow row, String... data) { + XWPFRun run = paragraph.createRun(); + run.setFontFamily("宋体"); + run.setBold(true); + run.setText(data[0]); + row.getCell(0).setParagraph(paragraph); + paragraph.removeRun(0); + for (int i = 1; i < data.length; i++) { + XWPFRun run1 = paragraph.createRun(); + run1.setFontFamily("宋体"); + run1.setBold(true); + run1.setText(data[i]); + row.addNewTableCell().setParagraph(paragraph); + paragraph.removeRun(0); + } + } + + /** + * 获取当前的日期 + * + * @return + */ + public String getRightNow() { + Calendar rightNow = Calendar.getInstance(); + Integer year = rightNow.get(Calendar.YEAR); + Integer month = rightNow.get(Calendar.MONTH) + 1; + Integer day = rightNow.get(rightNow.DAY_OF_MONTH); + return year + "年" + month + "月" + day + "日"; + } + + public String createWave(WaveData waveData) throws Exception { + HashMap datas = new HashMap<>(); + List> sunData = waveData.getSunData(); + int iphasic =waveData.getiPhasic(); + float pt = waveData.getPt() / 1000; + float ifmax = 0f, ifmin = 0f; + List> adata = new ArrayList<>(); + List> bdata = new ArrayList<>(); + List> cdata = new ArrayList<>(); + + if (sunData.size() > 0) { + ifmax = sunData.get(0).get(1) * pt; + ifmin = sunData.get(0).get(1) * pt; + } + List colors =new ArrayList<>(); + + for (int i = 0; i < sunData.size(); i++) { + float x = sunData.get(i).get(0); + if(iphasic==1){ + float shunFirstA = sunData.get(i).get(1) * pt; + List a = new ArrayList() { + { + add(x); + add(shunFirstA); + } + }; + adata.add(a); + ifmax = ifmax > shunFirstA ? ifmax : shunFirstA; + ifmin = ifmin < shunFirstA ? ifmin : shunFirstA; + colors.add("#DAA520"); + colors.add("#fff"); + colors.add("#fff"); + + datas.put("a", waveData.getA()); + datas.put("b", ""); + datas.put("c", ""); + }else if(iphasic==2){ + float shunFirstA = sunData.get(i).get(1) * pt; + float shunFirstB = sunData.get(i).get(2) * pt; + List a = new ArrayList() { + { + add(x); + add(shunFirstA); + } + }; + adata.add(a); + + List b = new ArrayList() { + { + add(x); + add(shunFirstB); + } + }; + bdata.add(b); + + ifmax = getMaxTwo(ifmax, shunFirstA, shunFirstB); + ifmin = getMinTwo(ifmin, shunFirstA, shunFirstB); + + colors.add("#DAA520"); + colors.add("#2E8B57"); + colors.add("#fff"); + + datas.put("a", waveData.getA()); + datas.put("b", waveData.getB()); + datas.put("c", ""); + + }else if(iphasic==3){ + float shunFirstA = sunData.get(i).get(1) * pt; + float shunFirstB = sunData.get(i).get(2) * pt; + float shunFirstC = sunData.get(i).get(3) * pt; + List a = new ArrayList() { + { + add(x); + add(shunFirstA); + } + }; + adata.add(a); + + List b = new ArrayList() { + { + add(x); + add(shunFirstB); + } + }; + bdata.add(b); + + List c = new ArrayList() { + { + add(x); + add(shunFirstC); + } + }; + cdata.add(c); + ifmax = getMax(ifmax, shunFirstA, shunFirstB, shunFirstC); + ifmin = getMin(ifmin, shunFirstA, shunFirstB, shunFirstC); + + colors.add("#DAA520"); + colors.add("#2E8B57"); + colors.add("#A52a2a"); + + datas.put("a", waveData.getA()); + datas.put("b", waveData.getB()); + datas.put("c", waveData.getC()); + } + + + } + + String time = waveData.getTime(); + time = time.replace(" ", "%20"); + float severity = waveData.getYzd(); + String strSeverity = String.valueOf(severity); + String type = waveData.getWaveType(); + + if (severity < 0) { + strSeverity = "/"; + type = "/"; + } + + String title = "监测点名称:" + waveData.getLineName() + "%20发生时刻:" + time + "%20特征幅值:" + waveData.getEventValue() + + "%25%20持续时间:" + waveData.getPersistTime() + "s"; + + + datas.put("title", title); + datas.put("adata", JSONArray.fromObject(adata).toString()); + datas.put("bdata", JSONArray.fromObject(bdata).toString()); + datas.put("cdata", JSONArray.fromObject(cdata).toString()); + datas.put("unit", "kV"); + datas.put("max", String.valueOf(ifmax)); + datas.put("min", String.valueOf(ifmin)); + datas.put("colors", JSONArray.fromObject(colors).toString()); + datas.put("cshow", Boolean.toString(!waveData.getOpenTri())); + + + String option = FreemarkerUtil.generateString("wave.ftl", "com/pqs9200/template", datas); + return EchartsUtil.generateEchartsBase64(option, "3003"); + } + + public String createRms(WaveData waveData) throws IOException, TemplateException { + List> rmsData = waveData.getRmsData(); + HashMap datas = new HashMap<>(); + int iphasic =waveData.getiPhasic(); + float pt = waveData.getPt() / 1000; + List> adata = new ArrayList<>(); + List> bdata = new ArrayList<>(); + List> cdata = new ArrayList<>(); + + List colors =new ArrayList<>(); + for (int i = 0; i < rmsData.size(); i++) { + float x = rmsData.get(i).get(0); + if(iphasic==1){ + float rmsFirstA = rmsData.get(i).get(1) * pt; + List a = new ArrayList() { + { + add(x); + add(rmsFirstA); + } + }; + adata.add(a); + + colors.add("#DAA520"); + colors.add("#fff"); + colors.add("#fff"); + + datas.put("a", waveData.getA()); + datas.put("b", ""); + datas.put("c", ""); + }else if(iphasic==2){ + float rmsFirstA = rmsData.get(i).get(1) * pt; + float rmsFirstB = rmsData.get(i).get(2) * pt; + List a = new ArrayList() { + { + add(x); + add(rmsFirstA); + } + }; + adata.add(a); + + List b = new ArrayList() { + { + add(x); + add(rmsFirstB); + } + }; + bdata.add(b); + + colors.add("#DAA520"); + colors.add("#2E8B57"); + colors.add("#fff"); + + datas.put("a", waveData.getA()); + datas.put("b", waveData.getB()); + datas.put("c", ""); + }else if(iphasic==3){ + float rmsFirstA = rmsData.get(i).get(1) * pt; + float rmsFirstB = rmsData.get(i).get(2) * pt; + float rmsFirstC = rmsData.get(i).get(3) * pt; + + List a = new ArrayList() { + { + add(x); + add(rmsFirstA); + } + }; + adata.add(a); + + List b = new ArrayList() { + { + add(x); + add(rmsFirstB); + } + }; + bdata.add(b); + + List c = new ArrayList() { + { + add(x); + add(rmsFirstC); + } + }; + cdata.add(c); + + colors.add("#DAA520"); + colors.add("#2E8B57"); + colors.add("#A52a2a"); + + datas.put("a", waveData.getA()); + datas.put("b", waveData.getB()); + datas.put("c", waveData.getC()); + } + + + } + + String time = waveData.getTime(); + time = time.replace(" ", "%20"); // 时分秒 + float severity = waveData.getYzd(); + String strSeverity = String.valueOf(severity); + String type = waveData.getWaveType(); + + if (severity < 0) { + strSeverity = "/"; + type = "/"; + } + + String title = "监测点名称:" + waveData.getLineName() + "%20发生时刻:" + time + "%20特征幅值:" + waveData.getEventValue() + + "%25%20持续时间:" + waveData.getPersistTime() + "s"; + + + datas.put("title", title); + datas.put("adata", JSONArray.fromObject(adata).toString()); + datas.put("bdata", JSONArray.fromObject(bdata).toString()); + datas.put("cdata", JSONArray.fromObject(cdata).toString()); + datas.put("unit", "kV"); + datas.put("colors", JSONArray.fromObject(colors).toString()); + datas.put("cshow", Boolean.toString(!waveData.getOpenTri())); + + String option = FreemarkerUtil.generateString("rms.ftl", "com/pqs9200/template", datas); + return EchartsUtil.generateEchartsBase64(option, "3003"); + } + + private float getMin(float temp, float tempA, float tempB, float tempC) { + temp = temp < tempA ? temp : tempA; + temp = temp < tempB ? temp : tempB; + temp = temp < tempC ? temp : tempC; + return temp; + } + + private float getMinTwo(float temp, float tempA, float tempB) { + temp = temp < tempA ? temp : tempA; + temp = temp < tempB ? temp : tempB; + return temp; + } + + private float getMax(float temp, float tempA, float tempB, float tempC) { + temp = temp > tempA ? temp : tempA; + temp = temp > tempB ? temp : tempB; + temp = temp > tempC ? temp : tempC; + return temp; + } + + private float getMaxTwo(float temp, float tempA, float tempB) { + temp = temp > tempA ? temp : tempA; + temp = temp > tempB ? temp : tempB; + return temp; + } +}