diff --git a/src/main/java/com/gunshi/project/xyt/controller/OsmoticPressRController.java b/src/main/java/com/gunshi/project/xyt/controller/OsmoticPressRController.java index d486470..e27ee21 100644 --- a/src/main/java/com/gunshi/project/xyt/controller/OsmoticPressRController.java +++ b/src/main/java/com/gunshi/project/xyt/controller/OsmoticPressRController.java @@ -2,7 +2,6 @@ package com.gunshi.project.xyt.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.gunshi.core.result.R; -import com.gunshi.project.xyt.entity.so.InfiltraLineSo; import com.gunshi.project.xyt.entity.so.OsmoticQueryPageSo; import com.gunshi.project.xyt.entity.so.OsmoticQuerySo; import com.gunshi.project.xyt.entity.vo.OsmoticChartVo; @@ -21,6 +20,7 @@ import org.springframework.web.bind.annotation.*; import java.io.Serializable; import java.util.List; + /** * 描述: 渗压监测记录表 * author: xusan @@ -70,25 +70,43 @@ public class OsmoticPressRController { @Operation(summary = "测值查询(数据表)") @PostMapping("/query/value") public R> queryValue(@RequestBody OsmoticQuerySo osmoticQuerySo) { - return R.ok(service.queryValue(osmoticQuerySo)); + return R.ok(service.queryValue(osmoticQuerySo,null)); } @Operation(summary = "测值查询(多图单表)") @PostMapping("/query/chart") public R> queryChart(@RequestBody OsmoticQuerySo osmoticQuerySo) { - return R.ok(service.queryChart(osmoticQuerySo)); + return R.ok(service.queryChart(osmoticQuerySo,null)); } @Operation(summary = "浸润线查询") @PostMapping("/infiltra/line") - public R> infiltraLine(@RequestBody InfiltraLineSo infiltraLineSo) { - return R.ok(service.infiltraLine(infiltraLineSo)); + public R> infiltraLine(@RequestBody OsmoticQuerySo osmoticQuerySo) { + return R.ok(service.infiltraLine(osmoticQuerySo)); } @Operation(summary = "浸润线导出") @PostMapping( "/export") - public void export(@RequestBody InfiltraLineSo infiltraLineSo, HttpServletResponse response) { - service.export(infiltraLineSo,response); + public void export(@RequestBody OsmoticQuerySo osmoticQuerySo, HttpServletResponse response) { + service.export(osmoticQuerySo,response); + } + + @Operation(summary = "年度渗压统计(表格)") + @PostMapping("/year/stat") + public R> yearStat(@RequestBody OsmoticQuerySo osmoticQuerySo) { + return R.ok(service.yearStat(osmoticQuerySo)); + } + + @Operation(summary = "年度渗压统计(全年度特征值统计)") + @PostMapping("/year/stat/value") + public R> yearStatValue(@RequestBody OsmoticQuerySo osmoticQuerySo) { + return R.ok(service.yearStatValue(osmoticQuerySo)); + } + + @Operation(summary = "年度渗压统计导出") + @PostMapping( "/year/stat/export") + public void yearStatExport(@RequestBody OsmoticQuerySo osmoticQuerySo, HttpServletResponse response) { + service.yearStatExport(osmoticQuerySo,response); } } \ No newline at end of file diff --git a/src/main/java/com/gunshi/project/xyt/entity/so/InfiltraLineSo.java b/src/main/java/com/gunshi/project/xyt/entity/so/InfiltraLineSo.java deleted file mode 100644 index 8e641c9..0000000 --- a/src/main/java/com/gunshi/project/xyt/entity/so/InfiltraLineSo.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gunshi.project.xyt.entity.so; - -import com.gunshi.db.dto.DateTimeRangeSo; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -/** - * Description: - * Created by wanyan on 2024/7/11 - * - * @author wanyan - * @version 1.0 - */ -@Data -@Schema(description = "浸润线查询对象") -public class InfiltraLineSo { - - @Schema(description = "上报时间") - private DateTimeRangeSo dateTimeRangeSo; - - @Schema(description = "监测断面") - private String profileCode; - -} diff --git a/src/main/java/com/gunshi/project/xyt/entity/so/OsmoticQuerySo.java b/src/main/java/com/gunshi/project/xyt/entity/so/OsmoticQuerySo.java index aa7574c..4f40f04 100644 --- a/src/main/java/com/gunshi/project/xyt/entity/so/OsmoticQuerySo.java +++ b/src/main/java/com/gunshi/project/xyt/entity/so/OsmoticQuerySo.java @@ -17,9 +17,14 @@ import java.util.List; @Schema(description = "测值查询对象") public class OsmoticQuerySo { + @Schema(description = "年度") + private Integer year; + @Schema(description = "时间") private DateTimeRangeSo dateTimeRangeSo; + @Schema(description = "监测断面") + private String profileCode; @Schema(description = "测点编号") private List stationCodes; diff --git a/src/main/java/com/gunshi/project/xyt/entity/vo/OsmoticChartVo.java b/src/main/java/com/gunshi/project/xyt/entity/vo/OsmoticChartVo.java index f572a78..ac9d47b 100644 --- a/src/main/java/com/gunshi/project/xyt/entity/vo/OsmoticChartVo.java +++ b/src/main/java/com/gunshi/project/xyt/entity/vo/OsmoticChartVo.java @@ -46,6 +46,12 @@ public class OsmoticChartVo { @Schema(description="最小值时间") private String minTm; + /** + * 变幅 + */ + @Schema(description="变幅") + private BigDecimal diff; + @Schema(description = "数据") private List detailVos; } diff --git a/src/main/java/com/gunshi/project/xyt/entity/vo/OsmoticStationVo.java b/src/main/java/com/gunshi/project/xyt/entity/vo/OsmoticStationVo.java index 90eb556..c5a0f3f 100644 --- a/src/main/java/com/gunshi/project/xyt/entity/vo/OsmoticStationVo.java +++ b/src/main/java/com/gunshi/project/xyt/entity/vo/OsmoticStationVo.java @@ -3,6 +3,7 @@ package com.gunshi.project.xyt.entity.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.math.BigDecimal; import java.util.List; /** @@ -13,11 +14,14 @@ import java.util.List; * @version 1.0 */ @Data -public class OsmoticStationVo extends StRzVo{ +public class OsmoticStationVo extends StRzVo { @Schema(description = "结果分析(0异常 1正常)") private Integer status = 1; @Schema(description="测值") private List list; + + @Schema(description = "降雨量") + private BigDecimal drp; } diff --git a/src/main/java/com/gunshi/project/xyt/mapper/OsmoticPressRMapper.java b/src/main/java/com/gunshi/project/xyt/mapper/OsmoticPressRMapper.java index 63c0c74..2e44f6f 100644 --- a/src/main/java/com/gunshi/project/xyt/mapper/OsmoticPressRMapper.java +++ b/src/main/java/com/gunshi/project/xyt/mapper/OsmoticPressRMapper.java @@ -2,7 +2,6 @@ package com.gunshi.project.xyt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.gunshi.project.xyt.entity.so.InfiltraLineSo; import com.gunshi.project.xyt.entity.so.OsmoticQueryPageSo; import com.gunshi.project.xyt.entity.so.OsmoticQuerySo; import com.gunshi.project.xyt.entity.vo.OsmoticValueVo; @@ -97,14 +96,14 @@ public interface OsmoticPressRMapper extends BaseMapper { order by t.tm desc """) - List queryLineRz(@Param("obj") InfiltraLineSo infiltraLineSo); + List queryLineRz(@Param("obj") OsmoticQuerySo osmoticQuerySo); @Select(""" """) - List queryLineValue(@Param("obj") InfiltraLineSo infiltraLineSo,@Param("list") List stationCodes); + List queryLineValue(@Param("obj") OsmoticQuerySo osmoticQuerySo); @Select(""" """) - List queryWarn(@Param("obj") InfiltraLineSo infiltraLineSo,@Param("list") List stationCodes); + List queryWarn(@Param("obj") OsmoticQuerySo osmoticQuerySo); + + @Select(""" + + """) + List queryDrp(@Param("year") Integer year); } \ No newline at end of file diff --git a/src/main/java/com/gunshi/project/xyt/service/OsmoticPressRService.java b/src/main/java/com/gunshi/project/xyt/service/OsmoticPressRService.java index 5b3a8e5..9a4c0b9 100644 --- a/src/main/java/com/gunshi/project/xyt/service/OsmoticPressRService.java +++ b/src/main/java/com/gunshi/project/xyt/service/OsmoticPressRService.java @@ -4,14 +4,14 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.gunshi.project.xyt.entity.so.InfiltraLineSo; +import com.gunshi.db.dto.DateTimeRangeSo; import com.gunshi.project.xyt.entity.so.OsmoticQueryPageSo; import com.gunshi.project.xyt.entity.so.OsmoticQuerySo; import com.gunshi.project.xyt.entity.vo.*; import com.gunshi.project.xyt.mapper.OsmoticPressRMapper; -import com.gunshi.project.xyt.model.OsmoticPressDevice; +import com.gunshi.project.xyt.model.*; +import com.gunshi.project.xyt.model.AttDamProfileAutoDao; import com.gunshi.project.xyt.model.OsmoticPressDeviceAutoDao; -import com.gunshi.project.xyt.model.OsmoticPressR; import com.gunshi.project.xyt.util.DateUtil; import com.gunshi.project.xyt.util.ExcelUtil; import com.gunshi.project.xyt.util.MyBeanUtil; @@ -38,6 +38,9 @@ public class OsmoticPressRService extends ServiceImpl queryValue(OsmoticQuerySo osmoticQuerySo) { - List dateList = DateUtil.getDatesBetween(osmoticQuerySo.getDateTimeRangeSo().getStart(), osmoticQuerySo.getDateTimeRangeSo().getEnd()); + public List queryValue(OsmoticQuerySo osmoticQuerySo,Integer year) { + Boolean isDesc = true; + //查询测站降雨量 + Map drpMap = new HashMap<>(); + if(year != null){ + isDesc = false; + List drpList = mapper.queryDrp(year); + drpMap = drpList.stream().collect(Collectors.toMap(StRzVo::getTm, StRzVo::getRz)); + } + List dateList = DateUtil.getDatesBetween(osmoticQuerySo.getDateTimeRangeSo().getStart(), osmoticQuerySo.getDateTimeRangeSo().getEnd(),isDesc); List resList = new ArrayList<>(); //查询库水位 List list = mapper.queryRz(osmoticQuerySo); @@ -63,6 +74,7 @@ public class OsmoticPressRService extends ServiceImplstr.equals(o.getTm())).map(t->{ t.setRz(vo.getRz()); return t; @@ -72,10 +84,40 @@ public class OsmoticPressRService extends ServiceImpl queryChart(OsmoticQuerySo osmoticQuerySo) { + public List queryChart(OsmoticQuerySo osmoticQuerySo,Integer year) { List resList = new ArrayList<>(); //查询库水位 List list = mapper.queryRz(osmoticQuerySo); + //查询测站降雨量 + List drpList = new ArrayList<>(); + if(year != null){ + drpList = mapper.queryDrp(year); + OsmoticChartVo chartVo = new OsmoticChartVo(); + chartVo.setStationCode("rz"); + if(CollectionUtils.isNotEmpty(list)){ + StRzVo max = list.stream().max(Comparator.comparing(StRzVo::getRz)).get(); + StRzVo min = list.stream().min(Comparator.comparing(StRzVo::getRz)).get(); + chartVo.setMaxValue(max.getRz()); + chartVo.setMaxTm(max.getTm()); + chartVo.setMinValue(min.getRz()); + chartVo.setMinTm(min.getTm()); + chartVo.setDiff(max.getRz().subtract(min.getRz())); + resList.add(chartVo); + } + + if(CollectionUtils.isNotEmpty(drpList)){ + OsmoticChartVo drpVo = new OsmoticChartVo(); + drpVo.setStationCode("drp"); + StRzVo maxDrp = drpList.stream().max(Comparator.comparing(StRzVo::getRz)).get(); + StRzVo minDrp = drpList.stream().min(Comparator.comparing(StRzVo::getRz)).get(); + drpVo.setMaxValue(maxDrp.getRz()); + drpVo.setMaxTm(maxDrp.getTm()); + drpVo.setMinValue(minDrp.getRz()); + drpVo.setMinTm(minDrp.getTm()); + drpVo.setDiff(maxDrp.getRz().subtract(minDrp.getRz())); + resList.add(drpVo); + } + } //查询测站管水位 List valueList = mapper.queryValue(osmoticQuerySo); //按测站分组 @@ -90,12 +132,17 @@ public class OsmoticPressRService extends ServiceImpl bindData(List tmRzList, List voList) { HashSet strings = new HashSet<>(); @@ -122,21 +169,22 @@ public class OsmoticPressRService extends ServiceImpl infiltraLine(InfiltraLineSo infiltraLineSo) { + public List infiltraLine(OsmoticQuerySo osmoticQuerySo) { List resList = new ArrayList<>(); - String profileCode = infiltraLineSo.getProfileCode(); + String profileCode = osmoticQuerySo.getProfileCode(); //通过断面查询渗压设备 List stationCodes = queryPressList(profileCode); if(CollectionUtils.isEmpty(stationCodes)){ return resList; } + osmoticQuerySo.setStationCodes(stationCodes); //查询库水位 - List list = mapper.queryLineRz(infiltraLineSo); + List list = mapper.queryLineRz(osmoticQuerySo); Map rzMap = list.stream().collect(Collectors.toMap(StRzVo::getTm, StRzVo::getRz)); //查询测站管水位 - List valueList = mapper.queryLineValue(infiltraLineSo,stationCodes); + List valueList = mapper.queryLineValue(osmoticQuerySo); //查询测站预警信息 - List warnList = mapper.queryWarn(infiltraLineSo,stationCodes); + List warnList = mapper.queryWarn(osmoticQuerySo); valueList.stream().map(vo->{ Boolean b = warnList.stream().filter(o->o.getStationCode().equals(vo.getStationCode()) && o.getTm().equals(vo.getTm())).findAny().isPresent(); if(b){ @@ -166,24 +214,27 @@ public class OsmoticPressRService extends ServiceImpl stationCodes = queryPressList(infiltraLineSo.getProfileCode()); + List stationCodes = queryPressList(osmoticQuerySo.getProfileCode()); //表头信息 List heads = new ArrayList<>(); + heads.add("序号"); heads.add("时间"); heads.add("库水位(m)"); heads.addAll(stationCodes); heads.add("结果分析"); //表格数据 - List resList = infiltraLine(infiltraLineSo); + List resList = infiltraLine(osmoticQuerySo); List> list = new ArrayList<>(); - for (OsmoticStationVo vo : resList) { + for (int j = 0;j < resList.size(); j++) { + OsmoticStationVo vo = resList.get(j); Map test = new LinkedHashMap<>(); + test.put("t0",j+1); test.put("t1", vo.getTm()); test.put("t2", vo.getRz()); - for(int i = 0;icode.equals(o.getStationCode())).findFirst().orElse(null); test.put(code,valueVo != null ? valueVo.getValue() : "-"); @@ -195,18 +246,161 @@ public class OsmoticPressRService extends ServiceImpl stationCodes = queryPressList(profileCode); + osmoticQuerySo.setStationCodes(stationCodes); + Integer year = osmoticQuerySo.getYear(); + Date start = DateUtil.convertStringToDate(year + "-01-01 00:00:00"); + Date end = DateUtil.convertStringToDate(year + "-12-31 00:00:00"); + DateTimeRangeSo so = new DateTimeRangeSo(); + so.setStart(start); + so.setEnd(end); + osmoticQuerySo.setDateTimeRangeSo(so); + return osmoticQuerySo; + } + + public List yearStat(OsmoticQuerySo osmoticQuerySo) { + commonQueryHandle(osmoticQuerySo); + return queryValue(osmoticQuerySo,osmoticQuerySo.getYear()); + } + + public List yearStatValue(OsmoticQuerySo osmoticQuerySo) { + commonQueryHandle(osmoticQuerySo); + return queryChart(osmoticQuerySo,osmoticQuerySo.getYear()); + } + + public void yearStatExport(OsmoticQuerySo osmoticQuerySo, HttpServletResponse response) { + String profileName = ""; + //断面名称 + AttDamProfile damProfile = profileAutoDao.getById(osmoticQuerySo.getProfileCode()); + if(damProfile != null){ + profileName = damProfile.getProfileName(); + } + //上方表格数据 + List resList = yearStat(osmoticQuerySo); + //下方特征值数据 + List chartList = queryChart(osmoticQuerySo,osmoticQuerySo.getYear()); + List stationCodes = osmoticQuerySo.getStationCodes(); + //表头信息 + List> headList = new ArrayList<>(); + List heads1 = new ArrayList<>(); + heads1.add("序号"); + heads1.add("序号"); + headList.add(heads1); + + List heads2 = new ArrayList<>(); + heads2.add("监测日期"); + heads2.add("监测日期"); + headList.add(heads2); + + for(String code : stationCodes){ + List heads = new ArrayList<>(); + heads.add(profileName + "断面测压管水位(m)"); + heads.add(code); + headList.add(heads); + } + + List heads3 = new ArrayList<>(); + heads3.add("库水位(m)"); + heads3.add("库水位(m)"); + headList.add(heads3); + + List heads4 = new ArrayList<>(); + heads4.add("降雨量(mm)"); + heads4.add("降雨量(mm)"); + headList.add(heads4); + + List> list = new ArrayList<>(); + for (int j = 0;j < resList.size(); j++) { + OsmoticStationVo vo = resList.get(j); + Map test = new LinkedHashMap<>(); + test.put("t0",j+1); + test.put("t1", vo.getTm()); + for(int i = 0;i < stationCodes.size();i++){ + String code = stationCodes.get(i); + OsmoticValueVo valueVo = vo.getList().stream().filter(o->code.equals(o.getStationCode())).findFirst().orElse(null); + test.put(code,valueVo != null ? valueVo.getValue() : ""); + } + test.put("t2", vo.getRz()); + test.put("t3", vo.getDrp()); + list.add(test); + } + + Map max = new LinkedHashMap<>(); + max.put("t0","全年度特征值统计"); + max.put("t1", "最大值"); + for(int i = 0;i < stationCodes.size();i++){ + String code = stationCodes.get(i); + max.put(code,chartList.stream().filter(o->code.equals(o.getStationCode())).findFirst().get().getMaxValue()); + } + max.put("t2", chartList.stream().filter(o->"rz".equals(o.getStationCode())).findFirst().get().getMaxValue()); + max.put("t3", chartList.stream().filter(o->"drp".equals(o.getStationCode())).findFirst().get().getMaxValue()); + list.add(max); + + Map maxTm = new LinkedHashMap<>(); + maxTm.put("t0","全年度特征值统计"); + maxTm.put("t1", "日期"); + for(int i = 0;i < stationCodes.size();i++){ + String code = stationCodes.get(i); + maxTm.put(code,chartList.stream().filter(o->code.equals(o.getStationCode())).findFirst().get().getMaxTm()); + } + maxTm.put("t2", chartList.stream().filter(o->"rz".equals(o.getStationCode())).findFirst().get().getMaxTm()); + maxTm.put("t3", chartList.stream().filter(o->"drp".equals(o.getStationCode())).findFirst().get().getMaxTm()); + list.add(maxTm); + + Map min = new LinkedHashMap<>(); + min.put("t0","全年度特征值统计"); + min.put("t1", "最大值"); + for(int i = 0;i < stationCodes.size();i++){ + String code = stationCodes.get(i); + min.put(code,chartList.stream().filter(o->code.equals(o.getStationCode())).findFirst().get().getMinValue()); + } + min.put("t2", chartList.stream().filter(o->"rz".equals(o.getStationCode())).findFirst().get().getMinValue()); + min.put("t3", chartList.stream().filter(o->"drp".equals(o.getStationCode())).findFirst().get().getMinValue()); + list.add(min); + + Map minTm = new LinkedHashMap<>(); + minTm.put("t0","全年度特征值统计"); + minTm.put("t1", "日期"); + for(int i = 0;i < stationCodes.size();i++){ + String code = stationCodes.get(i); + minTm.put(code,chartList.stream().filter(o->code.equals(o.getStationCode())).findFirst().get().getMinTm()); + } + minTm.put("t2", chartList.stream().filter(o->"rz".equals(o.getStationCode())).findFirst().get().getMinTm()); + minTm.put("t3", chartList.stream().filter(o->"drp".equals(o.getStationCode())).findFirst().get().getMinTm()); + list.add(minTm); + + Map diff = new LinkedHashMap<>(); + diff.put("t0","全年度特征值统计"); + diff.put("t1", "年变幅"); + for(int i = 0;i < stationCodes.size();i++){ + String code = stationCodes.get(i); + diff.put(code,chartList.stream().filter(o->code.equals(o.getStationCode())).findFirst().get().getDiff()); + } + diff.put("t2", chartList.stream().filter(o->"rz".equals(o.getStationCode())).findFirst().get().getDiff()); + diff.put("t3", chartList.stream().filter(o->"drp".equals(o.getStationCode())).findFirst().get().getDiff()); + list.add(diff); + + ExcelUtil.exportExcel(headList,tableData(list),2,new int[]{0},profileName+"断面年度渗压统计",response,"年度渗压统计"); + } + + private List tableData( List> list){ List list2 = new ArrayList<>(); Collection values; for (int i = 0; i < list.size(); i++) { values = list.get(i).values(); List objects = new ArrayList<>(); for (Object value : values) { - objects.add(value.toString()); + objects.add(value == null ? "" : value.toString()); } list2.add(objects); } - ExcelUtil.exportExcel(hs, list2, "浸润线", null, response, "浸润线"); + return list2; } } diff --git a/src/main/java/com/gunshi/project/xyt/util/DateUtil.java b/src/main/java/com/gunshi/project/xyt/util/DateUtil.java index ceccc66..f23d996 100644 --- a/src/main/java/com/gunshi/project/xyt/util/DateUtil.java +++ b/src/main/java/com/gunshi/project/xyt/util/DateUtil.java @@ -141,7 +141,7 @@ public class DateUtil { return now.format(ym); } - public static List getDatesBetween(Date startDate, Date endDate) { + public static List getDatesBetween(Date startDate, Date endDate,Boolean isDesc) { List dates = new ArrayList<>(); Calendar calendar = Calendar.getInstance(); calendar.setTime(startDate); @@ -150,7 +150,11 @@ public class DateUtil { dates.add(convertDateToString(calendar.getTime())); calendar.add(Calendar.DATE, 1); } - return dates.reversed(); + dates.add(convertDateToString(endDate)); + if(isDesc){ + return dates.reversed(); + } + return dates; } diff --git a/src/main/java/com/gunshi/project/xyt/util/ExcelUtil.java b/src/main/java/com/gunshi/project/xyt/util/ExcelUtil.java index 782ebe0..dccfc35 100644 --- a/src/main/java/com/gunshi/project/xyt/util/ExcelUtil.java +++ b/src/main/java/com/gunshi/project/xyt/util/ExcelUtil.java @@ -7,8 +7,10 @@ import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; import com.alibaba.excel.write.metadata.WriteSheet; +import com.gunshi.project.xyt.util.excel.ExcelFillCellMergeStrategy; import com.gunshi.project.xyt.util.excel.ExcelListener; import com.gunshi.project.xyt.util.excel.ExcelResult; +import com.gunshi.project.xyt.util.excel.VoteTitleHandler; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @@ -52,11 +54,20 @@ public class ExcelUtil { } } - public static void exportExcel(List> head,List data, String filename, Class clazz, HttpServletResponse response,String sheetName) { + /** + * 导出动态列 + * @param head 表头 + * @param data 数据 + * @param filename + * @param response + * @param sheetName + * @param + */ + public static void exportExcel(List> head,List data, String filename, HttpServletResponse response,String sheetName) { OutputStream out = null; try { out = getOutputStream(filename,response); - ExcelWriterSheetBuilder builder = EasyExcel.write(out, clazz) + ExcelWriterSheetBuilder builder = EasyExcel.write(out) //是否自动关闭流 .autoCloseStream(Boolean.FALSE) //自动列宽(不太精确) @@ -76,7 +87,39 @@ public class ExcelUtil { } } - + /** + *导出动态列,带合并单元格 + * @param head 表头 + * @param data 表格数据 + * @param mergeRowIndex 从第几行开始合并 + * @param mergeColumnIndex 合并字段的下标,如第一到五列new int[]{0,1,2,3,4} + * @param filename + * @param response + * @param sheetName + * @param + */ + public static void exportExcel(List> head,List data,int mergeRowIndex,int[] mergeColumnIndex, String filename, HttpServletResponse response,String sheetName) { + OutputStream out = null; + try { + out = getOutputStream(filename,response); + ExcelWriterSheetBuilder builder = EasyExcel.write(out) + //是否自动关闭流 + .autoCloseStream(Boolean.FALSE) + .registerWriteHandler(new ExcelFillCellMergeStrategy(mergeRowIndex,mergeColumnIndex)) + .head(head) + .sheet(sheetName); + builder.doWrite(data); + } finally { + try { + if (out != null){ + out.flush(); + out.close(); + } + } catch (IOException e) { + throw new RuntimeException("导出Excel异常"); + } + } + } /** * 单表多数据模板导出 模板格式为 {.属性} diff --git a/src/main/java/com/gunshi/project/xyt/util/excel/ExcelFillCellMergeStrategy.java b/src/main/java/com/gunshi/project/xyt/util/excel/ExcelFillCellMergeStrategy.java new file mode 100644 index 0000000..29f0dc7 --- /dev/null +++ b/src/main/java/com/gunshi/project/xyt/util/excel/ExcelFillCellMergeStrategy.java @@ -0,0 +1,96 @@ +package com.gunshi.project.xyt.util.excel; + +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import lombok.Data; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; + +import java.util.List; + + +@Data +public class ExcelFillCellMergeStrategy implements CellWriteHandler { + /** + * 合并字段的下标,如第一到五列new int[]{0,1,2,3,4} + */ + private int[] mergeColumnIndex; + /** + * 从第几行开始合并,如果表头占两行,这个数字就是2 + */ + private int mergeRowIndex; + + + public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) { + this.mergeRowIndex = mergeRowIndex; + this.mergeColumnIndex = mergeColumnIndex; + } + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Head head, Integer integer, Integer integer1, Boolean aBoolean) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, + Head head, Integer integer, Boolean aBoolean) { + + } + + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + List> list, Cell cell, Head head, Integer integer, Boolean aBoolean) { + //当前行 + int curRowIndex = cell.getRowIndex(); + //当前列 + int curColIndex = cell.getColumnIndex(); + + if (curRowIndex > mergeRowIndex) { + for (int i = 0; i < mergeColumnIndex.length; i++) { + if (curColIndex == mergeColumnIndex[i]) { + mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex); + break; + } + } + } + } + + private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) { + //获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并 + Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : + cell.getNumericCellValue(); + Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex); + Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() :preCell.getNumericCellValue(); + // 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行 + if (curData.equals(preData)) { + Sheet sheet = writeSheetHolder.getSheet(); + List mergeRegions = sheet.getMergedRegions(); + boolean isMerged = false; + for (int i = 0; i < mergeRegions.size() && !isMerged; i++) { + CellRangeAddress cellRangeAddr = mergeRegions.get(i); + // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元 + if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) { + sheet.removeMergedRegion(i); + cellRangeAddr.setLastRow(curRowIndex); + sheet.addMergedRegion(cellRangeAddr); + isMerged = true; + } + } + // 若上一个单元格未被合并,则新增合并单元 + if (!isMerged) { + CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, + curColIndex); + sheet.addMergedRegion(cellRangeAddress); + } + } + } +} + diff --git a/src/main/java/com/gunshi/project/xyt/util/VoteTitleHandler.java b/src/main/java/com/gunshi/project/xyt/util/excel/VoteTitleHandler.java similarity index 97% rename from src/main/java/com/gunshi/project/xyt/util/VoteTitleHandler.java rename to src/main/java/com/gunshi/project/xyt/util/excel/VoteTitleHandler.java index 2962029..a4d77d4 100644 --- a/src/main/java/com/gunshi/project/xyt/util/VoteTitleHandler.java +++ b/src/main/java/com/gunshi/project/xyt/util/excel/VoteTitleHandler.java @@ -1,4 +1,4 @@ -package com.gunshi.project.xyt.util; +package com.gunshi.project.xyt.util.excel; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.handler.CellWriteHandler;