瀏覽代碼

后台导出excel优化

24282 1 年之前
父節點
當前提交
992a7622f0

+ 0 - 4
sd-business/src/main/java/com/sd/business/entity/statement/vo/DocumentByOrderVo.java

@@ -1,6 +1,5 @@
 package com.sd.business.entity.statement.vo;
 
-import lombok.Builder;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -10,7 +9,6 @@ import java.util.List;
 
 @Getter
 @Setter
-@Builder
 public class DocumentByOrderVo {
 
     /**
@@ -55,7 +53,6 @@ public class DocumentByOrderVo {
 
     @Getter
     @Setter
-    @Builder
     public static class SkuSpec {
 
         /**
@@ -107,7 +104,6 @@ public class DocumentByOrderVo {
 
     @Getter
     @Setter
-    @Builder
     public static class BomSpec {
 
         /**

+ 38 - 56
sd-business/src/main/java/com/sd/business/service/statement/impl/DocumentByOrderExcelCellMergeStrategy.java

@@ -1,10 +1,7 @@
 package com.sd.business.service.statement.impl;
 
 import com.alibaba.excel.metadata.Head;
-import com.alibaba.excel.metadata.data.WriteCellData;
-import com.alibaba.excel.write.handler.CellWriteHandler;
-import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
-import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
 import com.sd.business.entity.statement.vo.DocumentByOrderVo;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Sheet;
@@ -14,96 +11,81 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-public class DocumentByOrderExcelCellMergeStrategy implements CellWriteHandler {
+public class DocumentByOrderExcelCellMergeStrategy extends AbstractMergeStrategy {
+
+    // 无需合并的行数
+    private final int mergeRowIndex = 2;
 
     // sku需要合并的列
     private final List<Integer> skuColIndex = Arrays.asList(3, 4, 5, 16, 17, 18, 19);
+    // sku无需合并的行
+    private final List<Integer> skuRowIndex = new ArrayList<>();
 
-    // 无需合并的行数
-    private final int mergeRowIndex = 3;
     // 订单无需合并的行
     private final List<Integer> orderRowIndex = new ArrayList<>();
     // 订单需要合并的列
     private final List<Integer> orderColIndex = Arrays.asList(0, 1, 2, 20, 21);
-    // sku无需合并的行
-    private final List<Integer> skuRowIndex = new ArrayList<>();
-    private Integer flag = 0;
 
     public DocumentByOrderExcelCellMergeStrategy(List<DocumentByOrderVo> documentByOrderVoList) {
         for (DocumentByOrderVo documentByOrderVo : documentByOrderVoList) {
-
             List<DocumentByOrderVo.SkuSpec> skuSpecList = documentByOrderVo.getSkuSpecList();
 
             // 赋值订单无需合并的行
             Integer size = skuSpecList.stream().map(item -> item.getBomSpecList().size()).reduce(0, Integer::sum);
-            if (orderRowIndex.size() == 0) {
-                orderRowIndex.add(size + mergeRowIndex);
-            } else {
-                orderRowIndex.add(size + orderRowIndex.get(orderRowIndex.size() - 1));
-            }
+            int orderRowIndexNumber = orderRowIndex.size() == 0 ? mergeRowIndex : orderRowIndex.get(orderRowIndex.size() - 1);
+            orderRowIndex.add(size + orderRowIndexNumber);
 
             // 赋值sku无需合并的行
             for (DocumentByOrderVo.SkuSpec skuSpec : skuSpecList) {
-                if (skuRowIndex.size() == 0) {
-                    skuRowIndex.add(skuSpec.getBomSpecList().size() + mergeRowIndex);
-                } else {
-                    skuRowIndex.add(skuSpec.getBomSpecList().size() + skuRowIndex.get(skuRowIndex.size() - 1));
-                }
+                int bomSpecListSize = skuSpec.getBomSpecList().size();
+                int skuRowIndexSize = skuRowIndex.size();
+                int skuRowIndexNumber = skuRowIndexSize == 0 ? mergeRowIndex : skuRowIndex.get(skuRowIndexSize - 1);
+                skuRowIndex.add(bomSpecListSize + skuRowIndexNumber);
             }
-
         }
     }
 
     @Override
-    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
-
-        // 当前行
-        int curRowIndex = cell.getRowIndex();
+    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
 
-        // 当前列
-        int curColIndex = cell.getColumnIndex();
+        // 当前行列
+        int curRowIndex = cell.getRowIndex(), curColIndex = cell.getColumnIndex();
 
-        // 前4行不合并
+        // 前3行不合并
         if (curRowIndex <= mergeRowIndex) {
             return;
         }
 
         // 合并订单列
-        if (orderColIndex.contains(curColIndex) && !orderRowIndex.contains(curRowIndex)) {
-            mergeWithPrevRow(writeSheetHolder, curRowIndex, curColIndex);
+        if (orderColIndex.contains(curColIndex) && orderRowIndex.contains(curRowIndex)) {
+            int i = orderRowIndex.indexOf(curRowIndex);
+            if (i == 0) {
+                mergeWithPrevRow(sheet, mergeRowIndex, curRowIndex, curColIndex);
+            } else {
+                Integer row = orderRowIndex.get(i - 1);
+                mergeWithPrevRow(sheet, row, curRowIndex, curColIndex);
+            }
         }
 
         // 合并sku列
-        else if (skuColIndex.contains(curColIndex) && !skuRowIndex.contains(curRowIndex)) {
-            mergeWithPrevRow(writeSheetHolder, curRowIndex, curColIndex);
+        else if (skuColIndex.contains(curColIndex) && skuRowIndex.contains(curRowIndex)) {
+            int i = skuRowIndex.indexOf(curRowIndex);
+            if (i == 0) {
+                mergeWithPrevRow(sheet, mergeRowIndex, curRowIndex, curColIndex);
+            } else {
+                Integer row = skuRowIndex.get(i - 1);
+                mergeWithPrevRow(sheet, row, curRowIndex, curColIndex);
+            }
         }
 
     }
 
     /**
-     * 当前单元格向上合并
+     * 合并单元格
      */
-    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, int curRowIndex, int curColIndex) {
-
-        Sheet sheet = writeSheetHolder.getSheet();
-        List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
-        for (int i = flag; i < mergeRegions.size(); i++) {
-            CellRangeAddress cellRangeAddr = mergeRegions.get(i);
-            // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
-            if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
-                sheet.removeMergedRegion(i);
-                cellRangeAddr.setLastRow(curRowIndex);
-                sheet.addMergedRegion(cellRangeAddr);
-
-                flag = i;
-                return;
-            }
-        }
-
-        // 若上一个单元格未被合并,则新增合并单元
-        CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
-        sheet.addMergedRegion(cellRangeAddress);
-
+    private void mergeWithPrevRow(Sheet sheet, int beginRow, int endRow, int col) {
+        CellRangeAddress cellRangeAddress = new CellRangeAddress(beginRow + 1, endRow, col, col);
+        sheet.addMergedRegionUnsafe(cellRangeAddress);
     }
 
