package com.gunshi.project.ss.service; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteTable; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gunshi.project.ss.entity.dto.ExportCommonDto; import com.gunshi.project.ss.entity.so.HisWaterDataPageSo; import com.gunshi.project.ss.entity.vo.HisWaterDataVo; import com.gunshi.project.ss.mapper.HisWaterDataMapper; import com.gunshi.project.ss.model.HisWaterData; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.io.Serializable; import java.math.BigDecimal; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @Service @Slf4j @Transactional(rollbackFor = Exception.class) public class HisWaterDataService extends ServiceImpl { public Page pageQuery(HisWaterDataPageSo page) { Page hisWaterDataPage = this.baseMapper.queryPage(page.getPageSo().toPage(),page); fillList(hisWaterDataPage); return hisWaterDataPage; } private void fillList(Page ret) { if (ret.getRecords() != null) { queryChild(ret.getRecords()); } } private void queryChild(List records) { for (HisWaterDataVo record : records) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(HisWaterData::getYear, record.getYear()) .eq(HisWaterData::getType,2) .orderByAsc(HisWaterData::getMonth); record.setChildren(this.list(queryWrapper)); } } public boolean saveData(HisWaterDataVo dto) { checkParam(dto); HisWaterData hisWaterData = new HisWaterData(); BeanUtils.copyProperties(dto,hisWaterData); List list = dto.getChildren(); list.stream().forEach(o ->{ o.setId(null); }); hisWaterData.setId(null); list.add(hisWaterData); boolean flag = saveBatch(list); return flag; } private void checkParam(HisWaterDataVo dto) { Long id = dto.getId(); LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); queryWrapper.eq(HisWaterData::getYear,dto.getYear()) .eq(HisWaterData::getType,1); if(id != null){ queryWrapper.ne(HisWaterData::getId,id); } if(this.count(queryWrapper ) > 0){ throw new IllegalArgumentException("该年份已存在历史降雨资料"); } Long len = dto.getChildren().stream().map(HisWaterData::getMonth).distinct().collect(Collectors.counting()); if(dto.getChildren().size() != len.intValue()){ throw new IllegalArgumentException("月份不可重复"); } } public boolean updateData(HisWaterDataVo dto) { checkParam(dto); HisWaterData hisWaterData = new HisWaterData(); BeanUtils.copyProperties(dto,hisWaterData); if(dto.getChildren() == null || dto.getChildren().isEmpty()){ dto.setAvgWater(BigDecimal.ZERO); } updateById(hisWaterData); deleteMonthData(dto.getYear()); List list = dto.getChildren(); list.stream().forEach(o ->{ o.setYear(dto.getYear()); }); return saveBatch(list); } private void deleteMonthData(Integer year) { LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); queryWrapper.eq(HisWaterData::getYear,year) .eq(HisWaterData::getType,2); this.remove(queryWrapper); } public Boolean removeData(Serializable id) { HisWaterData hisWaterData = this.getById(id); deleteMonthData(hisWaterData.getYear()); return this.removeById(id); } public void export(List records, HttpServletResponse response) { try { // 设置响应头 String fileName = URLEncoder.encode("历史蓄水量数据", "UTF-8").replaceAll("\\+", "%20"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); // 创建ExcelWriter ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()) .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 自动列宽 .build(); // 创建主工作表 WriteSheet writeSheet = EasyExcel.writerSheet("历史蓄水量数据").build(); // 当前行数据 List> dataList = new ArrayList<>(); // 遍历每年的数据 for (HisWaterDataVo yearData : records) { // 添加年份标题行 List yearRow = new ArrayList<>(); yearRow.add(yearData.getYear() + "年"); yearRow.add(""); // 第二列为空 dataList.add(yearRow); // 添加表头 List headerRow = new ArrayList<>(); headerRow.add("月份"); headerRow.add("月份平均蓄水量"); dataList.add(headerRow); // 添加月份数据 if (yearData.getChildren() != null) { for (HisWaterData monthData : yearData.getChildren()) { List monthRow = new ArrayList<>(); monthRow.add(monthData.getMonth() + "月"); monthRow.add(monthData.getAvgWater()); dataList.add(monthRow); } } // 添加年度总蓄水量行 List totalRow = new ArrayList<>(); totalRow.add("年度总蓄水量"); totalRow.add(yearData.getAvgWater()); dataList.add(totalRow); // 添加空行分隔 dataList.add(new ArrayList<>()); dataList.add(new ArrayList<>()); } // 创建表格并写入数据 WriteTable writeTable = EasyExcel.writerTable() .needHead(false) // 不显示表头,因为我们手动添加了 .build(); // 写入数据 excelWriter.write(dataList, writeSheet, writeTable); // 关闭流 excelWriter.finish(); } catch (IOException e) { throw new RuntimeException("导出Excel失败", e); } } public List yearList() { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(HisWaterData::getType,1); return this.baseMapper.selectList(queryWrapper); } public List selectList(ExportCommonDto dto) { List hisWaterDataVos = this.baseMapper.selectYearList(dto); if(!hisWaterDataVos.isEmpty()){ queryChild(hisWaterDataVos); } return hisWaterDataVos; } public List getYearList() { return this.baseMapper.selectYear(); } }