| | |
| | | |
| | | 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 javax.annotation.Resource; |
| | | import java.net.URLEncoder; |
| | | import java.util.List; |
| | | import java.nio.charset.StandardCharsets; |
| | | |
| | | @Slf4j |
| | |
| | | |
| | | @Resource |
| | | private ReportExportService reportService; |
| | | @Resource |
| | | private OperationLogService operationLogService; |
| | | |
| | | /** 生成_货运量分市州明细.xlsx */ |
| | | @GetMapping("/export/cityDetail") |
| | | public ResponseEntity<byte[]> exportCityDetail(@RequestParam("period") String period) throws Exception { |
| | | return buildResponse(reportService.exportCityDetail(period), "生成_货运量分市州明细.xlsx"); |
| | | 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) throws Exception { |
| | | return buildResponse(reportService.exportFreightRank(period), "生成_货运量排名.xlsx"); |
| | | 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) throws Exception { |
| | | return buildResponse(reportService.exportTurnoverRank(period), "生成_周转量排名.xlsx"); |
| | | 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("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) |
| | | .contentType(MediaType.parseMediaType(type)) |
| | | .body(data); |
| | | } |
| | | } |