package cn.iocoder.yudao.module.mes.service.energy; import cn.idev.excel.FastExcelFactory; import cn.iocoder.yudao.framework.common.exception.ErrorCode; import cn.iocoder.yudao.framework.common.util.http.HttpUtils; import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy; import cn.iocoder.yudao.module.mes.controller.admin.energy.vo.*; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @Service public class EnergyExportService { @Resource private EnergyRecordService energyRecordService; public void records(EnergyRecordPageReqVO req, HttpServletResponse response) throws IOException { req.setPageNo(1); req.setPageSize(50_001); var page = energyRecordService.page(req); if (page.getTotal() > 50_000) throw exception(new ErrorCode(1_040_952_000, "单次最多导出50000条,请缩小日期范围")); List> rows = page.getList().stream().map(r -> Arrays.asList(r.getRecordDate().toString(), EnergyAlertService.energyName(r.getEnergyType()), r.getUsageArea(), r.getProductCategory(), r.getUsagePurpose(), EnergyAlertService.unit(r.getEnergyType()), r.getQuantity(), r.getUnitPrice(), r.getAmount(), r.getRecorder(), r.getRemark())).toList(); write(response, "能耗台账.xlsx", List.of(new Sheet("能耗台账", List.of("日期", "能源", "使用区域", "产品类别", "用途", "用量单位", "用量", "单价(元/单位)", "费用(元)", "录入人", "备注"), rows))); } public void analysis(EnergyAnalysisReqVO req, HttpServletResponse response) throws IOException { var data = energyRecordService.analysis(req); var head = List.of("统计项", "能源", "用量单位", "用量", "费用(元)", "录入条数"); List> summary = data.getSummary().stream().map(r -> row("合计", r)).toList(); List> trend = data.getTrend().stream().map(r -> row(r.getLabel(), r)).toList(); List> areas = data.getAreas().stream().map(r -> row(r.getLabel(), r)).toList(); List> scope = List.of(Arrays.asList("开始日期", req.getStartDate().toString()), Arrays.asList("结束日期", req.getEndDate().toString()), Arrays.asList("汇总方式", "MONTH".equals(req.getGroupBy()) ? "按月" : "按日"), Arrays.asList("能源", req.getEnergyType() == null || req.getEnergyType().isEmpty() ? "全部" : EnergyAlertService.energyName(req.getEnergyType())), Arrays.asList("区域关键词", Objects.toString(req.getUsageArea(), "")), Arrays.asList("产品类别", Objects.toString(req.getProductCategory(), "")), Arrays.asList("总费用(元)", data.getTotalAmount()), Arrays.asList("录入条数", data.getRecordCount())); write(response, "能耗分析.xlsx", List.of(new Sheet("统计口径", List.of("项目", "内容"), scope), new Sheet("能源汇总", head, summary), new Sheet("日期趋势", head, trend), new Sheet("区域汇总", head, areas))); } private List row(String label, EnergyAnalysisRespVO.Summary r) { return Arrays.asList(label, EnergyAlertService.energyName(r.getEnergyType()), EnergyAlertService.unit(r.getEnergyType()), r.getQuantity(), r.getAmount(), r.getRecordCount()); } private record Sheet(String name, List headers, List> rows) {} private void write(HttpServletResponse response, String filename, List sheets) throws IOException { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Content-Disposition", "attachment;filename=" + HttpUtils.encodeUtf8(filename)); try (var writer = FastExcelFactory.write(response.getOutputStream()).autoCloseStream(false) .registerWriteHandler(new ColumnWidthMatchStyleStrategy()).build()) { for (int i = 0; i < sheets.size(); i++) { var sheet = sheets.get(i); writer.write(sheet.rows(), FastExcelFactory.writerSheet(i, sheet.name()) .head(sheet.headers().stream().map(List::of).toList()).build()); } } } }