Commit 8b456ed1652ea48dd81e8eefdb1d1b04c107c70b

Authored by yeqianyong
1 parent 87670dcb

楚江ERP-订货单规格变更记录导出功能开发

1 package com.lframework.xingyun.sc.controller.order; 1 package com.lframework.xingyun.sc.controller.order;
2 2
  3 +import cn.hutool.core.io.resource.ClassPathResource;
3 import com.lframework.starter.web.core.annotations.security.HasPermission; 4 import com.lframework.starter.web.core.annotations.security.HasPermission;
4 import com.lframework.starter.web.core.controller.DefaultBaseController; 5 import com.lframework.starter.web.core.controller.DefaultBaseController;
  6 +import com.lframework.starter.web.core.utils.JsonUtil;
5 import com.lframework.xingyun.sc.bo.order.change.OrderSpecificationChangeRecordBo; 7 import com.lframework.xingyun.sc.bo.order.change.OrderSpecificationChangeRecordBo;
  8 +import com.lframework.xingyun.sc.entity.PurchaseOrderLine;
6 import com.lframework.xingyun.sc.enums.OrderSpecChangeStatus; 9 import com.lframework.xingyun.sc.enums.OrderSpecChangeStatus;
  10 +import com.lframework.xingyun.sc.utils.ExcelUtil;
  11 +import com.lframework.xingyun.sc.utils.ResponseUtil;
7 import com.lframework.xingyun.sc.vo.order.change.QueryOrderSpecificationChangeRecordVo; 12 import com.lframework.xingyun.sc.vo.order.change.QueryOrderSpecificationChangeRecordVo;
8 import com.lframework.xingyun.sc.service.order.OrderSpecificationChangeRecordService; 13 import com.lframework.xingyun.sc.service.order.OrderSpecificationChangeRecordService;
9 import com.lframework.xingyun.sc.vo.order.change.CreateOrderSpecificationChangeRecordVo; 14 import com.lframework.xingyun.sc.vo.order.change.CreateOrderSpecificationChangeRecordVo;
@@ -14,6 +19,7 @@ import com.lframework.starter.web.core.components.resp.PageResult; @@ -14,6 +19,7 @@ import com.lframework.starter.web.core.components.resp.PageResult;
14 import com.lframework.starter.web.core.components.resp.InvokeResult; 19 import com.lframework.starter.web.core.components.resp.InvokeResult;
15 20
16 import javax.annotation.Resource; 21 import javax.annotation.Resource;
  22 +import javax.servlet.http.HttpServletResponse;
17 import javax.validation.constraints.NotBlank; 23 import javax.validation.constraints.NotBlank;
18 import io.swagger.annotations.ApiImplicitParam; 24 import io.swagger.annotations.ApiImplicitParam;
19 import com.lframework.starter.web.core.components.resp.InvokeResultBuilder; 25 import com.lframework.starter.web.core.components.resp.InvokeResultBuilder;
@@ -21,12 +27,22 @@ import com.lframework.starter.common.exceptions.impl.DefaultClientException; @@ -21,12 +27,22 @@ import com.lframework.starter.common.exceptions.impl.DefaultClientException;
21 import io.swagger.annotations.ApiOperation; 27 import io.swagger.annotations.ApiOperation;
22 import com.lframework.starter.common.utils.CollectionUtil; 28 import com.lframework.starter.common.utils.CollectionUtil;
23 import io.swagger.annotations.Api; 29 import io.swagger.annotations.Api;
  30 +import lombok.extern.slf4j.Slf4j;
  31 +import org.apache.commons.lang3.StringUtils;
  32 +import org.apache.poi.ss.usermodel.Sheet;
  33 +import org.apache.poi.ss.usermodel.Workbook;
  34 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
24 import org.springframework.web.bind.annotation.DeleteMapping; 35 import org.springframework.web.bind.annotation.DeleteMapping;
25 import org.springframework.validation.annotation.Validated; 36 import org.springframework.validation.annotation.Validated;
26 import org.springframework.web.bind.annotation.*; 37 import org.springframework.web.bind.annotation.*;
27 38
28 import javax.validation.Valid; 39 import javax.validation.Valid;
  40 +import java.io.FileNotFoundException;
  41 +import java.io.IOException;
  42 +import java.io.InputStream;
  43 +import java.time.format.DateTimeFormatter;
29 import java.util.List; 44 import java.util.List;
  45 +import java.util.Map;
