package com.ruoyi.system.service.impl; import cn.hutool.core.date.format.FastDateFormat; import cn.hutool.core.io.resource.ClassPathResource; import cn.hutool.json.JSONUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillWrapper; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.system.domain.*; import com.ruoyi.system.dto.PrintExcelDTO; import com.ruoyi.system.dto.TaskResultSortDTO; import com.ruoyi.system.dto.WaterLevelDTO; import com.ruoyi.system.mapper.*; import com.ruoyi.system.paramet.AchievementQuery; import com.ruoyi.system.paramet.ScattperPlotQuery; import com.ruoyi.system.paramet.WaterLevelQuery; import com.ruoyi.system.service.AchievementService; import com.ruoyi.system.service.SiteService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.OutputStream; import java.math.BigDecimal; import java.math.RoundingMode; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.*; /** * classname: 站点信息 * description 服务实现类 */ @Service @Slf4j public class AchievementServiceImpl implements AchievementService { @Resource private TaskResultMapper taskResultMapper; @Resource private WaterLevelMapper waterLevelMapper; @Resource private SiteInfoMapper siteInfoMapper; @Resource private BerthingPointMapper berthingPointMapper; @Resource private SiteService siteService; @Autowired private BerthingPointConfigMapper berthingPointConfigMapper; @Override public Page queryAchievement(AchievementQuery achievementQuery){ if (achievementQuery.getPage() == null || achievementQuery.getSize() == null) { achievementQuery.setPage(1L); achievementQuery.setSize(10L); } return taskResultMapper.queryAllByLimit(achievementQuery ,new Page(achievementQuery.getPage(),achievementQuery.getSize())); } @Override public TaskResult queryAchievementByTaskid(String taskid){ return taskResultMapper.queryByTaskid(taskid); } @Override public Page getWaterLevelList(WaterLevelQuery waterLevelQuery){ if (waterLevelQuery.getType() == null){ waterLevelQuery.setType(1L); } if (waterLevelQuery.getPage() == null || waterLevelQuery.getSize() == null) { waterLevelQuery.setPage(1L); waterLevelQuery.setSize(10L); } return waterLevelMapper.queryAllByTime(waterLevelQuery,new Page(waterLevelQuery.getPage(),waterLevelQuery.getSize())); } @Override public boolean downAchievement(Long resultId, HttpServletResponse response) { ExcelWriter excelWriter = null; try { //查询resultId结果 TaskResult taskResult = taskResultMapper.queryById(resultId); if (taskResult == null){ throw new BaseException("该结果不存在"); } if (taskResult.getStatus() != 2){ throw new BaseException("结果未完成,不支持导出"); } //查询站点信息 SiteInfo siteInfo = siteInfoMapper.queryById(taskResult.getSiteId()); if (siteInfo == null){ throw new BaseException("该站点不存在"); } //查站点详情 SiteConfig siteConfig = siteService.queryConfig(siteInfo.getSiteId()); if (siteConfig == null){ throw new BaseException("该站点配置不存在"); } //拿断面数据 BerthingPoint berthingPoint = berthingPointMapper.queryById(taskResult.getBerthingId()); if (berthingPoint == null){ throw new BaseException("断面不存在"); } //拿停泊点数据 BerthingPointConfig berthingPointConfig = berthingPointConfigMapper.queryById(taskResult.getStopId()); if (berthingPointConfig == null){ throw new BaseException("停泊点配置不存在"); } OutputStream outputStream = response.getOutputStream(); // 模版文件 ClassPathResource classPathResource = new ClassPathResource("excel/test.xlsx"); String templateFileName = classPathResource.getFile().getPath(); excelWriter = EasyExcel.write(outputStream).withTemplate(templateFileName).excelType(ExcelTypeEnum.XLSX).autoCloseStream(Boolean.FALSE).build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); //先组装单数据 Map map = MapUtils.newHashMap(); map.put("stieName", siteInfo.getSiteName()); map.put("startTime", taskResult.getStarttime()); map.put("endTime", taskResult.getEndtime()); map.put("flowsum", taskResult.getFlowsum()); map.put("width", taskResult.getWidth()); map.put("waterlevel",taskResult.getWaterlevel()); map.put("acreagesum",taskResult.getAcreagesum()); List WspeedsList = JSONUtil.parseArray(taskResult.getWspeeds()).toList(Double.class); double averageWspeed = WspeedsList.stream().mapToDouble(d -> d).average().orElse(Double.NaN); BigDecimal averageWspeedBigDecimal = new BigDecimal(averageWspeed).setScale(2, BigDecimal.ROUND_HALF_UP); Double maxWspeed = WspeedsList.stream().max(Double::compareTo).orElse(Double.NaN); List waterlevelList = JSONUtil.parseArray(taskResult.getWaterlevels()).toList(Double.class); double averageWaterlevel = waterlevelList.stream().mapToDouble(d -> d).average().orElse(Double.NaN); BigDecimal averageWaterlevelBigDecimal = new BigDecimal(averageWaterlevel).setScale(2, BigDecimal.ROUND_HALF_UP); Double maxWaterlevel = waterlevelList.stream().max(Double::compareTo).orElse(Double.NaN); map.put("agWaterlevels",averageWaterlevelBigDecimal.toString()); map.put("maxWaterlevels",String.valueOf(maxWaterlevel)); map.put("agWspeeds",averageWspeedBigDecimal.toString()); map.put("maxWspeeds",String.valueOf(maxWspeed)); excelWriter.fill(map, writeSheet); //拿断面数据 List positionsList = JSONUtil.toList(berthingPoint.getPositions(), PrintExcelDTO.class); //组装列表 List> dataList = new ArrayList<>(); List> pgList = new ArrayList<>(); List taskX = JSONUtil.toList(taskResult.getPositions(), Double.class); List taskY = JSONUtil.toList(taskResult.getElevations(), Double.class); List pointConfigfactors = JSONUtil.toList(berthingPointConfig.getFactors(), String.class); List taskWspeeds = JSONUtil.toList(taskResult.getWspeeds(), String.class); List taskStopwspeeds = JSONUtil.toList(taskResult.getStopwspeeds(), String.class); List tasKPartwspeeds = JSONUtil.toList(taskResult.getPartwspeeds(), String.class); List acreages = JSONUtil.toList(taskResult.getAcreages(), String.class); List taskFlows = JSONUtil.toList(taskResult.getFlows(), String.class); int pnIndex = 0; for (int i = 0; i < positionsList.size(); i++) { Map data = MapUtils.newHashMap(); if (i == 0) { String str = siteConfig.getLocal() == 0 ? "左水边" : "右水边"; data.put("index", str); } else if (i == positionsList.size() - 1) { String str = siteConfig.getLocal() == 1 ? "左水边" : "右水边"; data.put("index", str); } else { data.put("index", String.valueOf(i)); } data.put("x", positionsList.get(i).getX().toString()); data.put("y", positionsList.get(i).getY().toString()); data.put("waterlevel",taskResult.getWaterlevel()); data.put("subWlevel",BigDecimal.valueOf(taskResult.getWaterlevel()).subtract(BigDecimal.valueOf(positionsList.get(i).getY()))); if (pnIndex < taskX.size()) { if (taskX.get(pnIndex).equals(positionsList.get(i).getX()) && taskY.get(pnIndex).equals(positionsList.get(i).getY())) { data.put("speed", String.valueOf(pnIndex + 1)); data.put("time", "12:00"); data.put("factors", pointConfigfactors.get(pnIndex)); data.put("wspeeds", taskWspeeds.get(pnIndex)); data.put("stopwspeeds", taskStopwspeeds.get(pnIndex)); pnIndex = pnIndex + 1; } else { data.put("speed", ""); data.put("time", ""); data.put("factors", ""); data.put("wspeeds", ""); data.put("stopwspeeds", ""); } } else { data.put("speed", ""); data.put("time", ""); data.put("factors", ""); data.put("wspeeds", ""); data.put("stopwspeeds", ""); } dataList.add(data); } pnIndex = 0; //新循环 for (int i = 0; i < positionsList.size(); i++) { Map pgData = MapUtils.newHashMap(); if (i < positionsList.size() - 1) { if (pnIndex < taskX.size()) { if (taskX.get(pnIndex).equals(positionsList.get(i).getX()) && taskY.get(pnIndex).equals(positionsList.get(i).getY())) { pgData.put("partwspeeds", tasKPartwspeeds.get(pnIndex)); if (i < 2) { pgData.put("add", acreages.get(0));//部分 } else { BigDecimal bd1 = new BigDecimal(acreages.get(i)); BigDecimal bd2 = new BigDecimal(acreages.get(i - 1)); BigDecimal add = bd1.add(bd2); pgData.put("add", add.toString()); } pgData.put("flows", taskFlows.get(pnIndex));//部分流量 pnIndex = pnIndex + 1; } else { pgData.put("partwspeeds",""); pgData.put("add", ""); pgData.put("flows", ""); } } Map temp1 = dataList.get(i); Map temp2 = dataList.get(i + 1); // 将字符串转换为BigDecimal BigDecimal bd1 = new BigDecimal(temp1.get("subWlevel").toString()); BigDecimal bd2 = new BigDecimal(temp2.get("subWlevel").toString()); // 求和 BigDecimal sum = bd1.add(bd2); // 求平均值 BigDecimal average = sum.divide(new BigDecimal(2), 2, RoundingMode.HALF_UP); pgData.put("subWlevel", average.toString()); //平均水深 bd1 = new BigDecimal(temp1.get("x").toString()); bd2 = new BigDecimal(temp2.get("x").toString()); BigDecimal subx = bd2.subtract(bd1); pgData.put("subx", subx.toString()); //间距 pgData.put("acreages", acreages.get(i)); //垂线间 pgList.add(pgData); } } dataList = insertEmptyDataOnEvenRows(dataList); pgList = insertEmptyDataOnEvenRows(pgList); excelWriter.fill(new FillWrapper("details", dataList), writeSheet); excelWriter.fill(new FillWrapper("pg", pgList), writeSheet); // 设置输出流格式以及文件名: response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); String fileName = URLEncoder.encode("质检任务", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); return true; } catch (Exception e) { log.error("下载失败", e); throw new BaseException(e.getMessage()); } finally { if (excelWriter != null) { excelWriter.close(); } } } @Override public List getScatterPlot(ScattperPlotQuery scattperPlotQuery){ try { return taskResultMapper.queryByTimeQuery(scattperPlotQuery); } catch (Exception e){ log.error("获取数据失败", e); throw new BaseException("获取数据失败"); } } @Override public void downWaterLevel(Long siteId, Long type, String startTime, String endTime, HttpServletResponse response){ WaterLevelQuery waterLevelQuery = new WaterLevelQuery(); FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss"); try { Date startTimedDate = fdf.parse(startTime); Date endTimedDate = fdf.parse(endTime); waterLevelQuery.setSiteId(siteId); waterLevelQuery.setStartTime(startTimedDate); waterLevelQuery.setEndTime(endTimedDate); waterLevelQuery.setType(type); List waterLevelList = waterLevelMapper.queryAllByTime(waterLevelQuery, new Page(1, 1000000)).getRecords(); if (!waterLevelList.isEmpty()) { response.setContentType("application/octet-stream; charset=utf-8"); String today = new SimpleDateFormat("yyyyMMdd").format(new Date()); String fileName = "downWaterLevel_".concat(today); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build(); WriteSheet detailSheet = EasyExcel.writerSheet(0, "水位数据").head(WaterLevelDTO.class).build(); excelWriter.write(waterLevelList, detailSheet); excelWriter.finish(); } } catch (Exception e) { log.error("水位列表下载失败",e); } } @Override public void downScatterPlot(Long siteId, String startTime, String endTime, HttpServletResponse response){ ScattperPlotQuery scattperPlotQuery = new ScattperPlotQuery(); FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss"); try { Date startTimedDate = fdf.parse(startTime); Date endTimedDate = fdf.parse(endTime); scattperPlotQuery.setSiteId(siteId); scattperPlotQuery.setStartTime(startTimedDate); scattperPlotQuery.setEndTime(endTimedDate); List taskResultList = taskResultMapper.queryByTimeQuery(scattperPlotQuery); if (!taskResultList.isEmpty()) { response.setContentType("application/octet-stream; charset=utf-8"); String today = new SimpleDateFormat("yyyyMMdd").format(new Date()); String fileName = "downScatterPlot_".concat(today); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build(); WriteSheet detailSheet = EasyExcel.writerSheet(0, "测流结果").head(TaskResultSortDTO.class).build(); excelWriter.write(taskResultList, detailSheet); excelWriter.finish(); } } catch (Exception e) { log.error("测流结果下载失败",e); } } public static List insertEmptyDataOnEvenRows(List list) { List modifiedList = new ArrayList<>(list.size() * 2 - 1); // 预估新列表的大小 for (int i = 0; i < list.size(); i++) { modifiedList.add(list.get(i)); // 添加原始元素 if (i < list.size() - 1) { // 避免在最后一个元素后插入 modifiedList.add(list.get(i)); // 在每个元素后插入空白数据 } } return modifiedList; } }