From 35ce87cfb0cbde709f4cf72105af9705f21128cf Mon Sep 17 00:00:00 2001 From: yu Date: Wed, 22 Jan 2025 16:08:23 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=20=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E5=88=86=E6=9E=90=E5=AF=BC=E5=87=BAExcel=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E4=BB=A3=E7=A0=81;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StatisticalAnalysisController.java | 55 -- .../service/StatisticalAnalysisService.java | 30 - .../impl/StatisticalAnalysisServiceImpl.java | 807 ------------------ 3 files changed, 892 deletions(-) delete mode 100644 das/src/main/java/com/das/modules/page/controller/StatisticalAnalysisController.java delete mode 100644 das/src/main/java/com/das/modules/page/service/StatisticalAnalysisService.java delete mode 100644 das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java diff --git a/das/src/main/java/com/das/modules/page/controller/StatisticalAnalysisController.java b/das/src/main/java/com/das/modules/page/controller/StatisticalAnalysisController.java deleted file mode 100644 index a3772034..00000000 --- a/das/src/main/java/com/das/modules/page/controller/StatisticalAnalysisController.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.das.modules.page.controller; - - -import com.das.modules.page.domian.dto.TrendAnalyseDto; -import com.das.modules.page.domian.dto.TrendContrastDto; -import com.das.modules.page.service.StatisticalAnalysisService; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; - -@Slf4j -@RequestMapping("/api/page/statistical") -@RestController -public class StatisticalAnalysisController { - - @Autowired - private StatisticalAnalysisService statisticalAnalysisService; - - - - /** - * 趋势分析 (单机分析)Excel导出 - * @param param 查询条件 - */ - @PostMapping("/trendAnalyseExport") - public void trendAnalyseExport(@RequestBody List param ,HttpServletRequest request, HttpServletResponse response) { - statisticalAnalysisService.trendAnalyseExport(param, request, response); - } - - /** - * 功率曲线Excel导出 - * @param param 查询条件 - */ - @PostMapping("/powerCurveExport") - public void powerCurveExport(@RequestBody TrendAnalyseDto param ,HttpServletRequest request, HttpServletResponse response) { - statisticalAnalysisService.powerCurveExport(param, request, response); - } - - - /** - * 趋势对比(多机对比) Excel导出 - * @param param 查询条件 - */ - @PostMapping("/trendContrastExport") - public void trendContrastExport(@RequestBody TrendContrastDto param , HttpServletRequest request, HttpServletResponse response) { - statisticalAnalysisService.trendContrastExport(param, request, response); - } -} diff --git a/das/src/main/java/com/das/modules/page/service/StatisticalAnalysisService.java b/das/src/main/java/com/das/modules/page/service/StatisticalAnalysisService.java deleted file mode 100644 index ec4e5193..00000000 --- a/das/src/main/java/com/das/modules/page/service/StatisticalAnalysisService.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.das.modules.page.service; - -import com.das.modules.page.domian.dto.TrendAnalyseDto; -import com.das.modules.page.domian.dto.TrendContrastDto; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import java.util.List; - -public interface StatisticalAnalysisService { - - /** - * 趋势分析Excel导出 - * @param param 查询条件 - */ - void trendAnalyseExport(List param, HttpServletRequest request, HttpServletResponse response); - - /** - * 功率曲线Excel导出 - * @param param 查询条件 - */ - void powerCurveExport(TrendAnalyseDto param, HttpServletRequest request, HttpServletResponse response); - - /** - * 趋势对比Excel导出 - * @param param 查询条件 - */ - void trendContrastExport(TrendContrastDto param, HttpServletRequest request, HttpServletResponse response); - -} diff --git a/das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java b/das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java deleted file mode 100644 index b3ee1b0a..00000000 --- a/das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java +++ /dev/null @@ -1,807 +0,0 @@ -package com.das.modules.page.service.impl; - -import cn.hutool.core.io.IoUtil; -import cn.hutool.core.util.RandomUtil; -import cn.hutool.poi.excel.ExcelUtil; -import cn.hutool.poi.excel.ExcelWriter; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.das.common.constant.StatisticalAnalysisConstant; -import com.das.common.constant.StatisticalAnalysisFunctionConstant; -import com.das.common.exceptions.ServiceException; -import com.das.common.utils.BeanCopyUtils; -import com.das.modules.curve.domain.entity.CurveItemEntity; -import com.das.modules.curve.service.TheoreticalPowerCurveService; -import com.das.modules.data.domain.SnapshotValueQueryParam; -import com.das.modules.data.domain.TSValueQueryParam; -import com.das.modules.data.domain.WindowValueQueryParam; -import com.das.modules.data.service.DataService; -import com.das.modules.equipment.entity.SysIotModelField; -import com.das.modules.equipment.mapper.SysIotModelFieldMapper; -import com.das.modules.page.domian.dto.TrendAnalyseDto; -import com.das.modules.page.domian.dto.TrendContrastDto; -import com.das.modules.page.service.StatisticalAnalysisService; -import jakarta.servlet.ServletOutputStream; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xddf.usermodel.chart.*; -import org.apache.poi.xssf.usermodel.XSSFChart; -import org.apache.poi.xssf.usermodel.XSSFDrawing; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -@Slf4j -@Service -public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisService { - - @Autowired - DataService dataService; - - @Autowired - private TheoreticalPowerCurveService theoreticalPowerCurveService; - - @Autowired - private SysIotModelFieldMapper sysIotModelFieldMapper; - - private final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); - - /** - * 趋势分析Excel导出 - * - * @param param 查询条件 - */ - @Override - public void trendAnalyseExport(List param, HttpServletRequest request, HttpServletResponse response) { - //根据条件获取历史数据 - List>>> mapsList = new ArrayList<>(); - for (TrendAnalyseDto trendAnalyseDto : param) { - //瞬时值 - if (trendAnalyseDto.getCalFunction().equals(StatisticalAnalysisFunctionConstant.INTERPOLATION)){ - TSValueQueryParam tsValueQueryParam = new TSValueQueryParam(); - BeanCopyUtils.copy(trendAnalyseDto,tsValueQueryParam); - Map>> resultMap = dataService.queryTimeSeriesValues(tsValueQueryParam); - mapsList.add(resultMap); - }else { - //其他 - WindowValueQueryParam windowValueQueryParam = new WindowValueQueryParam(); - BeanCopyUtils.copy(trendAnalyseDto,windowValueQueryParam); - Map>> stringMapMap = dataService.queryWindowsValues(windowValueQueryParam); - mapsList.add(stringMapMap); - } - } - //获取Excel的列 - LinkedHashMap map = getTrendColumnName(param); - List> dataList = new ArrayList<>(); - // 遍历数据,填充Excel数据集 - setTrendAnalyseExcelValue(mapsList, dataList); - ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); - //设置Excel样式 - setExcelStyle(writer, map, dataList); - //下载Excel - downloadExcel(response, writer,StatisticalAnalysisConstant.TREND_ANALYSE); - } - - - - - /** - * 功率曲线Excel导出 - * - * @param param 查询条件 - */ - @Override - public void powerCurveExport(TrendAnalyseDto param, HttpServletRequest request, HttpServletResponse response) { - //获取理论数据 - List curveItemEntitieList = theoreticalPowerCurveService. - queryCurveItemByParent(param.getMadeinfactory(), param.getModel()); - //根据条件获取历史数据 - TSValueQueryParam tsValueQueryParam = new TSValueQueryParam(); - BeanCopyUtils.copy(param,tsValueQueryParam); - Map>> resultMap = dataService.queryTimeSeriesValues(tsValueQueryParam); - //显示曲线,需要计算功率的平均值 - if (param.getDisplayCurve()==1){ - try { - List windSpeedList = new ArrayList<>(); - List powerList = new ArrayList<>(); - getPowerCurveValueList(resultMap, powerList, windSpeedList); - List>> maps = calculateAverages(windSpeedList, powerList); - setPowerCurveValueList(resultMap, maps); - } catch (Exception e) { - log.error("计算功率曲线平均值失败:"+e.getMessage()); - } - } - List> dataList = new ArrayList<>(); - //填充功率曲线,Excel的数据集 - setPowerCurveExcelValue(resultMap, dataList, curveItemEntitieList); - //获取功率曲线的列 - LinkedHashMap map = getPowerCurveColumnName(param); - ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); - //设置Excel样式 - setExcelStyle(writer, map, dataList); - //下载Excel - downloadExcel(response, writer,StatisticalAnalysisConstant.POWER_CURVE); - } - - - - - - /** - * 趋势对比Excel导出 - * @param param 查询条件 - * @return TD数据库数据 - */ - @Override - public void trendContrastExport(TrendContrastDto param, HttpServletRequest request, HttpServletResponse response) { - Map>> maps = null; - //瞬时值,历史区间数据查询 - if (param.getCalFunction().equals(StatisticalAnalysisFunctionConstant.INTERPOLATION)){ - TSValueQueryParam tsValueQueryParam = new TSValueQueryParam(); - BeanCopyUtils.copy(param,tsValueQueryParam); - maps = dataService.queryTimeSeriesValues(tsValueQueryParam); - }else { - WindowValueQueryParam windowparam = new WindowValueQueryParam(); - BeanCopyUtils.copy(param,windowparam); - maps = dataService.queryWindowsValues(windowparam); - } - //自定义别名 别名的key和实体类中的名称要对应上! - LinkedHashMap map = gettrendContrastColumnName(param); - List> dataList = new ArrayList<>(); - // 遍历数据,将数据添加到dataList中 - setTrendContrastExcelValue(maps, dataList); - ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); - //设置Excel样式 - setExcelStyle(writer, map, dataList); - //下载Excel - downloadExcel(response, writer,StatisticalAnalysisConstant.TREND_CONTRAST); - } - - - - /** - * 设置Excel样式 - * - * @param writer ExcelWriter - * @param map 表格的列 - * @param dataList Excel数据集 - */ - private void setExcelStyle(ExcelWriter writer, LinkedHashMap map, List> dataList) { - //自定义别名 别名的key和实体类中的名称要对应上! - writer.setHeaderAlias(map); - //水平居中对齐,垂直中间对齐 - writer.getStyleSet().setAlign(HorizontalAlignment.CENTER, VerticalAlignment.CENTER); - //所有单元格宽25个字符 - writer.setColumnWidth(-1, 25); - // 一次性写出内容,使用默认样式,强制输出标题 - writer.write(dataList, true); - } - - /** - * 趋势分析-遍历数据,填充Excel和图表数据集 - * @param mapsList 测点历史数据 - * @param dataList Excel数据集 - */ - private void setTrendAnalyseExcelValue(List>>> mapsList, - List> dataList) { - for (int i = 0; i < mapsList.size(); i++) { - List timesListstr = new ArrayList<>(); - List valuesList = new ArrayList<>(); - int num = i + 1; - String pointName = null; - Map>> stringMapMap = mapsList.get(i); - for (Map.Entry>> stringMapEntry : stringMapMap.entrySet()) { - for (Map.Entry> mapEntry : stringMapEntry.getValue().entrySet()) { - pointName = mapEntry.getKey(); - for (Map.Entry stringObjectEntry : mapEntry.getValue().entrySet()) { - String key1 = stringObjectEntry.getKey(); - if (key1.equals("times")) { - List times = (List) stringObjectEntry.getValue(); - List liststr = times.stream() - .map(timestamp -> new Date(timestamp)) - .map(date -> sdf.format(date)) - .toList(); - timesListstr.addAll(liststr); - } - if (key1.equals("values")) { - List values = (List) stringObjectEntry.getValue(); - valuesList.addAll(values); - } - } - } - } - String pointNameKey = pointName + num; - String timeKey = "time" + num; - if (i == 0) { - for (int j = 0; j < timesListstr.size(); j++) { - Map dataMap = new HashMap<>(); - dataMap.put(timeKey, timesListstr.get(j)); - dataMap.put(pointNameKey, valuesList.get(j)); - dataList.add(dataMap); - } - } else { - if (dataList.size()< timesListstr.size()){ - for (int j = dataList.size(); j < timesListstr.size(); j++) { - Map dataMap = new HashMap<>(); - dataMap.put(timeKey, timesListstr.get(j)); - dataMap.put(pointNameKey, valuesList.get(j)); - dataList.add(dataMap); - } - } - for (int j = 0; j < timesListstr.size(); j++) { - Map stringObjectMap = dataList.get(j); - stringObjectMap.put(timeKey, timesListstr.get(j)); - stringObjectMap.put(pointNameKey, valuesList.get(j)); - } - } - } - } - - - - /** - * 趋势对比填充Excel数据集 - * - * @param dataList Excel数据集 - * @param maps 测点数据 - */ - private void setTrendContrastExcelValue(Map>> maps, - List> dataList) { - Map mapKey = new HashMap<>(); - int num =1; - int flagNum = 0; - for (Map.Entry>> stringMapEntry : maps.entrySet()) { - for (Map.Entry> mapEntry : stringMapEntry.getValue().entrySet()) { - List timesListstr = new ArrayList<>(); - List valuesList = new ArrayList<>(); - String key = mapEntry.getKey(); - if (mapKey.containsKey(key)){ - num++; - String str = key + num; - mapKey.put(str, num ); - key=str; - }else { - mapKey.put(key, num); - } - for (Map.Entry stringObjectEntry : mapEntry.getValue().entrySet()) { - String key1 = stringObjectEntry.getKey(); - if (key1.equals("times")) { - List times = (List) stringObjectEntry.getValue(); - List liststr = times.stream() - .map(timestamp -> new Date(timestamp)) - .map(date -> sdf.format(date)) - .toList(); - timesListstr.addAll(liststr); - } - if (key1.equals("values")) { - List values = (List) stringObjectEntry.getValue(); - valuesList.addAll(values); - } - } - if (flagNum == 0) { - for (int j = 0; j < timesListstr.size(); j++) { - Map dataMap = new HashMap<>(); - dataMap.put("time", timesListstr.get(j)); - dataMap.put(key, valuesList.get(j)); - dataList.add(dataMap); - } - } else { - for (int j = 0; j < timesListstr.size(); j++) { - Map stringObjectMap = dataList.get(j); - stringObjectMap.put(key, valuesList.get(j)); - } - } - flagNum++; - } - } - } - - /** - * 趋势-获取表格的列 - * @param param 查询条件 - * @return 表格的列 - */ - private LinkedHashMap getTrendColumnName(List param) { - LinkedHashMap map = new LinkedHashMap<>(); - for (int i = 0; i < param.size(); i++) { - TrendAnalyseDto trendAnalyseDto = param.get(i); - String timeName = trendAnalyseDto.getTimeName(); - int num = i + 1; - map.put("time" + num, "时间" + num); - for (SnapshotValueQueryParam device : trendAnalyseDto.getDevices()) { - //获取属性名称 - for (String attribute : device.getAttributes()) { - map.put(attribute + num, timeName); - } - } - } - return map; - } - - /** - * 趋势对比-获取表格的列 - * - * @param param 查询条件 - * @return 表格的列 - */ - private LinkedHashMap gettrendContrastColumnName(TrendContrastDto param) { - LinkedHashMap map = new LinkedHashMap<>(); - map.put("time", "时间"); - List strList = new ArrayList<>(); - for (SnapshotValueQueryParam device : param.getDevices()) { - strList.addAll(device.getAttributes()); - } - int num =1; - for (String code : strList) { - QueryWrapper queryWrapper = new QueryWrapper<>(); - queryWrapper.eq("attribute_code", code); - List sysIotModelFields = sysIotModelFieldMapper.selectVoList(queryWrapper); - for (SysIotModelField sysIotModelField : sysIotModelFields) { - if (map.containsKey(sysIotModelField.getAttributeCode())){ - num++; - map.put(sysIotModelField.getAttributeCode()+num, sysIotModelField.getAttributeName()+num ); - }else { - map.put(sysIotModelField.getAttributeCode(), sysIotModelField.getAttributeName()); - } - } - } - - return map; - } - - /** - * 获取功率曲线的列 - * @return Excel的列 - */ - private LinkedHashMap getPowerCurveColumnName(TrendAnalyseDto param) { - LinkedHashMap map = new LinkedHashMap<>(); - map.put("time", "时间"); - if (param.getWindSource().equals("原始风速")){ - map.put("AvgWindSpeed_10min", "原始风速"); - }else { - map.put("AvgWindSpeedCal_10min", "处理后风速"); - } - map.put("AvgActivePower_10min", "功率"); - map.put("theoryIWindSpeed", "理论风速"); - map.put("theoryIGenPower", "理论功率"); - return map; - } - - - /** - * 功率曲线-遍历数据,填充Excel数据集 - * - * @param maps 测点历史数据 - * @param dataList Excel数据集 - * @param curveItemEntitieList 理论数据 - */ - private void setPowerCurveExcelValue(Map>> maps, - List> dataList, List curveItemEntitieList) { - for (Map.Entry>> stringMapEntry : maps.entrySet()) { - int flagNum = 0; - for (Map.Entry> mapEntry : stringMapEntry.getValue().entrySet()) { - List timesListstr = new ArrayList<>(); - List valuesList = new ArrayList<>(); - String key = mapEntry.getKey(); - for (Map.Entry stringObjectEntry : mapEntry.getValue().entrySet()) { - String key1 = stringObjectEntry.getKey(); - if (key1.equals("times")) { - List times = (List) stringObjectEntry.getValue(); - List liststr = times.stream() - .map(timestamp -> new Date(timestamp)) - .map(date -> sdf.format(date)) - .toList(); - timesListstr.addAll(liststr); - } - if (key1.equals("values")) { - List values = (List) stringObjectEntry.getValue(); - valuesList.addAll(values); - } - } - if (flagNum == 0) { - for (int j = 0; j < timesListstr.size(); j++) { - Map dataMap = new HashMap<>(); - dataMap.put("time", timesListstr.get(j)); - dataMap.put(key, valuesList.get(j)); - dataList.add(dataMap); - } - } else { - for (int j = 0; j < timesListstr.size(); j++) { - Map stringObjectMap = dataList.get(j); - stringObjectMap.put(key, valuesList.get(j)); - } - } - flagNum++; - } - } - //转换为map - List> listMap = curveItemEntitieList.stream() - .map(entity -> { - Map map = new HashMap<>(); - map.put("theoryIWindSpeed", entity.getPower()); - map.put("theoryIGenPower", entity.getSpeed()); - return map; - }) - .collect(Collectors.toList()); - if (listMap.size() > dataList.size()) { - for (int i = 0; i < listMap.size(); i++) { - Map stringObjectMap1 = listMap.get(i); - if (dataList.size() > i) { - Map stringObjectMap = dataList.get(i); - stringObjectMap.put("theoryIWindSpeed", stringObjectMap1.get("theoryIWindSpeed")); - stringObjectMap.put("theoryIGenPower", stringObjectMap1.get("theoryIGenPower")); - }else { - HashMap theoryMaps = new HashMap<>(); - theoryMaps.put("theoryIWindSpeed", stringObjectMap1.get("theoryIWindSpeed")); - theoryMaps.put("theoryIGenPower", stringObjectMap1.get("theoryIGenPower")); - dataList.add(theoryMaps); - } - } - } else { - for (int i = 0; i < dataList.size(); i++) { - Map dataMap = dataList.get(i); - if (listMap.size() > i) { - Map stringObjectMap1 = listMap.get(i); - dataMap.put("theoryIWindSpeed", stringObjectMap1.get("theoryIWindSpeed")); - dataMap.put("theoryIGenPower", stringObjectMap1.get("theoryIGenPower")); - } - } - } - } - - - /** - * 下载Excel - * - * @param response 响应对象 - * @param writer Excel对象 - * @param title 标题 - */ - private void downloadExcel(HttpServletResponse response, ExcelWriter writer,String title) { - response.setCharacterEncoding(StandardCharsets.UTF_8.name()); - response.setContentType("application/vnd.ms-excel"); - // 清除缓存 - response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - response.setHeader("Pragma", "no-cache"); - response.setDateHeader("Expires", 0); - try { - // 设置请求头属性 - response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(title+"-"+System.currentTimeMillis()+".xls", StandardCharsets.UTF_8)); - ServletOutputStream out = response.getOutputStream(); - // 写出到文件 - writer.flush(out, true); - // 关闭writer,释放内存 - writer.close(); - // 此处记得关闭输出Servlet流 - IoUtil.close(out); - } catch (Exception e) { - throw new ServiceException("文件下载失败==" + e); - } - } - - /** - * 获取图表类别集 - * @param map Excel的列 - * @return 图表类别集 - */ - private List getCharKey(LinkedHashMap map) { - //获取图表类别集 - List chartKey = new ArrayList<>(); - for (Map.Entry stringStringEntry : map.entrySet()) { - String value = stringStringEntry.getValue(); - if (!value.contains("时间")){ - chartKey.add(value); - } - } - return chartKey; - } - - /** - * 生成折线图,并插入到Excel中 - * @param writer Sheet对象 - * @param data 测点数据集合 - * @param titleText 标题 - * @param chartKey 类别数据集 - */ - private static void addChartToExcel(ExcelWriter writer, List> data, - String titleText,List chartKey) { - try { - if (CollectionUtils.isEmpty(data)){ - return; - } - // 获取Sheet对象 - XSSFSheet sheet = (XSSFSheet) writer.getSheet(); - // 创建绘图区域 - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - int columnCount = sheet.getRow(0).getPhysicalNumberOfCells() + 1; - //图表位置,插入到最后一列+1 - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, columnCount, 0, 15, 15); - // 创建图表 - XSSFChart xssfChart = drawing.createChart(anchor); - // 设置图表标题 - xssfChart.setTitleText(titleText); - // 创建数据系列 - XDDFChartLegend legend = xssfChart.getOrAddLegend(); - legend.setPosition(LegendPosition.TOP_RIGHT); - XDDFCategoryAxis bottomAxis = xssfChart.createCategoryAxis(AxisPosition.BOTTOM); - XDDFValueAxis leftAxis = xssfChart.createValueAxis(AxisPosition.LEFT); - leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); - XDDFLineChartData chartData = (XDDFLineChartData) xssfChart.createData(ChartTypes.LINE, bottomAxis, leftAxis); - // 遍历每个系列并添加数据 - setChartData(data, titleText, chartKey, chartData, sheet); - xssfChart.plot(chartData); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * 生成散点图,并插入到 Excel 中 - * @param writer Sheet 对象 - * @param data 测点数据集合 - * @param titleText 标题 - * @param chartKey 类别数据集 - */ - private static void addScattersChartToExcel(ExcelWriter writer, List> data, - String titleText, List chartKey) { - try { - if (CollectionUtils.isEmpty(data)) { - return; - } - // 获取 Sheet 对象 - XSSFSheet sheet = (XSSFSheet) writer.getSheet(); - // 创建绘图区域 - XSSFDrawing drawing = sheet.createDrawingPatriarch(); - int columnCount = sheet.getRow(0).getPhysicalNumberOfCells() + 1; - // 图表位置,插入到最后一列+1 - ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, columnCount, 0, 15, 15); - // 创建图表 - XSSFChart xssfChart = drawing.createChart(anchor); - // 设置图表标题 - xssfChart.setTitleText(titleText); - // 创建数据系列 - XDDFChartLegend legend = xssfChart.getOrAddLegend(); - legend.setPosition(LegendPosition.TOP_RIGHT); - XDDFValueAxis bottomAxis = xssfChart.createValueAxis(AxisPosition.BOTTOM); - XDDFValueAxis leftAxis = xssfChart.createValueAxis(AxisPosition.LEFT); - leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); - // 创建散点图数据 - XDDFScatterChartData chartData = (XDDFScatterChartData) xssfChart.createData(ChartTypes.SCATTER, bottomAxis, leftAxis); - // 遍历每个系列并添加数据 - setChartDataForScatter(data, titleText, chartKey, chartData, sheet); - // 确保散点图数据点之间不连线 - for (XDDFChartData.Series series : chartData.getSeries()) { - if (series instanceof XDDFScatterChartData.Series) { - XDDFScatterChartData.Series scatterSeries = (XDDFScatterChartData.Series) series; - scatterSeries.setSmooth(false); - scatterSeries.setMarkerStyle(MarkerStyle.CIRCLE); - } - } - xssfChart.plot(chartData); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * 为散点图设置数据系列 - * @param data 测点数据集合 - * @param titleText 标题 - * @param chartKey 类别数据集 - * @param chartData 散点图数据对象 - * @param sheet Excel Sheet 对象 - */ - private static void setChartDataForScatter(List> data, String titleText, List chartKey, - XDDFScatterChartData chartData, XSSFSheet sheet) { - for (String key : chartKey) { - XDDFDataSource xAxisData = XDDFDataSourcesFactory.fromNumericCellRange(sheet, - new CellRangeAddress(1, data.size(), 0, 0)); - XDDFNumericalDataSource yAxisData = XDDFDataSourcesFactory.fromNumericCellRange(sheet, - new CellRangeAddress(1, data.size(), chartKey.indexOf(key) + 1, chartKey.indexOf(key) + 1)); - XDDFScatterChartData.Series series = (XDDFScatterChartData.Series) chartData.addSeries(xAxisData, yAxisData); - series.setTitle(key, null); - } - } - - /** - * 给每个类别,添加数据 - * @param data 测点数据 - * @param titleText 标题 - * @param chartKey 类别key - * @param chartData 图表数据 - * @param sheet sheet对象 - */ - private static void setChartData(List> data, String titleText, List chartKey, XDDFLineChartData chartData, XSSFSheet sheet) { - if (titleText.equals(StatisticalAnalysisConstant.TREND_ANALYSE)) { - int strStartRow = 0; - int strEndCol = 0; - int numStartRow = 1; - int numEndCol = 1; - for (int i = 0; i < chartKey.size(); i++) { - XDDFLineChartData.Series series = (XDDFLineChartData.Series) chartData.addSeries( - createStringDataReference(sheet, 1, data.size(), strStartRow, strEndCol), // 类别(X轴) - createNumericDataReference(sheet, 1, data.size(), numStartRow, numEndCol) // 值(Y轴) - ); - series.setTitle(chartKey.get(i), null); - strStartRow += 2; - strEndCol += 2; - numStartRow += 2; - numEndCol += 2; - } - } else { - for (int i = 0; i < chartKey.size(); i++) { - XDDFLineChartData.Series series = (XDDFLineChartData.Series) chartData.addSeries( - createStringDataReference(sheet, 1, data.size(), 0, 0), // 类别(X轴) - createNumericDataReference(sheet, 1, data.size(), i + 1, i + 1) // 值(Y轴) - ); - series.setTitle(chartKey.get(i), null); - } - } - - } - - /** - * 创建字符串数据引用 - * @return XDDFDataSource - */ - private static XDDFDataSource createStringDataReference(XSSFSheet sheet, int startRow, int endRow, int startCol, int endCol) { - CellRangeAddress ref = new CellRangeAddress(startRow, endRow, startCol, endCol); - return XDDFDataSourcesFactory.fromStringCellRange(sheet, ref); - } - - /** - * 创建值数据引用 - * @return XDDFNumericalDataSource - */ - private static XDDFNumericalDataSource createNumericDataReference(XSSFSheet sheet, int startRow, int endRow, int startCol, int endCol) { - CellRangeAddress ref = new CellRangeAddress(startRow, endRow, startCol, endCol); - return XDDFDataSourcesFactory.fromNumericCellRange(sheet, ref); - } - - - - /** - * 计算平均功率 - */ - public static List>> calculateAverages(List windSpeeds, List powers) { - // 找出最大的风速 - double maxWindSpeed = Double.MIN_VALUE; - for (double windSpeed : windSpeeds) { - if (windSpeed > maxWindSpeed) { - maxWindSpeed = windSpeed; - } - } - double interval = 0.5; - List>> result = new ArrayList<>(); - Map> dataMap = new HashMap<>(); - List windSpeedList = new ArrayList<>(); - List powerList = new ArrayList<>(); - // 从 0 开始,以 interval 为步长遍历风速 - for (double windSpeed = 0; windSpeed <= maxWindSpeed; windSpeed += interval) { - double sumPower = 0; - int count = 0; - - // 遍历输入列表,计算满足风速范围的功率总和和计数 - for (int i = 0; i < windSpeeds.size(); i++) { - double currentWindSpeed = windSpeeds.get(i); - double currentPower = powers.get(i); - - if (currentWindSpeed >= windSpeed && currentWindSpeed < windSpeed + interval) { - sumPower += currentPower; - count++; - } - } - - // 如果计数大于 0,计算平均值并添加到结果列表 - if (count > 0) { - double averagePower = sumPower / count; - windSpeedList.add(windSpeed + interval); - powerList.add(averagePower); - } - } - dataMap.put("windSpeed", windSpeedList); - dataMap.put("power", powerList); - result.add(dataMap); - return result; - } - - /** - * 根据size删除List value1的值 - */ - @NotNull - private static List delTimes(Map.Entry stringObjectEntry, List>> maps) { - int powerSize = maps.get(0).get("power").size(); - List value1 = (List) stringObjectEntry.getValue(); - List collect = IntStream.range(0, value1.size()) - .filter(i -> i < powerSize) - .mapToObj(value1::get) - .collect(Collectors.toList()); - return collect; - } - - private static void getPowerCurveValueList(Map>> resultMap, - List powerList, List windSpeedList) { - for (Map.Entry>> stringMapEntry : resultMap.entrySet()) { - for (Map.Entry> mapEntry : stringMapEntry.getValue().entrySet()) { - String key = mapEntry.getKey(); - Map value = mapEntry.getValue(); - //功率 - if (key.equals("AvgActivePower_10min")) { - for (Map.Entry stringObjectEntry : value.entrySet()) { - if (stringObjectEntry.getKey().equals("values")) { - List values = (List) stringObjectEntry.getValue(); - List doubleList = values.stream() - .map(Float::doubleValue) - .collect(Collectors.toList()); - powerList.addAll(doubleList); - } - } - } - if (key.equals("AvgWindSpeed_10min") || key.equals("AvgWindSpeedCal_10min")){ - for (Map.Entry stringObjectEntry : value.entrySet()) { - if (stringObjectEntry.getKey().equals("values")){ - List values = (List) stringObjectEntry.getValue(); - List doubleList = values.stream() - .map(Float::doubleValue) - .collect(Collectors.toList()); - windSpeedList.addAll(doubleList); - } - } - } - } - } - } - - private static void setPowerCurveValueList(Map>> resultMap, - List>> maps) { - if (CollectionUtils.isEmpty(maps)){ - return; - } - for (Map.Entry>> stringMapEntry : resultMap.entrySet()) { - for (Map.Entry> mapEntry : stringMapEntry.getValue().entrySet()) { - String key = mapEntry.getKey(); - Map value = mapEntry.getValue(); - //功率 - if (key.equals("AvgActivePower_10min")) { - for (Map.Entry stringObjectEntry : value.entrySet()) { - if (stringObjectEntry.getKey().equals("values")) { - stringObjectEntry.setValue(maps.get(0).get("power")); - } - if (stringObjectEntry.getKey().equals("times")){ - List collect = delTimes(stringObjectEntry, maps); - stringObjectEntry.setValue(collect); - } - } - } - if (key.equals("AvgWindSpeed_10min") || key.equals("AvgWindSpeedCal_10min")){ - for (Map.Entry stringObjectEntry : value.entrySet()) { - if (stringObjectEntry.getKey().equals("values")){ - stringObjectEntry.setValue(maps.get(0).get("windSpeed")); - } - if (stringObjectEntry.getKey().equals("times")){ - List collect = delTimes(stringObjectEntry, maps); - stringObjectEntry.setValue(collect); - } - } - } - } - } - } - - - -} -