30 import java.util.stream.Collectors; 46 import java.util.stream.Collectors;
31 47
32 /** 48 /**
@@ -35,6 +51,7 @@ import java.util.stream.Collectors; @@ -35,6 +51,7 @@ import java.util.stream.Collectors;
35 */ 51 */
36 @Api(tags = "订货单规格变更记录") 52 @Api(tags = "订货单规格变更记录")
37 @Validated 53 @Validated
  54 +@Slf4j
38 @RestController 55 @RestController
39 @RequestMapping("/order/change") 56 @RequestMapping("/order/change")
40 public class OrderSpecificationChangeRecordController extends DefaultBaseController { 57 public class OrderSpecificationChangeRecordController extends DefaultBaseController {
@@ -120,4 +137,87 @@ public class OrderSpecificationChangeRecordController extends DefaultBaseControl @@ -120,4 +137,87 @@ public class OrderSpecificationChangeRecordController extends DefaultBaseControl
120 orderSpecificationChangeRecordService.updateStatus(id, OrderSpecChangeStatus.CANCEL.getCode()); 137 orderSpecificationChangeRecordService.updateStatus(id, OrderSpecChangeStatus.CANCEL.getCode());
121 return InvokeResultBuilder.success(); 138 return InvokeResultBuilder.success();
122 } 139 }
  140 +
  141 + /**
  142 + * 规格变更打印
  143 + * @param id 主键ID
  144 + * @param response 响应体
  145 + */
  146 + @ApiOperation("规格变更打印")
  147 + @GetMapping("/printOrderSpecChangeRecord")
  148 + public void printOrderSpecChangeRecord(@NotBlank(message = "id不能为空") String id, HttpServletResponse response) {
  149 + OrderSpecificationChangeRecord data = orderSpecificationChangeRecordService.findById(id);
  150 + // 加载模板文件
  151 + ClassPathResource templateResource = new ClassPathResource("templates/orderSpecChangeTemplate.xlsx");
  152 + try (InputStream inputStream = templateResource.getStream();
  153 + Workbook workbook = new XSSFWorkbook(inputStream)) {
  154 + // 设置响应头
  155 + ResponseUtil.setResponseHead(response, data.getOrderNo() + "-订货单规格变更记录.xlsx");
  156 +
  157 + Sheet sheet = workbook.getSheetAt(0);
  158 + // 规格变更开始行
  159 + int startRow = 5;
  160 + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  161 + List<PurchaseOrderLine> beforeChangeSpecList = data.getBeforeChangeSpecList();
  162 + List<PurchaseOrderLine> afterChangeSpecList = data.getAfterChangeSpecList();
  163 + // 取最大数据行
  164 + int dataLine = Math.max(beforeChangeSpecList.size(), afterChangeSpecList.size());
  165 + for (int i = startRow + 1; i < startRow + dataLine; i++) {
  166 + ExcelUtil.copyRow(workbook, sheet, startRow, i);
  167 + }
  168 + for (int i = 0; i < dataLine; i++) {
  169 + PurchaseOrderLine beforeOrderLine = (i + 1) <= beforeChangeSpecList.size() ? beforeChangeSpecList.get(i) : null;
  170 + PurchaseOrderLine afterOrderLine = (i + 1) <= afterChangeSpecList.size() ? afterChangeSpecList.get(i) : null;
  171 + // 变更前数据填充
  172 + if (beforeOrderLine != null ) {
  173 + ExcelUtil.setCellValue(sheet, startRow, 0, beforeOrderLine.getBrand());
  174 + ExcelUtil.setCellValue(sheet, startRow, 1, beforeOrderLine.getThickness());
  175 + ExcelUtil.setCellValue(sheet, startRow, 2, beforeOrderLine.getWidth());
  176 + ExcelUtil.setCellValue(sheet, startRow, 3, beforeOrderLine.getLength());
  177 + ExcelUtil.setCellValue(sheet, startRow, 4, beforeOrderLine.getStatus());
  178 + ExcelUtil.setCellValue(sheet, startRow, 5, beforeOrderLine.getQuantity());
  179 + ExcelUtil.setCellValue(sheet, startRow, 6, beforeOrderLine.getSalesPrice());
  180 + }
  181 + // 变更后数据填充
  182 + if (afterOrderLine != null) {
  183 + ExcelUtil.setCellValue(sheet, startRow, 7, afterOrderLine.getBrand());
  184 + ExcelUtil.setCellValue(sheet, startRow, 8, afterOrderLine.getThickness());
  185 + ExcelUtil.setCellValue(sheet, startRow, 9, afterOrderLine.getWidth());
  186 + ExcelUtil.setCellValue(sheet, startRow, 10, afterOrderLine.getLength());
  187 + ExcelUtil.setCellValue(sheet, startRow, 11, afterOrderLine.getStatus());
  188 + ExcelUtil.setCellValue(sheet, startRow, 12, afterOrderLine.getQuantity());
  189 + ExcelUtil.setCellValue(sheet, startRow, 13, afterOrderLine.getSalesPrice());
  190 + }
  191 + startRow++;
  192 + }
  193 + Map<String, Object> dataMap = JsonUtil.parseMap(JsonUtil.toJsonString(data), String.class, Object.class);
  194 + dataMap.put("orderDate", data.getOrderDate() == null ? "" : data.getOrderDate().format(dateFormatter));
  195 + dataMap.put("deliveryDate", data.getDeliveryDate() == null ? "" : data.getDeliveryDate().format(dateFormatter));
  196 + dataMap.put("createTime", data.getCreateTime().format(dateFormatter));
  197 + dataMap.put("description", StringUtils.isBlank(data.getDescription()) ? "" : data.getDescription());
  198 + // 供货单位
  199 + String supplyUnit = data.getSupplyUnit();
  200 + if (StringUtils.isNotBlank(supplyUnit)) {
  201 + if ("GJ".equals(supplyUnit)) {
  202 + dataMap.put("supplyUnit", "安徽楚江高精铜带有限公司");
  203 + } else if ("XC".equals(supplyUnit)) {
  204 + dataMap.put("supplyUnit", "安徽楚江科技新材料股份有限公司");
  205 + }
  206 + }
  207 +
  208 + ExcelUtil.processTemplate(workbook, dataMap);
  209 + // 写入响应流
  210 + workbook.write(response.getOutputStream());
  211 + response.getOutputStream().flush();
  212 + } catch (FileNotFoundException e) {
  213 + log.error("订货单规格变更模版打印失败: ", e);
  214 + throw new DefaultClientException("模板文件不存在: templates/orderSpecChangeTemplate.xlsx");
  215 + } catch (IOException e) {
  216 + log.error("订货单规格变更模版打印失败: ", e);
  217 + throw new DefaultClientException("无法读取模板文件: templates/orderSpecChangeTemplate.xlsx");
  218 + } catch (Exception e) {
  219 + log.error("订货单规格变更模版打印失败: ", e);
  220 + throw new DefaultClientException(e.getMessage());
  221 + }
  222 + }
