Просмотр исходного кода

新增棒三以及上若工作台装运打印信息导出

lingpeng.li 1 месяц назад
Родитель
Сommit
639576700c

+ 265 - 1
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/rollClubThree/controller/RollClubThreeDetailsController.java

@@ -1,29 +1,54 @@
 package org.jeecg.modules.billet.rollClubThree.controller;
 
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.aspect.annotation.AutoLog;
 import org.jeecg.common.system.base.controller.JeecgController;
 import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletRulerConfig;
+import org.jeecg.modules.actualControl.billetActual.billetActual.mapper.BilletRulerConfigMapper;
 import org.jeecg.modules.billet.rollClubThree.entity.RollClubThreeDetails;
 import org.jeecg.modules.billet.rollClubThree.service.IRollClubThreeDetailsService;
+import org.jeecg.modules.billet.rollClubTwo.entity.RollClubTwoDetails;
+import org.jeecg.modules.billet.rollDeputyCross.entity.RollDeputyCrossDetails;
+import org.jeecg.modules.billet.rollOutShipp.entity.RollOutShippDetails;
 import org.jeecg.modules.billet.storageBill.dto.RollDetailQueryDTO;
+import org.jeecg.modules.billet.storageBill.entity.StorageBillPrint;
+import org.jeecg.modules.billet.storageBill.service.IStorageBillPrintService;
 import org.jeecg.modules.billet.storageBill.vo.RollChargeDetailsPageVO;
 import org.jeecg.modules.billet.storageBill.vo.RollChargeDetailsVO;
 import org.jeecg.modules.billet.storageBill.vo.RollOnDutyDataVo;