-}
+}

+ 51 - 46
sd-business/src/main/java/com/sd/business/service/statement/impl/StatementOfAccountServiceImpl.java

@@ -431,16 +431,16 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
             return Collections.emptyList();
         }
 
-        List<DocumentByOrderVo> result = orderList.stream().map(item ->
-                DocumentByOrderVo.builder()
-                        .orderId(item.getId())
-                        .wlnCreateTime(ObjectUtil.defaultIfNull(item.getWlnCreateTime(), item.getCreateTime()))
-                        .code(item.getCode())
-                        .wlnCode(item.getWlnCode())
-                        .outerBoxPackingFee(item.getOuterBoxPackingFee())
-                        .total(item.getTotalAmount())
-                        .build()
-        ).collect(Collectors.toList());
+        List<DocumentByOrderVo> result = orderList.stream().map(item -> {
+            DocumentByOrderVo documentByOrderVo = new DocumentByOrderVo();
+            documentByOrderVo.setOrderId(item.getId());
+            documentByOrderVo.setWlnCreateTime(ObjectUtil.defaultIfNull(item.getWlnCreateTime(), item.getCreateTime()));
+            documentByOrderVo.setCode(item.getCode());
+            documentByOrderVo.setWlnCode(item.getWlnCode());
+            documentByOrderVo.setOuterBoxPackingFee(item.getOuterBoxPackingFee());
+            documentByOrderVo.setTotal(item.getTotalAmount());
+            return documentByOrderVo;
+        }).collect(Collectors.toList());
 
         List<Long> orderIdList = orderList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
         List<OrderSku> orderSkuList = orderSkuService.list(q -> q.in(OrderSku::getOrderId, orderIdList));