123 } 223 }
@@ -43,6 +43,14 @@ public class OrderSpecificationChangeRecord extends BaseEntity implements BaseDt @@ -43,6 +43,14 @@ public class OrderSpecificationChangeRecord extends BaseEntity implements BaseDt
43 private String orderingUnitName; 43 private String orderingUnitName;
44 44
45 /** 45 /**
  46 + * 供货单位
  47 + * 安徽楚江高精铜带有限公司(GJ)、安徽楚江科技新材料股份有限公司(XC)
  48 + * 非持久化字段
  49 + */
  50 + @TableField(exist = false)
  51 + private String supplyUnit;
  52 +
  53 + /**
46 * 订货单编号 54 * 订货单编号
47 * 非持久化字段 55 * 非持久化字段
48 */ 56 */
@@ -8,6 +8,8 @@ import com.lframework.starter.web.core.components.security.SecurityUtil; @@ -8,6 +8,8 @@ import com.lframework.starter.web.core.components.security.SecurityUtil;
8 import com.lframework.starter.web.core.utils.*; 8 import com.lframework.starter.web.core.utils.*;
9 import com.lframework.starter.web.inner.entity.SysUser; 9 import com.lframework.starter.web.inner.entity.SysUser;
10 import com.lframework.starter.web.inner.service.system.SysUserService; 10 import com.lframework.starter.web.inner.service.system.SysUserService;
  11 +import com.lframework.xingyun.basedata.entity.Customer;
  12 +import com.lframework.xingyun.basedata.service.customer.CustomerService;