+import org.jeecg.modules.billet.storageBill.vo.StorageCenterExportRow;
+import org.jeecg.modules.carUnit.entity.SysDict;
+import org.jeecg.modules.carUnit.entity.SysDictItem;
+import org.jeecg.modules.carUnit.mapper.CarUnitMapper;
+import org.jeecg.modules.carUnit.service.ISysDictItemService;
+import org.jeecg.modules.carUnit.service.ISysDictService;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.servlet.ModelAndView;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.Arrays;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
 
 /**
  * @Description: 棒三明细信息
@@ -38,6 +63,12 @@ import java.util.Arrays;
 public class RollClubThreeDetailsController extends JeecgController<RollClubThreeDetails, IRollClubThreeDetailsService> {
     @Autowired
     private IRollClubThreeDetailsService rollClubThreeDetailsService;
+    @Autowired
+    private IStorageBillPrintService storageBillPrintService;
+    @Autowired
+    private ISysDictService sysDictService;
+    @Autowired
+    private BilletRulerConfigMapper billetRulerConfigMapper;
 
     /**
      * 分页列表查询
@@ -191,4 +222,237 @@ public class RollClubThreeDetailsController extends JeecgController<RollClubThre
     }
 
 
+    /**
+     * 导出excel
+     *
+     * @param response
+     * @param storageBillPrint
+     */
+    @RequestMapping(value = "/exportThreeXls")
+    public void exportThreeXls(HttpServletResponse response, StorageBillPrint storageBillPrint) {
+        try {
+            QueryWrapper<StorageBillPrint> queryWrapper = new QueryWrapper<>();
+
+            // 手动设置必要条件,避免 QueryGenerator 自动生成不必要的条件
+            if (oConvertUtils.isNotEmpty(storageBillPrint.getCcmNo())) {
+                queryWrapper.eq("ccm_no", storageBillPrint.getCcmNo());
+            }
+            if (oConvertUtils.isNotEmpty(storageBillPrint.getLicensePlate())) {
+                queryWrapper.eq("license_plate", storageBillPrint.getLicensePlate());
+            }
+            if (oConvertUtils.isNotEmpty(storageBillPrint.getDestination())) {
+                queryWrapper.eq("destination", storageBillPrint.getDestination());
+            }
+            // 开始时间
+            Date startTime = storageBillPrint.getArrivalTime();
+            // 结束时间
+            Date endTime = storageBillPrint.getCreateTime();
+
+            log.info("查询时间范围:startTime={}, endTime={}", startTime, endTime);
+
+            // 修改时间范围查询条件为 >= startTime 且 <= endTime
+            queryWrapper.ge("arrival_time", startTime)  // 大于等于开始时间
+                    .le("arrival_time", endTime);   // 小于等于结束时间
+            // Step.2 获取导出数据
+            // 打印完整的查询条件
+            log.info("最终查询条件:{}", queryWrapper.getSqlSegment());
+            List<StorageBillPrint> exportList = storageBillPrintService.list(queryWrapper);
+
+            // 用于存储拆分后的新数据
+            List<StorageBillPrint> splitList = new ArrayList<>();
+            // 遍历原始数据,拆分heatNo字段
+            for (StorageBillPrint item : exportList) {
+                String heatNoJson = item.getHeatNo();
+                if (heatNoJson != null && !heatNoJson.isEmpty()) {
+                    try {
+                        // 使用FastJSON解析JSON字符串
+                        JSONObject heatNoObj = JSON.parseObject(heatNoJson);
+
+                        // 遍历JSON中的每个键值对
+                        for (Map.Entry<String, Object> entry : heatNoObj.entrySet()) {
+                            String heatNoKey = entry.getKey();
+                            int quantity = Integer.parseInt(entry.getValue().toString());
+
+                            // 复制原始对象
+                            StorageBillPrint newItem = new StorageBillPrint();
+                            BeanUtils.copyProperties(item, newItem);
+                            // 设置新的heatNo和支数
+                            newItem.setHeatNo(heatNoKey);
+                            newItem.setAmountTotal(quantity);
+
+                            // 添加到新列表
+                            splitList.add(newItem);
+                        }
+                    } catch (Exception e) {
+                        // 处理JSON解析异常
+                        log.error("解析heatNo JSON失败: {}", heatNoJson, e);
+                        // 如果解析失败,保留原始数据
+                        splitList.add(item);
+                    }
+                } else {
+                    // 如果heatNo为空,保留原始数据
+                    splitList.add(item);
+                }
+            }
+
+            // 第二步:根据size字段拆分
+            List<StorageBillPrint> finalList = new ArrayList<>();
+            for (StorageBillPrint item : splitList) {
+                String sizeStr = item.getSize();
+                if (sizeStr != null && sizeStr.contains(",")) {
+                    // 按逗号分割定尺字符串
+                    String[] sizes = sizeStr.split(",");
+                    for (int i = 0; i < sizes.length; i++) {
+                        // 复制对象
+                        StorageBillPrint newItem = new StorageBillPrint();
+                        BeanUtils.copyProperties(item, newItem);
+                        newItem.setAmountTotal(0);
+                        newItem.setWeight(BigDecimal.ZERO);
+                        // 根据装运单ID、炉号、铸机号、定尺、目的地查询对应的明细信息
+
+
+                         if ("棒三".equals(item.getDestination())) {
+                            LambdaQueryWrapper<RollClubThreeDetails> queryWrapper3 = new LambdaQueryWrapper<>();
+                            queryWrapper3.eq(RollClubThreeDetails::getStorageBillId, item.getId())
+                                    .eq(RollClubThreeDetails::getCcmNo, item.getCcmNo())
+                                    .eq(RollClubThreeDetails::getSize, sizes[i])
+                                    .eq(RollClubThreeDetails::getHeatNo, item.getHeatNo());
+                            List<RollClubThreeDetails> rollClubThreeDetailsList = rollClubThreeDetailsService.list(queryWrapper3);
+                            if (rollClubThreeDetailsList.size() > 0) {
+                                newItem.setAmountTotal(rollClubThreeDetailsList.size());
+                                newItem.setWeight(BigDecimal.valueOf(rollClubThreeDetailsList.stream().mapToDouble(RollClubThreeDetails::getBlankOutput).sum()));
+                            }
+                        }
+                        // 设置单个定尺
+                        newItem.setSize(sizes[i]);
+                        finalList.add(newItem);
+                    }
+                } else {
+                    // 如果定尺没有逗号分隔,直接添加
+                    finalList.add(item);
+                }
+            }
+            List<StorageCenterExportRow> exportRows = new ArrayList<>();
+            finalList.forEach(x -> {
+                StorageCenterExportRow exportRow = new StorageCenterExportRow();
+                exportRow.setAmount(x.getAmountTotal());
+                exportRow.setCcmNo(Integer.valueOf(x.getCcmNo()));
+                exportRow.setEndPoint(x.getDestination());
+                exportRow.setFactoryDate(DateUtils.date2Str(x.getArrivalTime(), DateUtils.datetimeFormat.get()));
+                exportRow.setHeatNo(x.getHeatNo());
+                exportRow.setLicensePlate(x.getLicensePlate());
+                BigDecimal result = safeToBigDecimal(x.getSize()).divide(BigDecimal.valueOf(1000));
+                if (result != null) {
+                    exportRow.setSize("170*170*" + result.toPlainString());
+                }
+                exportRow.setSpec(x.getName());
+                exportRow.setTransportUnit(getTransportUnitNameByCarNumber(x.getLicensePlate()));
+                exportRow.setTotalWeight(x.getWeight());
+
+                String brandNum = Optional.ofNullable(x.getBrandNum())
+                        .map(bn -> sysDictService.queryDictTextByKey("billet_spec", bn))
+                        .orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
+                exportRow.setBrand(brandNum);
+
+                // 查询定尺规则
+                LambdaQueryWrapper<BilletRulerConfig> queryWrapperbilletRulerConfig = new LambdaQueryWrapper<BilletRulerConfig>().eq(BilletRulerConfig::getLength, Integer.valueOf(safeToInteger(x.getSize())));
+                BilletRulerConfig billetRulerConfig = billetRulerConfigMapper.selectOne(queryWrapperbilletRulerConfig);
+                Double weight = 0.0;
+                if (oConvertUtils.isEmpty(billetRulerConfig)) {
+                    exportRow.setWeightPerPiece(new BigDecimal(0.0));
+                } else {
+                    weight = billetRulerConfig.getWeight();
+                    exportRow.setWeightPerPiece(BigDecimal.valueOf(weight));
+                    Integer amount = x.getAmountTotal();
+                    BigDecimal totalWeight = (amount == null) ? BigDecimal.ZERO :
+                            BigDecimal.valueOf(weight).multiply(BigDecimal.valueOf(amount));
+                    exportRow.setTotalWeight(totalWeight);
+                }
+
+                String btype = Optional.ofNullable(x.getBtype()).orElse("");
+                exportRow.setBtype("0".equals(btype) ? "热坯" : "凉坯");
+                exportRows.add(exportRow);
+            });
+
+            // 设置响应
+            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+            response.setCharacterEncoding("utf-8");
+            String fileName = URLEncoder.encode("棒三工作台装运打印信息", String.valueOf(StandardCharsets.UTF_8)).replaceAll("\\+", "%20");
+            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
+
+            // 导出
+            EasyExcel.write(response.getOutputStream(), StorageCenterExportRow.class)
+                    .sheet("装运打印信息")
+                    .doWrite(exportRows);
+        } catch (Exception e) {
+            log.error("导出Excel失败:", e);
+        }
+
+    }
+
+    public static String getTransportUnitNameByCarNumber(String carNumber) {
+        if (StringUtils.isBlank(carNumber)) return "";
+
+        CarUnitMapper carUnitMapper = SpringContextUtils.getBean(CarUnitMapper.class);
+        ISysDictItemService sysDictItemService = SpringContextUtils.getBean(ISysDictItemService.class);
+        // 查询 unitCode
+        String unitCode = carUnitMapper.getUnitByCarNumber(carNumber);
+        if (StringUtils.isBlank(unitCode)) return "其他";
+
+        // 查询 car_unit_type 下所有字典项(item_text + item_value)
+        String dictId = getDictId("car_unit_type");
+        if (StringUtils.isBlank(dictId)) return "其他";
+
+        List<SysDictItem> sysDictItems = sysDictItemService.list(
+                new LambdaQueryWrapper<SysDictItem>()
+                        .eq(SysDictItem::getDictId, dictId)
+        );
+
+        // 遍历匹配 unitCode 是否在 item_value 中
+        for (SysDictItem item : sysDictItems) {
+            if (unitCode.equals(item.getItemValue())) {
+                return item.getItemText(); // 匹配成功返回单位名称(如“辉腾”)
+            }
+        }
+
+        return "其他";
+    }
+
+    private static String getDictId(String dictCode) {
+        ISysDictService sysDictService = SpringContextUtils.getBean(ISysDictService.class);
+        SysDict dict = sysDictService.getOne(
+                new LambdaQueryWrapper<SysDict>()
+                        .eq(SysDict::getDictCode, dictCode)
+                        .last("LIMIT 1")
+        );
+        return dict != null ? dict.getId() : null;
+    }
+
+    public static BigDecimal safeToBigDecimal(String str) {
+        if (StringUtils.isBlank(str)) {
+            return BigDecimal.ZERO;
+        }
+        try {
+            return new BigDecimal(str);
+        } catch (NumberFormatException e) {
+            return BigDecimal.ZERO;
+        }
+    }
+
+    public static Integer safeToInteger(String str) {
+        if (StringUtils.isBlank(str)) {
+            return 0;
+        }
+        try {
+            return Integer.parseInt(str);
+        } catch (NumberFormatException e) {
+            try {
+                // 尝试转成小数再取整
+                return new BigDecimal(str).intValue();
+            } catch (Exception ex) {
+                return 0;
+            }
+        }
+    }
+
 }

