修改excel导出逻辑
parent
564d028889
commit
7e4bdbce28
|
|
@ -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<ForecastDispatchPlan> forecastDispatchPlanPage = forecastDispatchPlanService.pageDetail(page);
|
||||
// List<ForecastDispatchPlan> 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<ForecastDispatchPlan> forecastDispatchPlanPage = forecastDispatchPlanService.pageDetail(page);
|
||||
List<ForecastDispatchPlan> records = forecastDispatchPlanPage.getRecords();
|
||||
public void export(@RequestParam("ids") List<String> ids, HttpServletResponse response) {
|
||||
List<ForecastDispatchPlan> records = forecastDispatchPlanService.selectByIds(ids);
|
||||
forecastDispatchPlanService.export(records,response);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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<ForecastDispatchPla
|
|||
return forecastDispatchPlanPage;
|
||||
}
|
||||
|
||||
public List<ForecastDispatchPlan> selectByIds(List<String> ids) {
|
||||
LambdaQueryWrapper<ForecastDispatchPlan> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.in(ForecastDispatchPlan::getId, ids);
|
||||
List<ForecastDispatchPlan> forecastDispatchPlans = this.baseMapper.selectList(queryWrapper);
|
||||
for (ForecastDispatchPlan record : forecastDispatchPlans) {
|
||||
List<ForecastDispatchCommand> 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,15 +101,74 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
forecastDispatchCommandService.saveBatch(forecastDispatchCommands);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void export(List<ForecastDispatchPlan> page, HttpServletResponse response) {
|
||||
try {
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = URLEncoder.encode("调度方案数据导出", "UTF-8").replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||
// 创建临时目录
|
||||
String tempDir = System.getProperty("java.io.tmpdir") + File.separator + "export_" + UUID.randomUUID();
|
||||
File dir = new File(tempDir);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
List<File> 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/zip");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setHeader("Content-disposition",
|
||||
"attachment;filename*=utf-8''" + URLEncoder.encode(zipFileName, "UTF-8").replaceAll("\\+", "%20"));
|
||||
|
||||
// 创建ZIP输出流
|
||||
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
|
||||
|
||||
// 将Excel文件添加到ZIP
|
||||
for (File excelFile : excelFiles) {
|
||||
ZipEntry zipEntry = new ZipEntry(excelFile.getName());
|
||||
zos.putNextEntry(zipEntry);
|
||||
|
||||
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();
|
||||
|
||||
} 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 File createExcelForPlan(ForecastDispatchPlan plan, String tempDir, int index) throws IOException {
|
||||
// 创建Excel工作簿
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
|
||||
|
|
@ -100,27 +177,12 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
CellStyle dataStyle = createDataStyle(workbook);
|
||||
CellStyle titleStyle = createTitleStyle(workbook);
|
||||
|
||||
// 在同一个Sheet页中按方案分组导出数据
|
||||
exportGroupedData(workbook, page, headerStyle, dataStyle, titleStyle);
|
||||
|
||||
// 写入响应流
|
||||
workbook.write(response.getOutputStream());
|
||||
workbook.close();
|
||||
} catch (Exception e) {
|
||||
log.error("导出Excel失败", e);
|
||||
throw new RuntimeException("导出失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按方案分组导出数据
|
||||
*/
|
||||
private void exportGroupedData(Workbook workbook, List<ForecastDispatchPlan> dataList, CellStyle headerStyle, CellStyle dataStyle, CellStyle titleStyle) {
|
||||
Sheet sheet = workbook.createSheet("调度方案数据");
|
||||
// 创建Sheet
|
||||
String sheetName = "调度方案";
|
||||
Sheet sheet = workbook.createSheet(sheetName);
|
||||
|
||||
int currentRow = 0;
|
||||
|
||||
for (ForecastDispatchPlan plan : dataList) {
|
||||
// 1. 导出调度方案基本信息
|
||||
currentRow = exportPlanBasicInfo(sheet, currentRow, plan, titleStyle, dataStyle);
|
||||
|
||||
|
|
@ -130,13 +192,23 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
// 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<ForecastDispatchPla
|
|||
titleCell.setCellValue("调度方案:" + getStringValue(plan.getPlanName()));
|
||||
titleCell.setCellStyle(titleStyle);
|
||||
|
||||
// 合并单元格(标题跨5列)
|
||||
sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(), titleRow.getRowNum(), 0, 4));
|
||||
|
||||
// 基本信息表头
|
||||
Row headerRow = sheet.createRow(startRow++);
|
||||
String[] headers = {"开始时间", "结束时间", "制定时间", "制定人", "水库控制水位(m)"};
|
||||
|
|
@ -167,14 +242,16 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
|
||||
// 设置数据行样式
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
if (dataRow.getCell(i) != null) {
|
||||
dataRow.getCell(i).setCellStyle(dataStyle);
|
||||
}
|
||||
}
|
||||
|
||||
return startRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出调度结果
|
||||
* 导出调度结果(保持原有逻辑)
|
||||
*/
|
||||
private int exportPlanResult(Sheet sheet, int startRow, ForecastDispatchPlan plan, CellStyle headerStyle, CellStyle dataStyle) {
|
||||
ForecastDispatchResult result = plan.getForecastDispatchResult();
|
||||
|
|
@ -188,6 +265,9 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
resultTitleCell.setCellValue("调度结果");
|
||||
resultTitleCell.setCellStyle(headerStyle);
|
||||
|
||||
// 合并单元格(结果标题跨7列)
|
||||
sheet.addMergedRegion(new CellRangeAddress(resultTitleRow.getRowNum(), resultTitleRow.getRowNum(), 0, 6));
|
||||
|
||||
// 结果表头
|
||||
Row resultHeaderRow = sheet.createRow(startRow++);
|
||||
String[] resultHeaders = {
|
||||
|
|
@ -219,14 +299,16 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
|
||||
// 设置数据行样式
|
||||
for (int i = 0; i < resultHeaders.length; i++) {
|
||||
if (resultDataRow.getCell(i) != null) {
|
||||
resultDataRow.getCell(i).setCellStyle(dataStyle);
|
||||
}
|
||||
}
|
||||
|
||||
return startRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出调度指令
|
||||
* 导出调度指令(保持原有逻辑)
|
||||
*/
|
||||
private int exportPlanCommands(Sheet sheet, int startRow, ForecastDispatchPlan plan, CellStyle headerStyle, CellStyle dataStyle) {
|
||||
List<ForecastDispatchCommand> commands = plan.getForecastDispatchCommands();
|
||||
|
|
@ -240,6 +322,9 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
commandTitleCell.setCellValue("调度指令");
|
||||
commandTitleCell.setCellStyle(headerStyle);
|
||||
|
||||
// 合并单元格(指令标题跨5列)
|
||||
sheet.addMergedRegion(new CellRangeAddress(commandTitleRow.getRowNum(), commandTitleRow.getRowNum(), 0, 4));
|
||||
|
||||
// 指令表头
|
||||
Row commandHeaderRow = sheet.createRow(startRow++);
|
||||
String[] commandHeaders = {
|
||||
|
|
@ -264,15 +349,17 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
|
||||
// 设置数据行样式
|
||||
for (int i = 0; i < commandHeaders.length; i++) {
|
||||
if (commandDataRow.getCell(i) != null) {
|
||||
commandDataRow.getCell(i).setCellStyle(dataStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return startRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建标题样式
|
||||
* 创建标题样式(保持原有逻辑)
|
||||
*/
|
||||
private CellStyle createTitleStyle(Workbook workbook) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
|
|
@ -284,7 +371,7 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
}
|
||||
|
||||
/**
|
||||
* 创建表头样式
|
||||
* 创建表头样式(保持原有逻辑)
|
||||
*/
|
||||
private CellStyle createHeaderStyle(Workbook workbook) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
|
|
@ -304,7 +391,7 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
}
|
||||
|
||||
/**
|
||||
* 创建数据样式
|
||||
* 创建数据样式(保持原有逻辑)
|
||||
*/
|
||||
private CellStyle createDataStyle(Workbook workbook) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
|
|
@ -318,7 +405,7 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
* 格式化时间(保持原有逻辑)
|
||||
*/
|
||||
private String formatDateTime(LocalDateTime dateTime) {
|
||||
if (dateTime == null) {
|
||||
|
|
@ -329,14 +416,14 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
}
|
||||
|
||||
/**
|
||||
* 获取字符串值
|
||||
* 获取字符串值(保持原有逻辑)
|
||||
*/
|
||||
private String getStringValue(String value) {
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取闸门状态文字
|
||||
* 获取闸门状态文字(保持原有逻辑)
|
||||
*/
|
||||
private String getGateStatus(Integer status) {
|
||||
if (status == null) {
|
||||
|
|
@ -344,4 +431,6 @@ public class ForecastDispatchPlanService extends ServiceImpl<ForecastDispatchPla
|
|||
}
|
||||
return status == 1 ? "开" : "关";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue