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<List<Object>> rows = page.getList().stream().map(r -> Arrays.<Object>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<List<Object>> summary = data.getSummary().stream().map(r -> row("合计", r)).toList();
|
List<List<Object>> trend = data.getTrend().stream().map(r -> row(r.getLabel(), r)).toList();
|
List<List<Object>> areas = data.getAreas().stream().map(r -> row(r.getLabel(), r)).toList();
|
List<List<Object>> 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<Object> 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<String> headers, List<List<Object>> rows) {}
|
private void write(HttpServletResponse response, String filename, List<Sheet> 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());
|
}
|
}
|
}
|
}
|