+ 264 - 2
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/rollOutShipp/controller/RollOutShippDetailsController.java

@@ -1,31 +1,54 @@
 package org.jeecg.modules.billet.rollOutShipp.controller;
 
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.aspect.annotation.AutoLog;
 import org.jeecg.common.system.base.controller.JeecgController;
 import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.actualControl.billetActual.billetActual.entity.BilletRulerConfig;
+import org.jeecg.modules.actualControl.billetActual.billetActual.mapper.BilletRulerConfigMapper;
+import org.jeecg.modules.billet.rollClubThree.entity.RollClubThreeDetails;
 import org.jeecg.modules.billet.rollOutShipp.entity.RollOutShippDetails;
 import org.jeecg.modules.billet.rollOutShipp.service.IRollOutShippDetailsService;
 import org.jeecg.modules.billet.storageBill.dto.RollDetailQueryDTO;
+import org.jeecg.modules.billet.storageBill.entity.StorageBillPrint;
+import org.jeecg.modules.billet.storageBill.service.IStorageBillPrintService;
 import org.jeecg.modules.billet.storageBill.vo.RollChargeDetailsPageVO;
 import org.jeecg.modules.billet.storageBill.vo.RollChargeDetailsVO;
 import org.jeecg.modules.billet.storageBill.vo.RollOnDutyDataVo;