@@ -542,20 +542,21 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
         Map<Long, OrderInfo> map = orderService.mapKEntity(BaseIdPo::getId, q -> q.in(BaseIdPo::getId, orderIdList).eq(OrderInfo::getType, 2));
 
         List<DocumentByOrderVo.SkuSpec> skuSpecList = orderSkuList.stream()
-                .map(item -> DocumentByOrderVo.SkuSpec.builder()
-                        .orderId(item.getOrderId())
-                        .orderSkuId(item.getId())
-                        .skuSpecId(item.getSkuSpecId())
-                        // 判断是否是委外订单,如果是委外订单时将bom数量修改为0
-                        .quantity(item.getQuantity())
-                        .unitPrice(item.getUnitPrice()
-                                .add(item.getCustomProcessingFee())
-                                .add(item.getLssueFee())
-                                .add(item.getDeliveryMaterialsFee())
-                                .add(item.getPackingLabor())
-                                .add(item.getPackagingMaterialCost())
-                                .add(item.getManagementFee()))
-                        .build())
+                .map(item -> {
+                    DocumentByOrderVo.SkuSpec skuSpec = new DocumentByOrderVo.SkuSpec();
+                    skuSpec.setOrderId(item.getOrderId());
+                    skuSpec.setOrderSkuId(item.getId());
+                    skuSpec.setSkuSpecId(item.getSkuSpecId());
+                    skuSpec.setQuantity(item.getQuantity());
+                    skuSpec.setUnitPrice(item.getUnitPrice()
+                            .add(item.getCustomProcessingFee())
+                            .add(item.getLssueFee())
+                            .add(item.getDeliveryMaterialsFee())
+                            .add(item.getPackingLabor())
+                            .add(item.getPackagingMaterialCost())
+                            .add(item.getManagementFee()));
+                    return skuSpec;
+                })
                 .peek(item -> item.setSubtotal(item.getQuantity().multiply(item.getUnitPrice())))
                 .peek(item -> {
 
@@ -583,22 +584,24 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
         Map<Long, OrderInfo> orderMap = orderService.mapKEntity(BaseIdPo::getId, q -> q.in(BaseIdPo::getId, orderIdList).eq(OrderInfo::getType, 2));
 
         List<DocumentByOrderVo.BomSpec> bomSpecList = orderSkuList.stream()
-                .map(item -> DocumentByOrderVo.BomSpec.builder()
-                        .orderSkuId(item.getId())
-                        .bomSpecId(item.getBomSpecId())
-                        // 判断是否是委外订单,如果是委外订单时将bom数量修改为0
-                        .quantity(ObjectUtil.isNotEmpty(orderMap.get(item.getOrderId()))
-                                ? BigDecimal.ZERO : item.getQuantity())
-                        .unitPrice(item.getUnitPrice())
-                        .laserLogoSummary((Objects.equals(item.getCustomProcessingType(), "20")
-                                ? item.getCustomProcessingFee() : BigDecimal.ZERO))
-                        .laserMitochondrialSummary((Objects.equals(item.getCustomProcessingType(), "10")
-                                ? item.getCustomProcessingFee() : BigDecimal.ZERO))
-                        .lssueFeeSummary(item.getLssueFee())
-                        .deliveryMaterialsFeeSummary(item.getDeliveryMaterialsFee())
-                        .packingLaborSummary(item.getPackingLabor())
-                        .managementFeeSummary(item.getManagementFee())
-                        .build())
+                .map(item -> {
+                    DocumentByOrderVo.BomSpec bomSpec = new DocumentByOrderVo.BomSpec();
+                    bomSpec.setOrderSkuId(item.getId());
+                    bomSpec.setBomSpecId(item.getBomSpecId());
+                    // 判断是否是委外订单,如果是委外订单时将bom数量修改为0
+                    bomSpec.setQuantity(ObjectUtil.isNotEmpty(orderMap.get(item.getOrderId()))
+                            ? BigDecimal.ZERO : item.getQuantity());
+                    bomSpec.setUnitPrice(item.getUnitPrice());
+                    bomSpec.setLaserLogoSummary((Objects.equals(item.getCustomProcessingType(), "20")
+                            ? item.getCustomProcessingFee() : BigDecimal.ZERO));
+                    bomSpec.setLaserMitochondrialSummary((Objects.equals(item.getCustomProcessingType(), "10")
+                            ? item.getCustomProcessingFee() : BigDecimal.ZERO));
+                    bomSpec.setLssueFeeSummary(item.getLssueFee());
+                    bomSpec.setDeliveryMaterialsFeeSummary(item.getDeliveryMaterialsFee());
+                    bomSpec.setPackingLaborSummary(item.getPackingLabor());
+                    bomSpec.setManagementFeeSummary(item.getManagementFee());
+                    return bomSpec;
+                })
                 .collect(Collectors.toList());
 
         Map<Long, BigDecimal> map = bomSpecList.stream().collect(
@@ -607,12 +610,14 @@ public class StatementOfAccountServiceImpl extends ServiceImpl<StatementOfAccoun
         List<OrderSkuBom> orderSkuBomList = orderSkuBomService.list(q -> q.in(OrderSkuBom::getOrderId, orderIdList));
 
         List<DocumentByOrderVo.BomSpec> packBomSpecList = orderSkuBomList.stream()
-                .map(item -> DocumentByOrderVo.BomSpec.builder()
-                        .orderSkuId(item.getOrderSkuId())
-                        .bomSpecId(item.getBomSpecId())
-                        .quantity(item.getQuantity())
-                        .unitPrice(item.getUnitPrice())
-                        .build())
+                .map(item -> {
+                    DocumentByOrderVo.BomSpec bomSpec = new DocumentByOrderVo.BomSpec();
+                    bomSpec.setOrderSkuId(item.getOrderSkuId());
+                    bomSpec.setBomSpecId(item.getBomSpecId());
+                    bomSpec.setQuantity(item.getQuantity());
+                    bomSpec.setUnitPrice(item.getUnitPrice());
+                    return bomSpec;
+                })
                 .peek(item -> item.setQuantity(ObjectUtil.equals(map.get(item.getOrderSkuId()), BigDecimal.ZERO) ? item.getQuantity() : map.get(item.getOrderSkuId()).multiply(item.getQuantity())))
                 .collect(Collectors.toList());
 

+ 2 - 2
sd-business/src/main/resources/mapper/excel/ExcelGenerateLogMapper.xml

@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.sd.business.mapper.excel.ExcelGenerateLogMapper">
-    <select id="getPage" resultType="com.sd.business.entity.excel.vo.ExcelGenerateLogVo">
+
+<select id="getPage" resultType="com.sd.business.entity.excel.vo.ExcelGenerateLogVo">
         select egl.id,
                egl.type,
-               egl.param,
                egl.status,
                egl.obs_file_url,
                egl.excel_name,

+ 150 - 8
sd-starter/src/test/java/TestList.java

@@ -1,11 +1,21 @@
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.metadata.fill.FillConfig;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.ruoyi.common.exception.ServiceException;
 import com.sd.SdApplication;
 import com.sd.business.entity.order.po.OrderInfo;
 import com.sd.business.entity.production.dto.StockPreparationDto;
 import com.sd.business.entity.production.vo.UncompletedVo;
+import com.sd.business.entity.statement.bo.ExportDocumentByOrderBo;
 import com.sd.business.entity.statement.dto.GetDocumentDto;
 import com.sd.business.entity.statement.vo.DocumentByOrderVo;
 import com.sd.business.service.order.OrderService;
@@ -13,17 +23,23 @@ import com.sd.business.service.production.StockPreparationService;
 import com.sd.business.service.statement.StatementOfAccountMergeService;
 import com.sd.wln.service.WlnStatementOfAccount;
 import com.sd.wln.util.WlnUtil;
+import lombok.SneakyThrows;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.ClassPathResource;
 import org.springframework.test.context.junit4.SpringRunner;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.nio.charset.Charset;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @RunWith(SpringRunner.class)
@@ -139,11 +155,137 @@ public class TestList {
         System.out.println(JSON.toJSONString(collect));
     }
 
+    // public static void main(String[] args) {
+    //     String a = "{\n" +
+    //             "    \"idGroupConcat\": \"1699739286011727873,1702638389020454914,1700101673936044034,1700464061822562305,1702276001603575809,1700826449696530434,1701928713001660417,1701551225520091137,1701106726288019458,1701106725822451713,1701106725755342850,1701106725625319426,1701106725558210565,1701106725558210564,1699376899223990273\"\n" +
+    //             "}";
+    //     System.out.println(a);
+    // }
+
+
+    @SneakyThrows
     public static void main(String[] args) {
-        String a = "{\n" +
-                "    \"idGroupConcat\": \"1699739286011727873,1702638389020454914,1700101673936044034,1700464061822562305,1702276001603575809,1700826449696530434,1701928713001660417,1701551225520091137,1701106726288019458,1701106725822451713,1701106725755342850,1701106725625319426,1701106725558210565,1701106725558210564,1699376899223990273\"\n" +
-                "}";
-        System.out.println(a);
+
+        String str2 = FileUtil.readString("E:\\新建文本文档2.txt", Charset.defaultCharset());
+        List<DocumentByOrderVo> list = JSON.parseArray(str2).toJavaList(DocumentByOrderVo.class);
+
+        String str = FileUtil.readString("E:\\新建文本文档.txt", Charset.defaultCharset());
+
+        JSONObject json = JSON.parseObject(str);
+        List<ExportDocumentByOrderBo> exportDocumentByOrderBos = (List<ExportDocumentByOrderBo>) json.remove("exportDocumentByOrderBos");
+
+        String filePath = "tempExcel" + File.separator + IdWorker.getId() + ".xlsx";
+        File tempExcel = new File("tempExcel");
+        if (!tempExcel.exists()) {
+            tempExcel.mkdir();
+        }
+        FileOutputStream os = new FileOutputStream(filePath);
+
+        ClassPathResource classPathResource = new ClassPathResource("template" + File.separator + "orderDocument.xlsx");
+        InputStream is = classPathResource.getInputStream();
+        ExcelWriter excelWriter = EasyExcel.write(os).withTemplate(is).build();
+        try {
+            A strategy = new A(list);
+            WriteSheet writeSheet = EasyExcel.writerSheet().registerWriteHandler(strategy).build();
+            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
+
+            System.out.println("写入1");
+            excelWriter.fill(json, fillConfig, writeSheet);
+            System.out.println("写入2");
+            List<ExportDocumentByOrderBo> ssss = ListUtil.partition(exportDocumentByOrderBos, 100).get(0);
+            excelWriter.fill(exportDocumentByOrderBos, fillConfig, writeSheet);
+            System.out.println("写入完成");
+        } finally {
+            if (excelWriter != null) {
+                excelWriter.finish();
+                excelWriter.close();
+            }
+            os.close();
+            is.close();
+        }
+
+    }
+
+    private static class A extends AbstractMergeStrategy {
+
+        // 无需合并的行数
+        private final int mergeRowIndex = 2;
+
+        // sku需要合并的列
+        private final List<Integer> skuColIndex = Arrays.asList(3, 4, 5, 16, 17, 18, 19);
+        // sku无需合并的行
+        private final List<Integer> skuRowIndex = new ArrayList<>();
+
+        // 订单无需合并的行
+        private final List<Integer> orderRowIndex = new ArrayList<>();
+        // 订单需要合并的列
+        private final List<Integer> orderColIndex = Arrays.asList(0, 1, 2, 20, 21);
+
+        public A(List<DocumentByOrderVo> documentByOrderVoList) {
+
+            for (DocumentByOrderVo documentByOrderVo : documentByOrderVoList) {
+                List<DocumentByOrderVo.SkuSpec> skuSpecList = documentByOrderVo.getSkuSpecList();
+
+                // 赋值订单无需合并的行
+                Integer size = skuSpecList.stream().map(item -> item.getBomSpecList().size()).reduce(0, Integer::sum);
+                int orderRowIndexNumber = orderRowIndex.size() == 0 ? mergeRowIndex : orderRowIndex.get(orderRowIndex.size() - 1);
+                orderRowIndex.add(size + orderRowIndexNumber);
+
+                // 赋值sku无需合并的行
+                for (DocumentByOrderVo.SkuSpec skuSpec : skuSpecList) {
+                    int bomSpecListSize = skuSpec.getBomSpecList().size();
+                    int skuRowIndexSize = skuRowIndex.size();
+                    int skuRowIndexNumber = skuRowIndexSize == 0 ? mergeRowIndex : skuRowIndex.get(skuRowIndexSize - 1);
+                    skuRowIndex.add(bomSpecListSize + skuRowIndexNumber);
+                }
+            }
+
+        }
+
+        @Override
+        protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
+
+            // 当前行列
+            int curRowIndex = cell.getRowIndex(), curColIndex = cell.getColumnIndex();
+
+            // 前3行不合并
+            if (curRowIndex <= mergeRowIndex) {
+                return;
+            }
+
+            // 合并订单列
+            if (orderColIndex.contains(curColIndex) && orderRowIndex.contains(curRowIndex)) {
+                int i = orderRowIndex.indexOf(curRowIndex);
+                if (i == 0) {
+                    mergeWithPrevRow(sheet, mergeRowIndex, curRowIndex, curColIndex);
+                } else {
+                    Integer row = orderRowIndex.get(i - 1);
+                    mergeWithPrevRow(sheet, row, curRowIndex, curColIndex);
+                }
+            }
+
+            // 合并sku列
+            else if (skuColIndex.contains(curColIndex) && skuRowIndex.contains(curRowIndex)) {
+                int i = skuRowIndex.indexOf(curRowIndex);
+                if (i == 0) {
+                    mergeWithPrevRow(sheet, mergeRowIndex, curRowIndex, curColIndex);
+                } else {
+                    Integer row = skuRowIndex.get(i - 1);
+                    mergeWithPrevRow(sheet, row, curRowIndex, curColIndex);
+                }
+            }
+
+        }
+
+        /**
+         * 合并单元格
+         */
+        private void mergeWithPrevRow(Sheet sheet, int beginRow, int endRow, int col) {
+            CellRangeAddress cellRangeAddress = new CellRangeAddress(beginRow + 1, endRow, col, col);
+            sheet.addMergedRegionUnsafe(cellRangeAddress);
+        }
+
     }
 
+
 }