11 import com.lframework.xingyun.sc.entity.OrderSpecificationChangeRecord; 13 import com.lframework.xingyun.sc.entity.OrderSpecificationChangeRecord;
12 import com.lframework.starter.web.core.impl.BaseMpServiceImpl; 14 import com.lframework.starter.web.core.impl.BaseMpServiceImpl;
13 import com.lframework.starter.web.core.components.resp.PageResult; 15 import com.lframework.starter.web.core.components.resp.PageResult;
@@ -16,6 +18,7 @@ import com.lframework.starter.common.utils.ObjectUtil; @@ -16,6 +18,7 @@ import com.lframework.starter.common.utils.ObjectUtil;
16 import com.lframework.starter.web.core.annotations.oplog.OpLog; 18 import com.lframework.starter.web.core.annotations.oplog.OpLog;
17 import com.lframework.starter.common.utils.Assert; 19 import com.lframework.starter.common.utils.Assert;
18 import com.lframework.starter.web.inner.components.oplog.OtherOpLogType; 20 import com.lframework.starter.web.inner.components.oplog.OtherOpLogType;
  21 +import com.lframework.xingyun.sc.entity.PurchaseOrderInfo;
19 import com.lframework.xingyun.sc.entity.PurchaseOrderLine; 22 import com.lframework.xingyun.sc.entity.PurchaseOrderLine;
20 import com.lframework.xingyun.sc.enums.OrderSpecChangeStatus; 23 import com.lframework.xingyun.sc.enums.OrderSpecChangeStatus;
21 import com.lframework.xingyun.sc.service.order.PurchaseOrderInfoService; 24 import com.lframework.xingyun.sc.service.order.PurchaseOrderInfoService;
@@ -48,6 +51,8 @@ public class OrderSpecificationChangeRecordServiceImpl extends BaseMpServiceImpl @@ -48,6 +51,8 @@ public class OrderSpecificationChangeRecordServiceImpl extends BaseMpServiceImpl
48 private PurchaseOrderInfoService purchaseOrderInfoService; 51 private PurchaseOrderInfoService purchaseOrderInfoService;
49 @Resource 52 @Resource
50 private FlowInstanceWrapperService flowInstanceWrapperService; 53 private FlowInstanceWrapperService flowInstanceWrapperService;
  54 + @Resource
  55 + private CustomerService customerService;
51 56
52 57
53 @Override 58 @Override
@@ -111,11 +116,20 @@ public class OrderSpecificationChangeRecordServiceImpl extends BaseMpServiceImpl @@ -111,11 +116,20 @@ public class OrderSpecificationChangeRecordServiceImpl extends BaseMpServiceImpl
111 OrderSpecificationChangeRecord changeRecord = getBaseMapper().selectById(id); 116 OrderSpecificationChangeRecord changeRecord = getBaseMapper().selectById(id);
112 if (changeRecord == null) { 117 if (changeRecord == null) {
113 throw new DefaultClientException("订货单规格变更记录不存在!"); 118 throw new DefaultClientException("订货单规格变更记录不存在!");
114 - };  
115 - String orderId = changeRecord.getOrderId(); 119 + }
  120 + // 获取订货单相关数据
  121 + PurchaseOrderInfo orderInfo = purchaseOrderInfoService.findById(changeRecord.getOrderId());
  122 + if (orderInfo != null) {
  123 + changeRecord.setOrderNo(orderInfo.getOrderNo());
  124 + changeRecord.setOrderDate(orderInfo.getOrderDate());
  125 + changeRecord.setSupplyUnit(orderInfo.getSupplyUnit());
  126 + // 订货公司数据
  127 + Customer customer = customerService.findById(orderInfo.getOrderingUnit());
  128 + changeRecord.setOrderingUnitName(customer.getName());
  129 + }
