package com.trafficaudit.reportexport.controller;
|
|
import com.trafficaudit.common.Result;
|
import com.trafficaudit.reportexport.service.ReportExportService;
|
import com.trafficaudit.system.service.OperationLogService;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.MediaType;
|
import org.springframework.http.ResponseEntity;
|
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RestController;
|
|
import javax.annotation.Resource;
|
import java.net.URLEncoder;
|
import java.util.List;
|
import java.nio.charset.StandardCharsets;
|
|
@Slf4j
|
@RestController
|
@RequestMapping("/api/report")
|
public class ReportExportController {
|
|
@Resource
|
private ReportExportService reportService;
|
@Resource
|
private OperationLogService operationLogService;
|
|
/** 生成_货运量分市州明细.xlsx */
|
@GetMapping("/export/cityDetail")
|
public ResponseEntity<byte[]> exportCityDetail(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_货运量分市州明细.xlsx", period);
|
return buildResponse(reportService.exportCityDetail(period, mode), "生成_货运量分市州明细.xlsx");
|
}
|
|
/** 生成_货运量排名.xlsx */
|
@GetMapping("/export/freightRank")
|
public ResponseEntity<byte[]> exportFreightRank(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_货运量排名.xlsx", period);
|
return buildResponse(reportService.exportFreightRank(period, mode), "生成_货运量排名.xlsx");
|
}
|
|
/** 生成_周转量排名.xlsx */
|
@GetMapping("/export/turnoverRank")
|
public ResponseEntity<byte[]> exportTurnoverRank(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_周转量排名.xlsx", period);
|
return buildResponse(reportService.exportTurnoverRank(period, mode), "生成_周转量排名.xlsx");
|
}
|
|
/** 生成_公路旅客分市州明细.xlsx(month: 报表期 yyyy-MM;year: 年份 yyyy) */
|
@GetMapping("/export/passengerCityDetail")
|
public ResponseEntity<byte[]> exportPassengerCityDetail(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_公路旅客分市州明细.xlsx", period);
|
return buildResponse(reportService.exportPassengerCityDetail(period, mode), "生成_公路旅客分市州明细.xlsx");
|
}
|
|
|
/** 生成_公路旅客中口径明细.xlsx */
|
@GetMapping("/export/passengerMidDetail")
|
public ResponseEntity<byte[]> exportPassengerMidDetail(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_公路旅客中口径明细.xlsx", period);
|
return buildResponse(reportService.exportPassengerMidDetail(period, mode), "生成_公路旅客中口径明细.xlsx");
|
}
|
|
/** 生成_公路旅客中口径排名.xlsx */
|
@GetMapping("/export/passengerMidRank")
|
public ResponseEntity<byte[]> exportPassengerMidRank(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_公路旅客中口径排名.xlsx", period);
|
return buildResponse(reportService.exportPassengerMidRank(period, mode), "生成_公路旅客中口径排名.xlsx");
|
}
|
|
/** 生成_公路旅客中口径分析.xlsx */
|
@GetMapping("/export/passengerMidAnalysis")
|
public ResponseEntity<byte[]> exportPassengerMidAnalysis(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_公路旅客中口径分析.xlsx", period);
|
return buildResponse(reportService.exportPassengerMidAnalysis(period, mode), "生成_公路旅客中口径分析.xlsx");
|
}
|
|
/** 生成_能运汇总表.xlsx(H204,全省 + 各市州 sheet) */
|
@GetMapping("/export/energySummary")
|
public ResponseEntity<byte[]> exportEnergySummary(@RequestParam("period") String period) throws Exception {
|
logExport("生成_能运汇总表.xlsx", period);
|
return buildResponse(reportService.exportEnergySummary(period), "生成_能运汇总表.xlsx");
|
}
|
/** 生成_城市公交客运量分市州明细.xlsx(城市客运第1步,公交) */
|
@GetMapping("/export/cityBusDetail")
|
public ResponseEntity<byte[]> exportCityBusDetail(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_城市公交客运量分市州明细.xlsx", period);
|
return buildResponse(reportService.exportCityBusDetail(period, mode), "生成_城市公交客运量分市州明细.xlsx");
|
}
|
|
/** 生成_巡游出租客运量分市州明细.xlsx(城市客运第2步,巡游出租) */
|
@GetMapping("/export/cityTaxiDetail")
|
public ResponseEntity<byte[]> exportCityTaxiDetail(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_巡游出租客运量分市州明细.xlsx", period);
|
return buildResponse(reportService.exportCityTaxiDetail(period, mode), "生成_巡游出租客运量分市州明细.xlsx");
|
}
|
|
/** 生成_2026年全省预安排计划进度情况汇总.xlsx(投资模块表1) */
|
@GetMapping("/export/investPlan")
|
public ResponseEntity<byte[]> exportInvestPlan(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_全省预安排计划进度情况汇总.xls", period);
|
return buildResponse(reportService.investPlan(period, mode), "生成_全省预安排计划进度情况汇总.xls");
|
}
|
|
/** 生成_"十五五"规划物流项目进展情况.xlsx(投资模块表2) */
|
@GetMapping("/export/investFiveYearLogistics")
|
public ResponseEntity<byte[]> exportInvestFiveYearLogistics(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_十五五规划物流项目进展情况.xls", period);
|
return buildResponse(reportService.investFiveYearLogistics(period, mode), "生成_十五五规划物流项目进展情况.xls");
|
}
|
|
/** 生成_湖北省(客货站场)亿元投资项目.xls(投资模块表3,投资总表+规上项目表两sheet) */
|
@GetMapping("/export/investBillion")
|
public ResponseEntity<byte[]> exportInvestBillion(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_湖北省(客货站场)亿元投资项目.xls", period);
|
return buildResponse(reportService.investBillion(period, mode), "生成_湖北省(客货站场)亿元投资项目.xls");
|
}
|
|
/** 生成_(经济强县项目)交通物流基础设施投资统计报表.xlsx(投资模块表4) */
|
@GetMapping("/export/investCounty")
|
public ResponseEntity<byte[]> exportInvestCounty(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_经济强县交通物流基础设施投资统计报表.xls", period);
|
return buildResponse(reportService.investCounty(period, mode), "生成_经济强县交通物流基础设施投资统计报表.xls");
|
}
|
|
/** 生成_轨道轮渡客运量分市州明细.xlsx(城市客运,轨道/轮渡取自公交源文件) */
|
@GetMapping("/export/cityRailFerryDetail")
|
public ResponseEntity<byte[]> exportCityRailFerryDetail(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_轨道轮渡客运量分市州明细.xlsx", period);
|
return buildResponse(reportService.exportCityRailFerryDetail(period, mode), "生成_轨道轮渡客运量分市州明细.xlsx");
|
}
|
|
/** 生成_城市客运客运量分市州累计.xlsx(城市分市州_模板底稿) */
|
@GetMapping("/export/cityPassengerCitySum")
|
public ResponseEntity<byte[]> exportCityPassengerCitySum(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_城市客运客运量分市州累计.xlsx", period);
|
return buildResponse(reportService.exportCityPassengerCitySum("导入模板_城市分市州.xlsx", period, mode), "生成_城市客运客运量分市州累计.xlsx");
|
}
|
|
/** 生成_城市客运各市州明细表.xlsx(城市客运各市州明细表_模板底稿) */
|
@GetMapping("/export/cityPassengerDetailSum")
|
public ResponseEntity<byte[]> exportCityPassengerDetailSum(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_城市客运各市州明细表.xlsx", period);
|
return buildResponse(reportService.exportCityPassengerCitySum("导入模板_城市客运各市州明细表.xlsx", period, mode), "生成_城市客运各市州明细表.xlsx");
|
}
|
|
/** 生成_城市客运汇总.xlsx(城市汇总_模板底稿) */
|
@GetMapping("/export/cityPassengerSummary")
|
public ResponseEntity<byte[]> exportCityPassengerSummary(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExport("生成_城市客运汇总.xlsx", period);
|
return buildResponse(reportService.exportCityPassengerSummary(period, mode), "生成_城市客运汇总.xlsx");
|
}
|
|
/** 生成_城市客运报表系列.zip(一键打包全部:公交/出租/轨道轮渡明细 + 分市州累计 + 各市州明细表 + 汇总) */
|
@GetMapping("/export/cityPassengerSeries")
|
public ResponseEntity<byte[]> exportCityPassengerSeries(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExportZip("生成_城市客运报表系列.zip", period);
|
String fileName = String.format("生成_城市客运报表系列_%s.zip", period);
|
String encoded = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
|
return ResponseEntity.ok()
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded)
|
.contentType(MediaType.parseMediaType("application/zip"))
|
.body(reportService.exportCityPassengerSeries(period, mode));
|
}
|
|
/** 生成_货运报表系列.zip(一键打包:明细+排名) */
|
@GetMapping("/export/freightSeries")
|
public ResponseEntity<byte[]> exportFreightSeries(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExportZip("生成_货运报表系列.zip", period);
|
return zipResponse(reportService.exportFreightSeries(period, mode), String.format("生成_货运报表系列_%s.zip", period));
|
}
|
|
/** 生成_公路旅客报表系列.zip(一键打包:分市州明细+中口径明细/排名/分析) */
|
@GetMapping("/export/passengerSeries")
|
public ResponseEntity<byte[]> exportPassengerSeries(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExportZip("生成_公路旅客报表系列.zip", period);
|
return zipResponse(reportService.exportPassengerSeries(period, mode), String.format("生成_公路旅客报表系列_%s.zip", period));
|
}
|
|
/** 生成_投资报表系列.zip(一键打包:预安排/十五五/亿元/经济强县) */
|
@GetMapping("/export/investSeries")
|
public ResponseEntity<byte[]> exportInvestSeries(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode) throws Exception {
|
logExportZip("生成_投资报表系列.zip", period);
|
return zipResponse(reportService.exportInvestSeries(period, mode), String.format("生成_投资报表系列_%s.zip", period));
|
}
|
|
/** 生成_所选报表.zip:types 逗号分隔(前端"生成选中"多选) */
|
@GetMapping("/export/selected")
|
public ResponseEntity<byte[]> exportSelected(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode,
|
@RequestParam("types") String types) throws Exception {
|
List<String> typeList = new java.util.ArrayList<>();
|
for (String t : types.split(",")) {
|
String s = t.trim();
|
if (!s.isEmpty()) typeList.add(s);
|
}
|
logExportZip("生成_所选报表.zip", period);
|
return zipResponse(reportService.exportSelectedSeries(period, mode, typeList),
|
String.format("生成_所选报表_%s.zip", period));
|
}
|
|
/** 导出前数据就绪校验:返回每张报表依赖的数据行数/缺失提示(types 逗号分隔) */
|
@GetMapping("/ready")
|
public Result<java.util.Map<String, Object>> exportReady(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode,
|
@RequestParam("types") String types) {
|
List<String> typeList = new java.util.ArrayList<>();
|
for (String t : types.split(",")) {
|
String s = t.trim();
|
if (!s.isEmpty()) typeList.add(s);
|
}
|
return Result.ok(reportService.checkExportReady(period, mode, typeList));
|
}
|
|
/** 报表数据预览(轻量版):就绪 + 月度覆盖 + 核心指标摘要 + 问题清单(types 逗号分隔) */
|
@GetMapping("/preview")
|
public Result<java.util.Map<String, Object>> reportPreview(@RequestParam("period") String period,
|
@RequestParam(value = "mode", defaultValue = "month") String mode,
|
@RequestParam("types") String types) {
|
List<String> typeList = new java.util.ArrayList<>();
|
for (String t : types.split(",")) {
|
String s = t.trim();
|
if (!s.isEmpty()) typeList.add(s);
|
}
|
return Result.ok(reportService.reportPreview(period, mode, typeList));
|
}
|
|
private void logExport(String reportName, String period) {
|
operationLogService.record("报表生成", "导出报表", reportName + "(报表期:" + period + ")");
|
}
|
|
private void logExportZip(String zipName, String period) {
|
operationLogService.record("报表生成", "导出报表系列", zipName + "(报表期:" + period + ")");
|
}
|
|
private ResponseEntity<byte[]> zipResponse(byte[] data, String fileName) throws Exception {
|
String encoded = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
|
return ResponseEntity.ok()
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded)
|
.contentType(MediaType.parseMediaType("application/zip"))
|
.body(data);
|
}
|
|
private ResponseEntity<byte[]> buildResponse(byte[] data, String fileName) throws Exception {
|
String encoded = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
|
String type = fileName.toLowerCase().endsWith(".xls")
|
? "application/vnd.ms-excel"
|
: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
return ResponseEntity.ok()
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encoded)
|
.contentType(MediaType.parseMediaType(type))
|
.body(data);
|
}
|
}
|