diff --git a/das/pom.xml b/das/pom.xml index d4d40234..df873674 100644 --- a/das/pom.xml +++ b/das/pom.xml @@ -32,6 +32,7 @@ 3.4.4 5.4.3 8.4.3 + 1.5.3 @@ -208,7 +209,11 @@ minio ${minio.version} - + + org.jfree + jfreechart + ${jfreechart.version} + 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 new file mode 100644 index 00000000..3e303709 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/controller/StatisticalAnalysisController.java @@ -0,0 +1,58 @@ +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 查询条件 + * @return TD数据库数据 + */ + @PostMapping("/trendAnalyseExport") + public void trendAnalyseExport(@RequestBody List param ,HttpServletRequest request, HttpServletResponse response) { + statisticalAnalysisService.trendAnalyseExport(param, request, response); + } + + /** + * 功率曲线Excel导出 + * @param param 查询条件 + * @return TD数据库数据 + */ + @PostMapping("/powerCurveExport") + public void powerCurveExport(@RequestBody TrendAnalyseDto param ,HttpServletRequest request, HttpServletResponse response) { + statisticalAnalysisService.powerCurveExport(param, request, response); + } + + + /** + * 趋势对比Excel导出 + * @param param 查询条件 + * @return TD数据库数据 + */ + @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/domian/dto/TrendAnalyseDto.java b/das/src/main/java/com/das/modules/page/domian/dto/TrendAnalyseDto.java new file mode 100644 index 00000000..079fe844 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/domian/dto/TrendAnalyseDto.java @@ -0,0 +1,55 @@ +package com.das.modules.page.domian.dto; + +import com.das.modules.data.domain.SnapshotValueQueryParam; +import lombok.Data; + +import java.util.List; + +/** + * 时序数据查询实体 + */ +@Data +public class TrendAnalyseDto +{ + /** + * 开始时间 + */ + private String startTime; + + /** + * 结束时间 + */ + private String endTime; + + /** + * 间隔 + */ + private String interval; + + /** + * 填充模式 + */ + private String fill; + + + /** + * 时间条件名称 + */ + private String timeName; + + + /** + * 设备属性列表 + */ + private List devices; + + /** + * 制造商 + */ + private String madeinfactory; + + /** + * 模型 + */ + private String model; +} diff --git a/das/src/main/java/com/das/modules/page/domian/dto/TrendContrastDto.java b/das/src/main/java/com/das/modules/page/domian/dto/TrendContrastDto.java new file mode 100644 index 00000000..9bf82c14 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/domian/dto/TrendContrastDto.java @@ -0,0 +1,43 @@ +package com.das.modules.page.domian.dto; + +import com.das.modules.data.domain.SnapshotValueQueryParam; +import lombok.Data; + +import java.util.List; + +/** + * 时序数据查询实体 + */ +@Data +public class TrendContrastDto +{ + /** + * 开始时间 + */ + private String startTime; + + /** + * 结束时间 + */ + private String endTime; + + /** + * 间隔 + */ + private String interval; + + /** + * 填充模式 + */ + private String fill; + + + + + /** + * 设备属性列表 + */ + private List devices; + + +} 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 new file mode 100644 index 00000000..ec4e5193 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/service/StatisticalAnalysisService.java @@ -0,0 +1,30 @@ +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 new file mode 100644 index 00000000..70ea00e2 --- /dev/null +++ b/das/src/main/java/com/das/modules/page/service/impl/StatisticalAnalysisServiceImpl.java @@ -0,0 +1,567 @@ +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.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.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 org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartUtils; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.CategoryAxis; +import org.jfree.chart.axis.CategoryLabelPositions; +import org.jfree.chart.plot.CategoryPlot; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.category.CategoryItemRenderer; +import org.jfree.chart.title.LegendTitle; +import org.jfree.chart.title.TextTitle; +import org.jfree.data.category.DefaultCategoryDataset; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class StatisticalAnalysisServiceImpl implements StatisticalAnalysisService { + + @Autowired + DataService dataService; + + @Autowired + private TheoreticalPowerCurveService theoreticalPowerCurveService; + + @Autowired + private SysIotModelFieldMapper sysIotModelFieldMapper; + + private 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) { + TSValueQueryParam tsValueQueryParam = new TSValueQueryParam(); + BeanCopyUtils.copy(trendAnalyseDto,tsValueQueryParam); + Map>> resultMap = dataService.queryTimeSeriesValues(tsValueQueryParam); + mapsList.add(resultMap); + } + //获取Excel的列 + LinkedHashMap map = getTrendColumnName(param); + List> dataList = new ArrayList<>(); + //图表数据集 + DefaultCategoryDataset dataset = new DefaultCategoryDataset(); + // 遍历数据,填充Excel和图表数据集 + setTrendAnalyseExcelValue(mapsList, dataList, map, dataset); + ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); + //设置Excel样式 + setExcelStyle(writer, map, dataList); + // 使用JFreeChart生成折线图 + createChart(dataList, writer, dataset, "趋势分析"); + //下载Excel + downloadExcel(response, writer,"趋势分析"); + } + + /** + * 功率曲线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); + List> dataList = new ArrayList<>(); + //填充功率曲线,Excel的数据集 + setPowerCurveExcelValue(resultMap, dataList, curveItemEntitieList); + //获取功率曲线的列 + LinkedHashMap map = getPowerCurveColumnName(); + //获取图表数据集 + DefaultCategoryDataset dataset = getDefaultCategoryDataset(dataList); + ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); + //设置Excel样式 + setExcelStyle(writer, map, dataList); + //使用JFreeChart生成图表 + createChart(dataList, writer, dataset, "功率曲线分析"); + //下载Excel + downloadExcel(response, writer,"功率曲线分析"); + } + + + /** + * 趋势对比Excel导出 + * @param param 查询条件 + * @return TD数据库数据 + */ + @Override + public void trendContrastExport(TrendContrastDto param, HttpServletRequest request, HttpServletResponse response) { + //根据条件获取历史数据 + TSValueQueryParam tsValueQueryParam = new TSValueQueryParam(); + BeanCopyUtils.copy(param,tsValueQueryParam); + Map>> maps = dataService.queryTimeSeriesValues(tsValueQueryParam); + //自定义别名 别名的key和实体类中的名称要对应上! + LinkedHashMap map = gettrendContrastColumnName(param); + List> dataList = new ArrayList<>(); + //图表数据集 + DefaultCategoryDataset dataset = new DefaultCategoryDataset(); + // 遍历数据,将数据添加到dataList中 + setTrendContrastExcelValue(maps, dataList, map, dataset); + ExcelWriter writer = ExcelUtil.getWriter(RandomUtil.randomInt(100, 1000) + "statistics" + ".xlsx"); + //设置Excel样式 + setExcelStyle(writer, map, dataList); + // 使用JFreeChart生成折线图 + createChart(dataList, writer, dataset, "趋势对比"); + //下载Excel + downloadExcel(response, writer,"趋势对比"); + } + + /** + * 获取图表数据集 + * + * @param dataList 数据集 + * @return 图表数据集 + */ + private DefaultCategoryDataset getDefaultCategoryDataset(List> dataList) { + DefaultCategoryDataset dataset = new DefaultCategoryDataset(); + for (Map mapData : dataList) { + Object time = mapData.get("time"); + Object speed = mapData.get("iWindSpeed"); + Object power = mapData.get("iGenPower"); + Object theorySpeed = mapData.get("theoryIWindSpeed"); + Object theoryPower = mapData.get("theoryIGenPower"); + if (speed != null && power != null) { + dataset.addValue((Float) speed, "风速实际值", (String) time); + dataset.addValue((Float) power, "功率实际值", (String) time); + } + if (theorySpeed != null && theoryPower != null) { + dataset.addValue((Float) theorySpeed, "风速理论值", (String) time); + dataset.addValue((Float) theoryPower, "功率理论值", (String) time); + } + } + return dataset; + } + + + /** + * 设置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数据集 + * @param map 表格的列 + * @param dataset 图表数据集 + */ + private void setTrendAnalyseExcelValue(List>>> mapsList, + List> dataList, + LinkedHashMap map, DefaultCategoryDataset dataset) { + 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()) { + String key = mapEntry.getKey(); + pointName = key; + 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)) + .collect(Collectors.toList()); + timesListstr.addAll(liststr); + } + if (key1.equals("values")) { + List values = (List) stringObjectEntry.getValue(); + valuesList.addAll(values); + } + } + } + } + String pointNameKey = pointName + num; + String timeKey = "time" + num; + //添加图表的数据集 + for (int j = 0; j < timesListstr.size(); j++) { + dataset.addValue(valuesList.get(j), map.get(pointNameKey), timesListstr.get(j)); + } + 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 { + 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 + * @param map + * @param dataset + */ + private void setTrendContrastExcelValue(Map>> maps, + List> dataList, + LinkedHashMap map, DefaultCategoryDataset dataset) { + 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)) + .collect(Collectors.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++; + //生成图表的数据集 + for (int j = 0; j < timesListstr.size(); j++) { + dataset.addValue(valuesList.get(j), map.get(key), timesListstr.get(j)); + } + } + } + + } + + /** + * 趋势-获取表格的列 + * * + * + * @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()) { + for (String attribute : device.getAttributes()) { + strList.add(attribute); + } + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("attribute_code", strList); + List sysIotModelFields = sysIotModelFieldMapper.selectVoList(queryWrapper); + for (SysIotModelField sysIotModelField : sysIotModelFields) { + map.put(sysIotModelField.getAttributeCode(), sysIotModelField.getAttributeName()); + } + return map; + } + + /** + * 获取功率曲线的列 + * + * @return + */ + private LinkedHashMap getPowerCurveColumnName() { + LinkedHashMap map = new LinkedHashMap<>(); + map.put("time", "时间"); + map.put("iWindSpeed", "风速"); + map.put("iGenPower", "功率"); + 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)) + .collect(Collectors.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")); + listMap.remove(i); + } + } + dataList.addAll(listMap); + } 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 + */ + 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); + ServletOutputStream out = null; + try { + // 设置请求头属性 + response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(title+".xls", StandardCharsets.UTF_8)); + out = response.getOutputStream(); + // 写出到文件 + writer.flush(out, true); + // 关闭writer,释放内存 + writer.close(); + // 此处记得关闭输出Servlet流 + IoUtil.close(out); + } catch (Exception e) { + throw new ServiceException("文件下载失败==" + e); + } + } + + /** + * 使用JFreeChart生成折线图 + * + * @param data excel数据集 + * @param writer excel对象 + * @param dataset 图表数据集 + * @param titleStr 标题 + */ + private void createChart(List> data, ExcelWriter writer, + DefaultCategoryDataset dataset, String titleStr) { + // 获取Sheet对象 + XSSFSheet xssfSheet = (XSSFSheet) writer.getSheet(); + Workbook workbook = writer.getWorkbook(); + JFreeChart chart = ChartFactory.createLineChart( + titleStr, // 图表标题 + "", // 横轴标签 + "", // 纵轴标签 + dataset, // 数据集 + PlotOrientation.VERTICAL, // 图表方向 + true, // 是否显示图例 + true, // 是否使用工具提示 + false // 是否生成URL链接 + ); + // 设置图表标题的字体 + TextTitle title = chart.getTitle(); + title.setFont(new java.awt.Font("SimSun", java.awt.Font.BOLD, 16)); + // 获取图表的绘图区域 + CategoryPlot plot = chart.getCategoryPlot(); + // 设置横轴标签 + CategoryAxis domainAxis = plot.getDomainAxis(); + domainAxis.setLabelFont(new java.awt.Font("SimSun", java.awt.Font.PLAIN, 12)); + domainAxis.setMaximumCategoryLabelLines(1); // 可以控制标签行数 + domainAxis.setCategoryMargin(3); // 控制类别之间的间距 + domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 旋转横轴标签为45度,90度为:UP_90 + domainAxis.setLabelFont(new Font("SansSerif", Font.PLAIN, 7));//调整字体大小 +// if (data.size() > 50) { +// domainAxis.setVisible(false); // 隐藏横坐标 +// } + // 设置图例的字体 + LegendTitle legend = chart.getLegend(); + if (legend != null) { + legend.setItemFont(new java.awt.Font("SimSun", java.awt.Font.PLAIN, 12)); + } + // 设置绘图区域的背景颜色 + plot.setBackgroundPaint(Color.WHITE); + // 设置绘图区域的边框 + plot.setOutlinePaint(Color.LIGHT_GRAY); + plot.setOutlineVisible(true); + // 设置网格线的颜色 + plot.setDomainGridlinePaint(Color.LIGHT_GRAY); + plot.setRangeGridlinePaint(Color.LIGHT_GRAY); + // 设置线条的宽度 + CategoryItemRenderer renderer1 = plot.getRenderer(); + renderer1.setSeriesStroke(0, new BasicStroke(2.0f)); // 设置线条宽度 + // 将图表保存为 PNG 文件 + String chartFilePath = "lineChart.png"; + // 调整图表尺寸 + int width = 750; + int height = 400; + try { + ChartUtils.saveChartAsPNG(new File(chartFilePath), chart, width, height); + } catch (IOException e) { + throw new ServiceException("图表保存为PNG文件失败==" + e); + } + byte[] bytes = null; + try { + bytes = java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(chartFilePath)); + } catch (IOException e) { + throw new ServiceException("图表保存失败==" + e); + } + int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG); + // 计算数据的最后一行,创建图表插入位置的锚点 + XSSFClientAnchor anchor = new XSSFClientAnchor(0, 1, 0, 1, 0, data.size() + 2, 15, data.size() + 30); + XSSFDrawing drawing = xssfSheet.createDrawingPatriarch(); + drawing.createPicture(anchor, pictureIdx); + } + + +} +