116 // 获取规格数据 130 // 获取规格数据
117 // 变更前 131 // 变更前
118 - List<PurchaseOrderLine> beforeChangeList = purchaseOrderLineService.listByOrderIds(Collections.singletonList(orderId)); 132 + List<PurchaseOrderLine> beforeChangeList = purchaseOrderLineService.listByOrderIds(Collections.singletonList(changeRecord.getOrderId()));
119 changeRecord.setBeforeChangeSpecList(beforeChangeList); 133 changeRecord.setBeforeChangeSpecList(beforeChangeList);
120 // 变更后 134 // 变更后
121 List<PurchaseOrderLine> afterChangeList = purchaseOrderLineService.listByChangeIds(Collections.singletonList(id)); 135 List<PurchaseOrderLine> afterChangeList = purchaseOrderLineService.listByChangeIds(Collections.singletonList(id));
  1 +package com.lframework.xingyun.sc.utils;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.apache.poi.ss.usermodel.*;
  5 +import org.apache.poi.ss.util.CellRangeAddress;
  6 +
  7 +import javax.swing.*;
  8 +import java.awt.*;
  9 +import java.math.BigDecimal;
  10 +import java.time.LocalDate;
  11 +import java.time.format.DateTimeFormatter;
  12 +import java.util.ArrayList;
  13 +import java.util.List;
  14 +import java.util.Map;
  15 +
  16 +@Slf4j
  17 +public class ExcelUtil {
  18 +
  19 +
  20 + /**
  21 + * 根据Excel模板封装数据
  22 + *
  23 + * @param workbook Excel文件
  24 + * @param dataMap 数据实体
  25 + */
  26 + public static void processTemplate(Workbook workbook, Map<String, Object> dataMap) {
  27 + Sheet sheet = workbook.getSheetAt(0);
  28 + for (Row row : sheet) {
  29 + for (Cell cell : row) {
  30 + if (cell.getCellTypeEnum() == CellType.STRING) {
  31 + String cellValue = cell.getStringCellValue();
  32 + String newValue = replacePlaceholders(cellValue, dataMap);
  33 + if (!cellValue.equals(newValue)) {
  34 + cell.setCellValue(newValue);
  35 + }
  36 + }
  37 + }
  38 + }
  39 + }
  40 +
  41 +
  42 + /**
  43 + * 解析占位符
  44 + * @param text 文本内容
  45 + * @param dataMap 数据实体
  46 + * @return String
  47 + */
  48 + public static String replacePlaceholders(String text, Map<String, Object> dataMap) {
  49 + if (text == null || text.isEmpty()) {
  50 + return text;
  51 + }
  52 + String result = text;
  53 + for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
  54 + String placeholder = "${" + entry.getKey() + "}";
  55 + String value = entry.getValue() != null ? entry.getValue().toString() : "";
  56 + // 将数据库中的 \n 转换为 Excel 识别的换行符
  57 + value = value.replace("\\n", "\n");
  58 +
  59 + result = result.replace(placeholder, value);
  60 + }
  61 + for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
  62 + String placeholder = "#{" + entry.getKey() + "}";
  63 + String value = entry.getValue() != null ? entry.getValue().toString() : "";
  64 + // 将数据库中的 \n 转换为 Excel 识别的换行符
  65 + value = value.replace("\\n", "\n");
  66 +
  67 + result = result.replace(placeholder, value);
  68 + }
  69 + return result;
  70 + }
  71 +
  72 +
  73 + /**
  74 + * 复制行并处理合并单元格
  75 + */
  76 + public static void copyRow(Workbook workbook, Sheet sheet,
  77 + int sourceRowIndex, int targetRowIndex) {
  78 + // 获取源行的所有合并区域
  79 + List<CellRangeAddress> mergedRegions = getMergedRegionsInRow(sheet, sourceRowIndex);
  80 + // 移动目标行及之后的行
  81 + if (targetRowIndex <= sheet.getLastRowNum()) {
  82 + sheet.shiftRows(targetRowIndex, sheet.getLastRowNum(), 1, true, false);
  83 + }
  84 + // 复制行内容
  85 + Row sourceRow = sheet.getRow(sourceRowIndex);
  86 + Row newRow = sheet.createRow(targetRowIndex);
  87 + newRow.setHeight(sourceRow.getHeight());
  88 + // 复制单元格
  89 + for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
  90 + Cell oldCell = sourceRow.getCell(i);
  91 + Cell newCell = newRow.createCell(i);
  92 + if (oldCell != null) {
  93 + copyCell(oldCell, newCell);
  94 + }
  95 + }
  96 + // 处理合并单元格
  97 + handleMergedRegions(sheet, mergedRegions, sourceRowIndex, targetRowIndex);
  98 + }
  99 +
  100 + /**
  101 + * 获取行中涉及的合并区域
  102 + */
  103 + public static List<CellRangeAddress> getMergedRegionsInRow(Sheet sheet, int rowIndex) {
  104 + List<CellRangeAddress> result = new ArrayList<>();
  105 + for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
  106 + CellRangeAddress mergedRegion = sheet.getMergedRegion(i);
  107 + if (mergedRegion.getFirstRow() == rowIndex) {
  108 + result.add(mergedRegion);
  109 + }
  110 + }
  111 + return result;
  112 + }
  113 +
  114 + /**
  115 + * 复制单元格内容和样式
  116 + */
  117 + private static void copyCell(Cell oldCell, Cell newCell) {
  118 + if (oldCell.getCellStyle() != null) {
  119 + newCell.setCellStyle(oldCell.getCellStyle());
  120 + }
  121 + switch (oldCell.getCellTypeEnum()) {
  122 + case STRING:
  123 + newCell.setCellValue(oldCell.getStringCellValue());
  124 + break;
  125 + case NUMERIC:
  126 + newCell.setCellValue(oldCell.getNumericCellValue());
  127 + break;
  128 + case BOOLEAN:
  129 + newCell.setCellValue(oldCell.getBooleanCellValue());
  130 + break;
  131 + case FORMULA:
  132 + newCell.setCellFormula(oldCell.getCellFormula());
  133 + break;
  134 + default:
  135 + newCell.setCellValue(oldCell.getStringCellValue());
  136 + break;
  137 + }
  138 + }
  139 +
  140 + /**
  141 + * 处理合并单元格的复制
  142 + */
  143 + public static void handleMergedRegions(Sheet sheet, List<CellRangeAddress> mergedRegions,
  144 + int sourceRowIndex, int targetRowIndex) {
  145 + for (CellRangeAddress oldRegion : mergedRegions) {
  146 + // 创建新的合并区域
  147 + CellRangeAddress newRegion = new CellRangeAddress(
  148 + targetRowIndex,
  149 + targetRowIndex + (oldRegion.getLastRow() - oldRegion.getFirstRow()),
  150 + oldRegion.getFirstColumn(),
  151 + oldRegion.getLastColumn()
  152 + );
  153 + sheet.addMergedRegion(newRegion);
  154 + // 设置合并区域的边框样式
  155 + setMergedRegionBorderStyle(sheet, newRegion);
  156 + }
  157 + }
  158 +
  159 + /**
  160 + * 设置合并单元格的边框样式
  161 + */
  162 + public static void setMergedRegionBorderStyle(Sheet sheet, CellRangeAddress region) {
  163 + Row firstRow = sheet.getRow(region.getFirstRow());
  164 + if (firstRow != null) {
  165 + Cell firstCell = firstRow.getCell(region.getFirstColumn());
  166 + if (firstCell != null && firstCell.getCellStyle() != null) {
  167 + CellStyle style = firstCell.getCellStyle();
  168 +
  169 + // 为合并区域的所有单元格设置样式
  170 + for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
  171 + Row row = sheet.getRow(i);
  172 + if (row == null) {
  173 + row = sheet.createRow(i);
  174 + }
  175 + for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
  176 + Cell cell = row.getCell(j);
  177 + if (cell == null) {
  178 + cell = row.createCell(j);
  179 + }
  180 + cell.setCellStyle(style);
  181 + }
  182 + }
  183 + }
  184 + }
  185 + }
  186 +
  187 + /**
  188 + * 设置单元格值
  189 + */
  190 + public static void setCellValue(Sheet sheet, int rowNum, int colNum, Object value) {
  191 + Row row = sheet.getRow(rowNum);
  192 + if (row == null) {
  193 + row = sheet.createRow(rowNum);
  194 + }
  195 + Cell cell = row.getCell(colNum);
  196 + if (cell == null) {
  197 + cell = row.createCell(colNum);
  198 + }
  199 + if (value == null) {
  200 + cell.setCellValue("");
  201 + } else if (value instanceof String) {
  202 + cell.setCellValue((String) value);
  203 + } else if (value instanceof Integer) {
  204 + cell.setCellValue((Integer) value);
  205 + } else if (value instanceof Double) {
  206 + cell.setCellValue((Double) value);
  207 + } else if (value instanceof BigDecimal) {
  208 + cell.setCellValue(((BigDecimal) value).doubleValue());
  209 + } else if (value instanceof LocalDate) {
  210 + cell.setCellValue(((LocalDate) value).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
  211 + }
  212 + }
  213 +}
  1 +package com.lframework.xingyun.sc.utils;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.apache.poi.ss.usermodel.*;
  5 +
  6 +import javax.servlet.http.HttpServletResponse;
  7 +import javax.swing.*;
  8 +import java.awt.*;
  9 +import java.io.IOException;
  10 +import java.net.URLEncoder;
  11 +
  12 +@Slf4j
  13 +public class ResponseUtil {
  14 +
  15 +
  16 + /**
  17 + * 设置HTTP响应头
  18 + */
  19 + public static void setResponseHead(HttpServletResponse response, String fileName) throws IOException {
  20 + String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
  21 +
  22 + response.setContentType("application/vnd.ms-excel");
  23 + response.setCharacterEncoding("UTF-8");
  24 + response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName);
  25 + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
  26 + }
  27 +
  28 +
  29 +}