diff --git a/hzims-service-api/hzims-operational-api/src/main/java/com/hnac/hzims/operational/report/entity/RunMonthEntity.java b/hzims-service-api/hzims-operational-api/src/main/java/com/hnac/hzims/operational/report/entity/RunMonthEntity.java index f4d2eae..4e29738 100644 --- a/hzims-service-api/hzims-operational-api/src/main/java/com/hnac/hzims/operational/report/entity/RunMonthEntity.java +++ b/hzims-service-api/hzims-operational-api/src/main/java/com/hnac/hzims/operational/report/entity/RunMonthEntity.java @@ -19,6 +19,9 @@ public class RunMonthEntity extends BaseEntity { @ApiModelProperty("站点编码") private String stationCode; + @ApiModelProperty("站点名称") + private String stationName; + @ApiModelProperty("月份") private String month; diff --git a/hzims-service-api/hzims-operational-api/src/main/java/com/hnac/hzims/operational/report/vo/RunAlarmVo.java b/hzims-service-api/hzims-operational-api/src/main/java/com/hnac/hzims/operational/report/vo/RunAlarmVo.java index 5490c01..be44671 100644 --- a/hzims-service-api/hzims-operational-api/src/main/java/com/hnac/hzims/operational/report/vo/RunAlarmVo.java +++ b/hzims-service-api/hzims-operational-api/src/main/java/com/hnac/hzims/operational/report/vo/RunAlarmVo.java @@ -24,6 +24,9 @@ public class RunAlarmVo { @ApiModelProperty("告警类型 : 3-故障 21-一级告警 30-智能预警") private String type; + @ApiModelProperty("告警类型 : 3-故障 21-一级告警 30-智能预警") + private String typeName; + @ApiModelProperty("告警次数") private Integer count; @@ -32,4 +35,7 @@ public class RunAlarmVo { @ApiModelProperty("处置") private String dispose; + + @ApiModelProperty("备注") + private String memo; } diff --git a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/report/service/impl/RunMonthServiceImpl.java b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/report/service/impl/RunMonthServiceImpl.java index 96c01e4..f8909b0 100644 --- a/hzims-service/operational/src/main/java/com/hnac/hzims/operational/report/service/impl/RunMonthServiceImpl.java +++ b/hzims-service/operational/src/main/java/com/hnac/hzims/operational/report/service/impl/RunMonthServiceImpl.java @@ -6,19 +6,33 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.hnac.hzims.operational.report.entity.RunMonthEntity; import com.hnac.hzims.operational.report.mapper.RunMonthMapper; import com.hnac.hzims.operational.report.service.RunMonthService; +import com.hnac.hzims.operational.report.vo.RunAlarmVo; import com.hnac.hzims.operational.report.vo.RunDataShowVo; import com.hnac.hzims.operational.report.vo.RunDataVo; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.util.CellRangeAddress; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.core.tool.utils.BeanUtil; import org.springblade.core.tool.utils.CollectionUtil; import org.springblade.core.tool.utils.ObjectUtil; import org.springframework.stereotype.Service; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; +import java.net.URLEncoder; import java.util.List; /** @@ -74,6 +88,382 @@ public class RunMonthServiceImpl extends BaseServiceImpllambdaQuery() + .eq(RunMonthEntity::getStationCode,stationCode) + .eq(RunMonthEntity::getMonth,mon) + ); + if(ObjectUtil.isEmpty(data)){ + throw new ServiceException("站点" + mon + "月份未生成运行月报数据!"); + } + // 创建Excel文件 + // 表头、sheet页、文件名 + String headerName = data.getStationName() + "运行月报(" + mon + ")"; + HSSFWorkbook hssWB = this.drawBook(headerName,data); + // 设置头信息 + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/vnd.ms-excel"); + ServletOutputStream outputStream; + try { + //设置xlsx格式 + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(headerName + ".xls", "UTF-8")); + //创建一个输出流 + outputStream = response.getOutputStream(); + //写入数据 + hssWB.write(outputStream); + // 关闭 + outputStream.close(); + hssWB.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 手绘运行数据表格 + * @return + */ + private HSSFWorkbook drawBook(String headerName,RunMonthEntity entity) { + HSSFWorkbook hssWB = new HSSFWorkbook(); + // 添加sheet页 + HSSFSheet sheet = hssWB.createSheet(headerName); + // 绘制表格行标 + int row = 2; + // 行高 + sheet.setDefaultRowHeight((short) (20 * 25)); + // 列宽 + sheet.setDefaultColumnWidth(20); + // 首行表头 + this.firstHeader(hssWB, sheet , headerName); + // 一、表头格式设置 + this.titleHeader(hssWB, sheet,"1、运行数据总汇",row); + row =+ 1; + // 运行数据表头 + this.runDataHeader(hssWB,sheet,row); + row =+ 1; + // 运行数据填充 + List runData = JSONObject.parseObject(entity.getRunData(),new TypeReference>(){}); + row = this.runDataFill(hssWB,sheet,row,runData); + // 二、表头格式设置 + this.titleHeader(hssWB, sheet,"2、告警报表",row); + row =+ 1; + // 告警数据表头 + this.alarmHeader(hssWB,sheet,row); + row =+ 1; + // 告警数据填充 + List runAlarm = JSONObject.parseObject(entity.getAlarmData(),new TypeReference>(){}); + row = this.alarmDataFill(hssWB,sheet,row,runAlarm); + + // 三、表头格式设置 + this.titleHeader(hssWB, sheet,"3、机组负荷、温度曲线",row); + row =+ 1; + + + // 四、表头格式设置 + this.titleHeader(hssWB, sheet,"4、运行数据分析",row); + row =+ 1; + + + // 五、表头格式设置 + this.titleHeader(hssWB, sheet,"5、运行建议及其他",row); + row =+ 1; + return hssWB; + } + /** + * 设置头部 + * @param hssWB + * @param sheet + */ + private void firstHeader(HSSFWorkbook hssWB, HSSFSheet sheet,String headerName) { + // 第一行 + HSSFRow fisrtRow = sheet.createRow(0); + this.setTitileStyle(hssWB, fisrtRow, 8, true,true,HorizontalAlignment.CENTER); + // 第一个单元格 + HSSFCell headCell = fisrtRow.getCell(0); + headCell.setCellValue(headerName); + // 首行合并情况 + CellRangeAddress region1 = new CellRangeAddress(0, 0, (short) 0, (short) 8); + sheet.addMergedRegion(region1); + } + + /** + * 设置标题表头 + * @param hssWB + * @param sheet + */ + private void titleHeader(HSSFWorkbook hssWB, HSSFSheet sheet,String title,int rowNumber) { + // 创建行 + HSSFRow row_1 = sheet.createRow(rowNumber); + this.setTitileStyle(hssWB, row_1, 8, false,true,HorizontalAlignment.LEFT); + HSSFCell work_header_row_cell_1 = row_1.getCell(0); + work_header_row_cell_1.setCellValue(title); + // 行合并情况 + CellRangeAddress region1 = new CellRangeAddress(0, 0, (short) 0, (short) 8); + sheet.addMergedRegion(region1); + } + + /** + * 运行数据表头绘制 + * @param hssWB + * @param sheet + */ + private void runDataHeader(HSSFWorkbook hssWB, HSSFSheet sheet,int rowNumber) { + // 创建行 + HSSFRow row = sheet.createRow(rowNumber); + this.setTitileStyle(hssWB, row, 8, false,true,HorizontalAlignment.CENTER); + // 第一行 + HSSFCell row_cell_1 = row.getCell(0); + row_cell_1.setCellValue("组名"); + HSSFCell row_cell_2 = row.getCell(1); + row_cell_2.setCellValue("本月累计运行时长"); + HSSFCell row_cell_3 = row.getCell(2); + row_cell_3.setCellValue("机组发电量"); + HSSFCell row_cell_4 = row.getCell(3); + row_cell_4.setCellValue("计划发电量"); + HSSFCell row_cell_5 = row.getCell(4); + row_cell_5.setCellValue("实发电量"); + HSSFCell row_cell_6 = row.getCell(5); + row_cell_6.setCellValue("完成率"); + HSSFCell row_cell_7 = row.getCell(6); + row_cell_7.setCellValue("年累计发电量"); + HSSFCell row_cell_8 = row.getCell(7); + row_cell_8.setCellValue("年计划完成率"); + } + + /** + * 运行数据填充 + * @param hssWB + * @param sheet + * @param rowNumber + */ + private int runDataFill(HSSFWorkbook hssWB, HSSFSheet sheet, int rowNumber,List runData) { + if(CollectionUtil.isEmpty(runData)){ + // 绘制空表格 + this.emptyRow(hssWB,sheet,rowNumber); + return rowNumber + 1; + } + int row = rowNumber; + int endRow = rowNumber + runData.size(); + for (;row < endRow ; row ++){ + // 创建行 + HSSFRow frow = sheet.createRow(row); + this.setTitileStyle(hssWB, frow, 8, false,false,HorizontalAlignment.CENTER); + // 组名 + HSSFCell frow_cell_1 = frow.getCell(0); + frow_cell_1.setCellValue(runData.get(row - rowNumber).getDeviceName()); + // 本月累计运行时长 + HSSFCell frow_cell_2 = frow.getCell(1); + frow_cell_2.setCellValue(runData.get(row - rowNumber).getRunHours() + "小时"); + // 机组发电量 + HSSFCell frow_cell_3 = frow.getCell(2); + frow_cell_3.setCellValue(runData.get(row - rowNumber).getGenerate()); + if(row == rowNumber){ + // 计划发电量 + HSSFCell frow_cell_4 = frow.getCell(3); + frow_cell_4.setCellValue(runData.stream().mapToDouble(RunDataVo::getPlan).sum()); + // 实发电量 + HSSFCell frow_cell_5 = frow.getCell(4); + frow_cell_5.setCellValue(runData.stream().mapToDouble(RunDataVo::getGenerate).sum()); + // 完成率 + HSSFCell frow_cell_6 = frow.getCell(5); + double monSumGenerate = runData.stream().mapToDouble(RunDataVo::getGenerate).sum(); + double monSumPlan = runData.stream().mapToDouble(RunDataVo::getPlan).sum(); + if(Math.abs(monSumGenerate) > 0 && Math.abs(monSumPlan) > 0){ + frow_cell_6.setCellValue(BigDecimal.valueOf(monSumGenerate / monSumPlan * 100L).setScale(2, RoundingMode.HALF_UP).doubleValue() + "%"); + }else{ + frow_cell_6.setCellValue("0%"); + } + // 年累计发电量 + HSSFCell frow_cell_7 = frow.getCell(6); + frow_cell_7.setCellValue(runData.stream().mapToDouble(RunDataVo::getGenerateYear).sum()); + // 年计划完成率 + HSSFCell frow_cell_8 = frow.getCell(7); + double yearSumGenerate = runData.stream().mapToDouble(RunDataVo::getGenerateYear).sum(); + double yearSumPlan = runData.stream().mapToDouble(RunDataVo::getPlanYear).sum(); + if(Math.abs(yearSumGenerate) > 0 && Math.abs(yearSumPlan) > 0){ + frow_cell_8.setCellValue(BigDecimal.valueOf(yearSumGenerate / yearSumPlan * 100L).setScale(2, RoundingMode.HALF_UP).doubleValue() + "%"); + }else{ + frow_cell_8.setCellValue("0%"); + } + } + // 行合并情况 + CellRangeAddress region3 = new CellRangeAddress(rowNumber, endRow , (short) 3, (short) 3); + CellRangeAddress region4 = new CellRangeAddress(rowNumber, endRow, (short) 4, (short) 4); + CellRangeAddress region5 = new CellRangeAddress(rowNumber, endRow, (short) 5, (short) 5); + CellRangeAddress region6 = new CellRangeAddress(rowNumber, endRow, (short) 6, (short) 6); + CellRangeAddress region7 = new CellRangeAddress(rowNumber, endRow, (short) 7, (short) 7); + sheet.addMergedRegion(region3); + sheet.addMergedRegion(region4); + sheet.addMergedRegion(region5); + sheet.addMergedRegion(region6); + sheet.addMergedRegion(region7); + } + return endRow; + } + + /** + * 绘制空表格 + * @param hssWB + * @param sheet + * @param rowNumber + */ + private void emptyRow(HSSFWorkbook hssWB, HSSFSheet sheet, int rowNumber) { + // 创建行 + HSSFRow row = sheet.createRow(rowNumber); + this.setTitileStyle(hssWB, row, 8, false,false,HorizontalAlignment.CENTER); + // 第一行 + HSSFCell row_cell_1 = row.getCell(0); + row_cell_1.setCellValue(""); + HSSFCell row_cell_2 = row.getCell(1); + row_cell_2.setCellValue(""); + HSSFCell row_cell_3 = row.getCell(2); + row_cell_3.setCellValue(""); + HSSFCell row_cell_4 = row.getCell(3); + row_cell_4.setCellValue(""); + HSSFCell row_cell_5 = row.getCell(4); + row_cell_5.setCellValue(""); + HSSFCell row_cell_6 = row.getCell(5); + row_cell_6.setCellValue(""); + HSSFCell row_cell_7 = row.getCell(6); + row_cell_7.setCellValue(""); + HSSFCell row_cell_8 = row.getCell(7); + row_cell_8.setCellValue(""); + } + + + /** + * 告警数据表头绘制 + * @param hssWB + * @param sheet + */ + private void alarmHeader(HSSFWorkbook hssWB, HSSFSheet sheet,int rowNumber) { + // 创建行 + HSSFRow row = sheet.createRow(rowNumber); + this.setTitileStyle(hssWB, row, 8, false,true,HorizontalAlignment.CENTER); + // 第一行 + HSSFCell row_cell_1 = row.getCell(0); + row_cell_1.setCellValue("组名"); + HSSFCell row_cell_2 = row.getCell(1); + row_cell_2.setCellValue("首次时间"); + HSSFCell row_cell_3 = row.getCell(2); + row_cell_3.setCellValue("事件内容"); + HSSFCell row_cell_4 = row.getCell(3); + row_cell_4.setCellValue("告警类型"); + HSSFCell row_cell_5 = row.getCell(4); + row_cell_5.setCellValue("次数"); + HSSFCell row_cell_6 = row.getCell(5); + row_cell_6.setCellValue("原因初步分析"); + HSSFCell row_cell_7 = row.getCell(6); + row_cell_7.setCellValue("处置"); + HSSFCell row_cell_8 = row.getCell(7); + row_cell_8.setCellValue("备注"); + } + + /** + * 告警数据填充 + * @param hssWB + * @param sheet + * @param rowNumber + * @param runAlarm + * @return + */ + private int alarmDataFill(HSSFWorkbook hssWB, HSSFSheet sheet, int rowNumber, List runAlarm) { + if(CollectionUtil.isEmpty(runAlarm)){ + // 绘制空表格 + this.emptyRow(hssWB,sheet,rowNumber); + return rowNumber + 1; + } + int row = rowNumber; + int endRow = rowNumber + runAlarm.size(); + for (;row < endRow ; row ++){ + // 创建行 + HSSFRow frow = sheet.createRow(row); + this.setTitileStyle(hssWB, frow, 8, false,false,HorizontalAlignment.CENTER); + // 组名 + HSSFCell frow_cell_1 = frow.getCell(0); + frow_cell_1.setCellValue(runAlarm.get(row - rowNumber).getDeviceName()); + // 首次时间 + HSSFCell frow_cell_2 = frow.getCell(1); + frow_cell_2.setCellValue(runAlarm.get(row - rowNumber).getAlarmTime()); + // 事件内容 + HSSFCell frow_cell_3 = frow.getCell(2); + frow_cell_3.setCellValue(runAlarm.get(row - rowNumber).getContent()); + // 告警类型 + HSSFCell frow_cell_4 = frow.getCell(3); + frow_cell_4.setCellValue(runAlarm.get(row - rowNumber).getTypeName()); + // 次数 + HSSFCell frow_cell_5 = frow.getCell(4); + frow_cell_5.setCellValue(runAlarm.get(row - rowNumber).getCount()); + // 原因初步分析 + HSSFCell frow_cell_6 = frow.getCell(5); + frow_cell_6.setCellValue(runAlarm.get(row - rowNumber).getReason()); + // 处置 + HSSFCell frow_cell_7 = frow.getCell(6); + frow_cell_7.setCellValue(runAlarm.get(row - rowNumber).getDispose()); + // 备注 + HSSFCell frow_cell_8 = frow.getCell(7); + frow_cell_8.setCellValue(runAlarm.get(row - rowNumber).getMemo()); + } + return endRow; + } + + + /** + * 设置Titile单元格样式 + * + * @param hssWB + * @param row + * @param len + */ + private void setTitileStyle(HSSFWorkbook hssWB, HSSFRow row, int len, boolean isHead,boolean isBold,HorizontalAlignment alignment) { + HSSFCellStyle cellStyle = getHeadStyle(hssWB, alignment,isHead,isBold); + for (int i = 0; i <= len; i++) { + HSSFCell hssfcell = row.createCell(i); + hssfcell.setCellStyle(cellStyle); + } + } + + /** + * 获取表头样式 + * + * @param hssWB + * @return + */ + private HSSFCellStyle getHeadStyle(HSSFWorkbook hssWB,HorizontalAlignment alignment ,boolean isHead,boolean isBold) { + HSSFCellStyle headStyle = hssWB.createCellStyle(); + //边框 + headStyle.setBorderLeft(BorderStyle.THIN); + headStyle.setBorderRight(BorderStyle.THIN); + headStyle.setBorderTop(BorderStyle.THIN); + headStyle.setBorderBottom(BorderStyle.THIN); + //格式: 居中、居右、居左..... + headStyle.setAlignment(alignment); + headStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中 + HSSFFont font = hssWB.createFont(); + //字体: + font.setFontName("黑体"); + if(isBold){ + // 字体加粗 + font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + } + if (isHead) { + // 字体大小 + font.setFontHeightInPoints((short) 12); + //背景颜色 + headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + headStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index); + } else { + //设置字体大小 + font.setFontHeightInPoints((short) 8); + //背景颜色 + headStyle.setFillPattern(FillPatternType.NO_FILL); + headStyle.setFillForegroundColor(HSSFColor.WHITE.index); + } + // 组装 + headStyle.setFont(font); + return headStyle; } } \ No newline at end of file