+import org.jeecg.modules.billet.storageBill.vo.StorageCenterExportRow;
+import org.jeecg.modules.carUnit.entity.SysDict;
+import org.jeecg.modules.carUnit.entity.SysDictItem;
+import org.jeecg.modules.carUnit.mapper.CarUnitMapper;
+import org.jeecg.modules.carUnit.service.ISysDictItemService;
+import org.jeecg.modules.carUnit.service.ISysDictService;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.servlet.ModelAndView;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.Arrays;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
 
- /**
+/**
  * @Description: 上若明细信息
  * @Author: jeecg-boot
  * @Date:   2024-11-20
@@ -38,6 +61,12 @@ import java.util.Arrays;
 public class RollOutShippDetailsController extends JeecgController<RollOutShippDetails, IRollOutShippDetailsService> {
 	@Autowired
 	private IRollOutShippDetailsService rollOutShippDetailsService;
+	@Autowired
+	private IStorageBillPrintService storageBillPrintService;
+	@Autowired
+	private ISysDictService sysDictService;
+	@Autowired
+	private BilletRulerConfigMapper billetRulerConfigMapper;
 	
 	/**
 	 * 分页列表查询
@@ -188,4 +217,237 @@ public class RollOutShippDetailsController extends JeecgController<RollOutShippD
 		 RollChargeDetailsPageVO rollChargeDetailsVO = rollOutShippDetailsService.rollOutShippWorkbenchesQuery(queryDTO);
 		 return Result.OK(rollChargeDetailsVO);
 	 }
+
+	/**
+	 * 导出excel
+	 *
+	 * @param response
+	 * @param storageBillPrint
+	 */
+	@RequestMapping(value = "/exportOutXls")
+	public void exportOutXls(HttpServletResponse response, StorageBillPrint storageBillPrint) {
+		try {
+			QueryWrapper<StorageBillPrint> queryWrapper = new QueryWrapper<>();
+
+			// 手动设置必要条件,避免 QueryGenerator 自动生成不必要的条件
+			if (oConvertUtils.isNotEmpty(storageBillPrint.getCcmNo())) {
+				queryWrapper.eq("ccm_no", storageBillPrint.getCcmNo());
+			}
+			if (oConvertUtils.isNotEmpty(storageBillPrint.getLicensePlate())) {
+				queryWrapper.eq("license_plate", storageBillPrint.getLicensePlate());
+			}
+			if (oConvertUtils.isNotEmpty(storageBillPrint.getDestination())) {
+				queryWrapper.eq("destination", storageBillPrint.getDestination());
+			}
+			// 开始时间
+			Date startTime = storageBillPrint.getArrivalTime();
+			// 结束时间
+			Date endTime = storageBillPrint.getCreateTime();
+
+			log.info("查询时间范围:startTime={}, endTime={}", startTime, endTime);
+
+			// 修改时间范围查询条件为 >= startTime 且 <= endTime
+			queryWrapper.ge("arrival_time", startTime)  // 大于等于开始时间
+					.le("arrival_time", endTime);   // 小于等于结束时间
+			// Step.2 获取导出数据
+			// 打印完整的查询条件
+			log.info("最终查询条件:{}", queryWrapper.getSqlSegment());
+			List<StorageBillPrint> exportList = storageBillPrintService.list(queryWrapper);
+
+			// 用于存储拆分后的新数据
+			List<StorageBillPrint> splitList = new ArrayList<>();
+			// 遍历原始数据,拆分heatNo字段
+			for (StorageBillPrint item : exportList) {
+				String heatNoJson = item.getHeatNo();
+				if (heatNoJson != null && !heatNoJson.isEmpty()) {
+					try {
+						// 使用FastJSON解析JSON字符串
+						JSONObject heatNoObj = JSON.parseObject(heatNoJson);
+
+						// 遍历JSON中的每个键值对
+						for (Map.Entry<String, Object> entry : heatNoObj.entrySet()) {
+							String heatNoKey = entry.getKey();
+							int quantity = Integer.parseInt(entry.getValue().toString());
+
+							// 复制原始对象
+							StorageBillPrint newItem = new StorageBillPrint();
+							BeanUtils.copyProperties(item, newItem);
+							// 设置新的heatNo和支数
+							newItem.setHeatNo(heatNoKey);
+							newItem.setAmountTotal(quantity);
+
+							// 添加到新列表
+							splitList.add(newItem);
+						}
+					} catch (Exception e) {
+						// 处理JSON解析异常
+						log.error("解析heatNo JSON失败: {}", heatNoJson, e);
+						// 如果解析失败,保留原始数据
+						splitList.add(item);
+					}
+				} else {
+					// 如果heatNo为空,保留原始数据
+					splitList.add(item);
+				}
+			}
+
+			// 第二步:根据size字段拆分
+			List<StorageBillPrint> finalList = new ArrayList<>();
+			for (StorageBillPrint item : splitList) {
+				String sizeStr = item.getSize();
+				if (sizeStr != null && sizeStr.contains(",")) {
+					// 按逗号分割定尺字符串
+					String[] sizes = sizeStr.split(",");
+					for (int i = 0; i < sizes.length; i++) {
+						// 复制对象
+						StorageBillPrint newItem = new StorageBillPrint();
+						BeanUtils.copyProperties(item, newItem);
+						newItem.setAmountTotal(0);
+						newItem.setWeight(BigDecimal.ZERO);
+						// 根据装运单ID、炉号、铸机号、定尺、目的地查询对应的明细信息
+
+
+						if ("上若".equals(item.getDestination())){
+							LambdaQueryWrapper<RollOutShippDetails> queryWrapper4 = new LambdaQueryWrapper<>();
+							queryWrapper4.eq(RollOutShippDetails::getStorageBillId, item.getId())
+									.eq(RollOutShippDetails::getCcmNo, item.getCcmNo())
+									.eq(RollOutShippDetails::getSize, sizes[i])
+									.eq(RollOutShippDetails::getHeatNo, item.getHeatNo());
+							List<RollOutShippDetails> rollOutShippDetailsList = rollOutShippDetailsService.list(queryWrapper4);
+							if (rollOutShippDetailsList.size() > 0) {
+								newItem.setAmountTotal(rollOutShippDetailsList.size());
+								newItem.setWeight(BigDecimal.valueOf(rollOutShippDetailsList.stream().mapToDouble(RollOutShippDetails::getBlankOutput).sum()));
+							}
+						}
+						// 设置单个定尺
+						newItem.setSize(sizes[i]);
+						finalList.add(newItem);
+					}
+				} else {
+					// 如果定尺没有逗号分隔,直接添加
+					finalList.add(item);
+				}
+			}
+			List<StorageCenterExportRow> exportRows = new ArrayList<>();
+			finalList.forEach(x -> {
+				StorageCenterExportRow exportRow = new StorageCenterExportRow();
+				exportRow.setAmount(x.getAmountTotal());
+				exportRow.setCcmNo(Integer.valueOf(x.getCcmNo()));
+				exportRow.setEndPoint(x.getDestination());
+				exportRow.setFactoryDate(DateUtils.date2Str(x.getArrivalTime(), DateUtils.datetimeFormat.get()));
+				exportRow.setHeatNo(x.getHeatNo());
+				exportRow.setLicensePlate(x.getLicensePlate());
+				BigDecimal result = safeToBigDecimal(x.getSize()).divide(BigDecimal.valueOf(1000));
+				if (result != null) {
+					exportRow.setSize("170*170*" + result.toPlainString());
+				}
+				exportRow.setSpec(x.getName());
+				exportRow.setTransportUnit(getTransportUnitNameByCarNumber(x.getLicensePlate()));
+				exportRow.setTotalWeight(x.getWeight());
+
+				String brandNum = Optional.ofNullable(x.getBrandNum())
+						.map(bn -> sysDictService.queryDictTextByKey("billet_spec", bn))
+						.orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
+				exportRow.setBrand(brandNum);
+
+				// 查询定尺规则
+				LambdaQueryWrapper<BilletRulerConfig> queryWrapperbilletRulerConfig = new LambdaQueryWrapper<BilletRulerConfig>().eq(BilletRulerConfig::getLength, Integer.valueOf(safeToInteger(x.getSize())));
+				BilletRulerConfig billetRulerConfig = billetRulerConfigMapper.selectOne(queryWrapperbilletRulerConfig);
+				Double weight = 0.0;
+				if (oConvertUtils.isEmpty(billetRulerConfig)) {
+					exportRow.setWeightPerPiece(new BigDecimal(0.0));
+				} else {
+					weight = billetRulerConfig.getWeight();
+					exportRow.setWeightPerPiece(BigDecimal.valueOf(weight));
+					Integer amount = x.getAmountTotal();
+					BigDecimal totalWeight = (amount == null) ? BigDecimal.ZERO :
+							BigDecimal.valueOf(weight).multiply(BigDecimal.valueOf(amount));
+					exportRow.setTotalWeight(totalWeight);
+				}
+
+				String btype = Optional.ofNullable(x.getBtype()).orElse("");
+				exportRow.setBtype("0".equals(btype) ? "热坯" : "凉坯");
+				exportRows.add(exportRow);
+			});
+
+			// 设置响应
+			response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+			response.setCharacterEncoding("utf-8");
+			String fileName = URLEncoder.encode("上若工作台装运打印信息", String.valueOf(StandardCharsets.UTF_8)).replaceAll("\\+", "%20");
+			response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
+
+			// 导出
+			EasyExcel.write(response.getOutputStream(), StorageCenterExportRow.class)
+					.sheet("装运打印信息")
+					.doWrite(exportRows);
+		} catch (Exception e) {
+			log.error("导出Excel失败:", e);
+		}
+
+	}
+
+	public static String getTransportUnitNameByCarNumber(String carNumber) {
+		if (StringUtils.isBlank(carNumber)) return "";
+
+		CarUnitMapper carUnitMapper = SpringContextUtils.getBean(CarUnitMapper.class);
+		ISysDictItemService sysDictItemService = SpringContextUtils.getBean(ISysDictItemService.class);
+		// 查询 unitCode
+		String unitCode = carUnitMapper.getUnitByCarNumber(carNumber);
+		if (StringUtils.isBlank(unitCode)) return "其他";
+
+		// 查询 car_unit_type 下所有字典项(item_text + item_value)
+		String dictId = getDictId("car_unit_type");
+		if (StringUtils.isBlank(dictId)) return "其他";
+
+		List<SysDictItem> sysDictItems = sysDictItemService.list(
+				new LambdaQueryWrapper<SysDictItem>()
+						.eq(SysDictItem::getDictId, dictId)
+		);
+
+		// 遍历匹配 unitCode 是否在 item_value 中
+		for (SysDictItem item : sysDictItems) {
+			if (unitCode.equals(item.getItemValue())) {
+				return item.getItemText(); // 匹配成功返回单位名称(如“辉腾”)
+			}
+		}
+
+		return "其他";
+	}
+
+	private static String getDictId(String dictCode) {
+		ISysDictService sysDictService = SpringContextUtils.getBean(ISysDictService.class);
+		SysDict dict = sysDictService.getOne(
+				new LambdaQueryWrapper<SysDict>()
+						.eq(SysDict::getDictCode, dictCode)
+						.last("LIMIT 1")
+		);
+		return dict != null ? dict.getId() : null;
+	}
+
+	public static BigDecimal safeToBigDecimal(String str) {
+		if (StringUtils.isBlank(str)) {
+			return BigDecimal.ZERO;
+		}
+		try {
+			return new BigDecimal(str);
+		} catch (NumberFormatException e) {
+			return BigDecimal.ZERO;
+		}
+	}
+
+	public static Integer safeToInteger(String str) {
+		if (StringUtils.isBlank(str)) {
+			return 0;
+		}
+		try {
+			return Integer.parseInt(str);
+		} catch (NumberFormatException e) {
+			try {
+				// 尝试转成小数再取整
+				return new BigDecimal(str).intValue();
+			} catch (Exception ex) {
+				return 0;
+			}
+		}
+	}
 }