diff --git a/src/main/java/com/gunshi/project/hsz/controller/ForecastDispatchPlanController.java b/src/main/java/com/gunshi/project/hsz/controller/ForecastDispatchPlanController.java index 143f95f..60e9ca0 100644 --- a/src/main/java/com/gunshi/project/hsz/controller/ForecastDispatchPlanController.java +++ b/src/main/java/com/gunshi/project/hsz/controller/ForecastDispatchPlanController.java @@ -48,12 +48,19 @@ public class ForecastDispatchPlanController { return R.ok(forecastDispatchPlanService.deleteById(id)); } +// @Operation(summary = "导出") +// @PostMapping("/export") +// public void export(@RequestBody @Validated ForecastDispatchPlanPageSo page, HttpServletResponse response) { +// page.getPageSo().setPageSize(90000); +// Page forecastDispatchPlanPage = forecastDispatchPlanService.pageDetail(page); +// List records = forecastDispatchPlanPage.getRecords(); +// forecastDispatchPlanService.export(records,response); +// } + @Operation(summary = "导出") @PostMapping("/export") - public void export(@RequestBody @Validated ForecastDispatchPlanPageSo page, HttpServletResponse response) { - page.getPageSo().setPageSize(90000); - Page forecastDispatchPlanPage = forecastDispatchPlanService.pageDetail(page); - List records = forecastDispatchPlanPage.getRecords(); + public void export(@RequestParam("ids") List ids, HttpServletResponse response) { + List records = forecastDispatchPlanService.selectByIds(ids); forecastDispatchPlanService.export(records,response); } } diff --git a/src/main/java/com/gunshi/project/hsz/model/ForecastDispatchPlan.java b/src/main/java/com/gunshi/project/hsz/model/ForecastDispatchPlan.java index 1d4873a..32c2d1e 100644 --- a/src/main/java/com/gunshi/project/hsz/model/ForecastDispatchPlan.java +++ b/src/main/java/com/gunshi/project/hsz/model/ForecastDispatchPlan.java @@ -49,6 +49,15 @@ public class ForecastDispatchPlan implements Serializable { @NotNull(message = "方案名称不能为空") private String planName; + /** + * 洪水预报方案名称 + */ + @TableField(value = "forecast_plan_name") + @Schema(description = "方案名称") + @Size(max = 255, message = "方案名称最大长度要小于 255") + @NotNull(message = "方案名称不能为空") + private String forecastPlanName; + /** * 开始时间 */ diff --git a/src/main/java/com/gunshi/project/hsz/service/ForecastDispatchPlanService.java b/src/main/java/com/gunshi/project/hsz/service/ForecastDispatchPlanService.java index ff72918..1dcf17d 100644 --- a/src/main/java/com/gunshi/project/hsz/service/ForecastDispatchPlanService.java +++ b/src/main/java/com/gunshi/project/hsz/service/ForecastDispatchPlanService.java @@ -13,16 +13,21 @@ import com.ruoyi.common.utils.StringUtils; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.io.Serializable; +import java.io.*; import java.net.URLEncoder; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; /** * 描述: 调度方案主表 @@ -58,6 +63,19 @@ public class ForecastDispatchPlanService extends ServiceImpl selectByIds(List ids) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(ForecastDispatchPlan::getId, ids); + List forecastDispatchPlans = this.baseMapper.selectList(queryWrapper); + for (ForecastDispatchPlan record : forecastDispatchPlans) { + List forecastDispatchCommandList = forecastDispatchCommandService.lambdaQuery().eq(ForecastDispatchCommand::getPlanId, record.getId()).list(); + record.setForecastDispatchCommands(forecastDispatchCommandList); + ForecastDispatchResult forecastDispatchResult = forecastDispatchResultService.lambdaQuery().eq(ForecastDispatchResult::getPlanId, record.getId()).one(); + record.setForecastDispatchResult(forecastDispatchResult); + } + return forecastDispatchPlans; + } + public Boolean deleteById(Serializable id) { boolean flag = removeById(id); if(flag){ @@ -83,60 +101,114 @@ public class ForecastDispatchPlanService extends ServiceImpl page, HttpServletResponse response) { + // 创建临时目录 + String tempDir = System.getProperty("java.io.tmpdir") + File.separator + "export_" + UUID.randomUUID(); + File dir = new File(tempDir); + if (!dir.exists()) { + dir.mkdirs(); + } + + List excelFiles = new ArrayList<>(); + try { + // 为每个方案创建Excel文件 + for (int i = 0; i < page.size(); i++) { + ForecastDispatchPlan plan = page.get(i); + File excelFile = createExcelForPlan(plan, tempDir, i + 1); + excelFiles.add(excelFile); + } + + // 创建ZIP压缩包 + String zipFileName = "调度方案数据导出_" + + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".zip"; + // 设置响应头 - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setContentType("application/zip"); response.setCharacterEncoding("utf-8"); - String fileName = URLEncoder.encode("调度方案数据导出", "UTF-8").replaceAll("\\+", "%20"); - response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + response.setHeader("Content-disposition", + "attachment;filename*=utf-8''" + URLEncoder.encode(zipFileName, "UTF-8").replaceAll("\\+", "%20")); - // 创建Excel工作簿 - Workbook workbook = new XSSFWorkbook(); + // 创建ZIP输出流 + ZipOutputStream zos = new ZipOutputStream(response.getOutputStream()); - // 创建单元格样式 - CellStyle headerStyle = createHeaderStyle(workbook); - CellStyle dataStyle = createDataStyle(workbook); - CellStyle titleStyle = createTitleStyle(workbook); + // 将Excel文件添加到ZIP + for (File excelFile : excelFiles) { + ZipEntry zipEntry = new ZipEntry(excelFile.getName()); + zos.putNextEntry(zipEntry); - // 在同一个Sheet页中按方案分组导出数据 - exportGroupedData(workbook, page, headerStyle, dataStyle, titleStyle); + try (FileInputStream fis = new FileInputStream(excelFile)) { + byte[] buffer = new byte[1024]; + int len; + while ((len = fis.read(buffer)) > 0) { + zos.write(buffer, 0, len); + } + } + zos.closeEntry(); + } + + zos.close(); - // 写入响应流 - workbook.write(response.getOutputStream()); - workbook.close(); } catch (Exception e) { log.error("导出Excel失败", e); throw new RuntimeException("导出失败"); + } finally { + // 清理临时文件 + for (File file : excelFiles) { + if (file.exists()) { + file.delete(); + } + } + if (dir.exists()) { + dir.delete(); + } } } /** - * 按方案分组导出数据 + * 为单个调度方案创建Excel文件 */ - private void exportGroupedData(Workbook workbook, List dataList, CellStyle headerStyle, CellStyle dataStyle, CellStyle titleStyle) { - Sheet sheet = workbook.createSheet("调度方案数据"); + private File createExcelForPlan(ForecastDispatchPlan plan, String tempDir, int index) throws IOException { + // 创建Excel工作簿 + Workbook workbook = new XSSFWorkbook(); + + // 创建单元格样式 + CellStyle headerStyle = createHeaderStyle(workbook); + CellStyle dataStyle = createDataStyle(workbook); + CellStyle titleStyle = createTitleStyle(workbook); + + // 创建Sheet + String sheetName = "调度方案"; + Sheet sheet = workbook.createSheet(sheetName); int currentRow = 0; - for (ForecastDispatchPlan plan : dataList) { - // 1. 导出调度方案基本信息 - currentRow = exportPlanBasicInfo(sheet, currentRow, plan, titleStyle, dataStyle); + // 1. 导出调度方案基本信息 + currentRow = exportPlanBasicInfo(sheet, currentRow, plan, titleStyle, dataStyle); - // 2. 导出调度结果 - currentRow = exportPlanResult(sheet, currentRow, plan, headerStyle, dataStyle); + // 2. 导出调度结果 + currentRow = exportPlanResult(sheet, currentRow, plan, headerStyle, dataStyle); - // 3. 导出调度指令 - currentRow = exportPlanCommands(sheet, currentRow, plan, headerStyle, dataStyle); + // 3. 导出调度指令 + currentRow = exportPlanCommands(sheet, currentRow, plan, headerStyle, dataStyle); - // 添加空行分隔不同方案 - currentRow += 2; + // 生成文件名 + String fileName = plan.getPlanName(); + File excelFile = new File(tempDir, fileName + ".xlsx"); + + // 写入文件 + try (FileOutputStream fos = new FileOutputStream(excelFile)) { + workbook.write(fos); } + + workbook.close(); + + return excelFile; } + /** - * 导出调度方案基本信息 + * 导出调度方案基本信息(保持原有逻辑) */ private int exportPlanBasicInfo(Sheet sheet, int startRow, ForecastDispatchPlan plan, CellStyle titleStyle, CellStyle dataStyle) { // 方案标题 @@ -145,6 +217,9 @@ public class ForecastDispatchPlanService extends ServiceImpl commands = plan.getForecastDispatchCommands(); @@ -240,6 +322,9 @@ public class ForecastDispatchPlanService extends ServiceImpl