|
@@ -493,6 +493,81 @@ public class SalesForecastSummaryController {
|
|
|
|
|
|
|
|
|
/**
|
|
|
+ * 根据预测主表ID导出销售预测明细数据到Excel
|
|
|
+ */
|
|
|
+ @GetMapping("/user/exportByMainId/{forecastMainId}")
|
|
|
+ public void userExportByMainId(@PathVariable Long forecastMainId, HttpServletResponse response) {
|
|
|
+
|
|
|
+ Long customerId = AuthUtil.getUserId();
|
|
|
+
|
|
|
+ PcBladeSalesForecastSummary pcBladeSalesForecastSummary = new PcBladeSalesForecastSummary();
|
|
|
+ pcBladeSalesForecastSummary.setCustomerId(customerId);
|
|
|
+ pcBladeSalesForecastSummary.setForecastMainId(forecastMainId);
|
|
|
+
|
|
|
+ // 1. 根据forecast_main_id查询明细数据
|
|
|
+ List<PcBladeSalesForecastSummary> summaryList = forecastService.findByForecastMainId(pcBladeSalesForecastSummary);
|
|
|
+
|
|
|
+ if (summaryList == null || summaryList.isEmpty()) {
|
|
|
+ try {
|
|
|
+ response.getWriter().write("没有找到对应的数据");
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 创建Excel工作簿
|
|
|
+ try (Workbook workbook = new XSSFWorkbook()) {
|
|
|
+ // 3. 创建工作表
|
|
|
+ Sheet sheet = workbook.createSheet("销售预测明细数据");
|
|
|
+
|
|
|
+ // 4. 创建表头样式
|
|
|
+ CellStyle headerStyle = createHeaderStyle(workbook);
|
|
|
+
|
|
|
+ // 5. 创建表头
|
|
|
+ String[] headers = {
|
|
|
+ "年份", "月份", "经销商编码", "经销商名称",
|
|
|
+ "品牌编码", "品牌名称", "物料编码", "物料名称",
|
|
|
+ "规格", "花纹", "预测数量", "审批状态"
|
|
|
+ };
|
|
|
+ Row headerRow = sheet.createRow(0);
|
|
|
+ for (int i = 0; i < headers.length; i++) {
|
|
|
+ Cell cell = headerRow.createCell(i);
|
|
|
+ cell.setCellValue(headers[i]);
|
|
|
+ cell.setCellStyle(headerStyle);
|
|
|
+ // 自动调整列宽
|
|
|
+ sheet.autoSizeColumn(i);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 填充数据
|
|
|
+ int rowNum = 1;
|
|
|
+ for (PcBladeSalesForecastSummary summary : summaryList) {
|
|
|
+ Row row = sheet.createRow(rowNum++);
|
|
|
+ fillSummaryDataRow(row, summary);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 设置响应头,准备下载
|
|
|
+ String fileName = "销售预测明细数据_" + forecastMainId + ".xlsx";
|
|
|
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
+ response.setHeader("Content-Disposition",
|
|
|
+ "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
|
|
|
+
|
|
|
+ // 8. 写入响应流
|
|
|
+ workbook.write(response.getOutputStream());
|
|
|
+ } catch (IOException e) {
|
|
|
+ // 实际应用中应该使用日志框架记录异常
|
|
|
+ e.printStackTrace();
|
|
|
+ // 可以考虑添加适当的异常处理逻辑
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
* 填充用户数据行
|
|
|
*/
|
|
|
private void fillUserDataRow(Row row, PcBladeSalesForecastMain main, PcBladeSalesForecastSummary summary) {
|
|
@@ -914,6 +989,121 @@ public class SalesForecastSummaryController {
|
|
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
+ * 根据预测主表ID导出销售预测明细数据到Excel
|
|
|
+ */
|
|
|
+ @GetMapping("/exportByMainId/{forecastMainId}")
|
|
|
+ public void exportByMainId(@PathVariable Long forecastMainId, HttpServletResponse response) {
|
|
|
+ // 1. 根据forecast_main_id查询明细数据
|
|
|
+ PcBladeSalesForecastSummary pcBladeSalesForecastSummary = new PcBladeSalesForecastSummary();
|
|
|
+ pcBladeSalesForecastSummary.setForecastMainId(forecastMainId);
|
|
|
+ List<PcBladeSalesForecastSummary> summaryList = forecastService.findByForecastMainId(pcBladeSalesForecastSummary);
|
|
|
+
|
|
|
+ if (summaryList == null || summaryList.isEmpty()) {
|
|
|
+ try {
|
|
|
+ response.getWriter().write("没有找到对应的数据");
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 创建Excel工作簿
|
|
|
+ try (Workbook workbook = new XSSFWorkbook()) {
|
|
|
+ // 3. 创建工作表
|
|
|
+ Sheet sheet = workbook.createSheet("销售预测明细数据");
|
|
|
+
|
|
|
+ // 4. 创建表头样式
|
|
|
+ CellStyle headerStyle = createHeaderStyle(workbook);
|
|
|
+
|
|
|
+ // 5. 创建表头
|
|
|
+ String[] headers = {
|
|
|
+ "年份", "月份", "经销商编码", "经销商名称",
|
|
|
+ "品牌编码", "品牌名称", "物料编码", "物料名称",
|
|
|
+ "规格", "花纹", "预测数量", "审批状态"
|
|
|
+ };
|
|
|
+ Row headerRow = sheet.createRow(0);
|
|
|
+ for (int i = 0; i < headers.length; i++) {
|
|
|
+ Cell cell = headerRow.createCell(i);
|
|
|
+ cell.setCellValue(headers[i]);
|
|
|
+ cell.setCellStyle(headerStyle);
|
|
|
+ // 自动调整列宽
|
|
|
+ sheet.autoSizeColumn(i);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 填充数据
|
|
|
+ int rowNum = 1;
|
|
|
+ for (PcBladeSalesForecastSummary summary : summaryList) {
|
|
|
+ Row row = sheet.createRow(rowNum++);
|
|
|
+ fillSummaryDataRow(row, summary);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7. 设置响应头,准备下载
|
|
|
+ String fileName = "销售预测明细数据_" + forecastMainId + ".xlsx";
|
|
|
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
+ response.setHeader("Content-Disposition",
|
|
|
+ "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
|
|
|
+
|
|
|
+ // 8. 写入响应流
|
|
|
+ workbook.write(response.getOutputStream());
|
|
|
+ } catch (IOException e) {
|
|
|
+ // 实际应用中应该使用日志框架记录异常
|
|
|
+ e.printStackTrace();
|
|
|
+ // 可以考虑添加适当的异常处理逻辑
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充明细数据行
|
|
|
+ */
|
|
|
+ private void fillSummaryDataRow(Row row, PcBladeSalesForecastSummary summary) {
|
|
|
+ int cellNum = 0;
|
|
|
+
|
|
|
+ // 年份
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getYear() != null ? summary.getYear() : 0);
|
|
|
+ // 月份
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getMonth() != null ? summary.getMonth() : 0);
|
|
|
+ // 经销商编码
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getCustomerCode() != null ? summary.getCustomerCode() : "");
|
|
|
+ // 经销商名称
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getCustomerName() != null ? summary.getCustomerName() : "");
|
|
|
+ // 品牌编码
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getBrandCode() != null ? summary.getBrandCode() : "");
|
|
|
+ // 品牌名称
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getBrandName() != null ? summary.getBrandName() : "");
|
|
|
+ // 物料编码
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getItemCode() != null ? summary.getItemCode() : "");
|
|
|
+ // 物料名称
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getItemName() != null ? summary.getItemName() : "");
|
|
|
+ // 规格
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getSpecs() != null ? summary.getSpecs() : "");
|
|
|
+ // 花纹
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getPattern() != null ? summary.getPattern() : "");
|
|
|
+ // 预测数量
|
|
|
+ if (summary.getForecastQuantity() != null) {
|
|
|
+ row.createCell(cellNum++).setCellValue(summary.getForecastQuantity().doubleValue());
|
|
|
+ } else {
|
|
|
+ row.createCell(cellNum++).setCellValue(0);
|
|
|
+ }
|
|
|
+ // 审批状态(转换为文字描述)
|
|
|
+ String approvalStatus = "";
|
|
|
+ if (summary.getApprovalStatus() != null) {
|
|
|
+ switch (summary.getApprovalStatus()) {
|
|
|
+ case 0:
|
|
|
+ approvalStatus = "未审批";
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ approvalStatus = "已通过";
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ approvalStatus = "已拒绝";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ approvalStatus = "未知";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ row.createCell(cellNum++).setCellValue(approvalStatus);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|