From 95c01301f65379e7634e4619bf4c49186aa5be41 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子Li <15040126243@163.com>
Date: 星期五, 07 二月 2025 14:19:28 +0800
Subject: [PATCH] !644 同步修复一些问题 Merge pull request !644 from 疯狂的狮子Li/dev

---
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelDownHandler.java |  145 +++++++++++++++++++++++++++++-------------------
 1 files changed, 87 insertions(+), 58 deletions(-)

diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelDownHandler.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelDownHandler.java
index 52bfebc..32fee7a 100644
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelDownHandler.java
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/ExcelDownHandler.java
@@ -5,7 +5,9 @@
 import cn.hutool.core.util.EnumUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
-import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.metadata.FieldCache;
+import com.alibaba.excel.metadata.FieldWrapper;
+import com.alibaba.excel.util.ClassUtils;
 import com.alibaba.excel.write.handler.SheetWriteHandler;
 import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
 import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
@@ -18,6 +20,7 @@
 import org.dromara.common.core.service.DictService;
 import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.excel.annotation.ExcelDictFormat;
 import org.dromara.common.excel.annotation.ExcelEnumFormat;
 
@@ -52,6 +55,7 @@
      * 涓嬫媺鍙�夐」
      */
     private final List<DropDownOptions> dropDownOptions;
+    private final DictService dictService;
     /**
      * 褰撳墠鍗曢�夎繘搴�
      */
@@ -60,7 +64,6 @@
      * 褰撳墠鑱斿姩閫夋嫨杩涘害
      */
     private int currentLinkedOptionsSheetIndex;
-    private final DictService dictService;
 
     public ExcelDownHandler(List<DropDownOptions> options) {
         this.dropDownOptions = options;
@@ -83,42 +86,39 @@
         Sheet sheet = writeSheetHolder.getSheet();
         // 寮�濮嬭缃笅鎷夋 HSSFWorkbook
         DataValidationHelper helper = sheet.getDataValidationHelper();
-        Field[] fields = writeWorkbookHolder.getClazz().getDeclaredFields();
         Workbook workbook = writeWorkbookHolder.getWorkbook();
-        int length = fields.length;
-        for (int i = 0; i < length; i++) {
+        FieldCache fieldCache = ClassUtils.declaredFields(writeWorkbookHolder.getClazz(), writeWorkbookHolder);
+        for (Map.Entry<Integer, FieldWrapper> entry : fieldCache.getSortedFieldMap().entrySet()) {
+            Integer index = entry.getKey();
+            FieldWrapper wrapper = entry.getValue();
+            Field field = wrapper.getField();
             // 寰幆瀹炰綋涓殑姣忎釜灞炴��
             // 鍙�夌殑涓嬫媺鍊�
             List<String> options = new ArrayList<>();
-            if (fields[i].isAnnotationPresent(ExcelDictFormat.class)) {
+            if (field.isAnnotationPresent(ExcelDictFormat.class)) {
                 // 濡傛灉鎸囧畾浜咢ExcelDictFormat锛屽垯浣跨敤瀛楀吀鐨勯�昏緫
-                ExcelDictFormat format = fields[i].getDeclaredAnnotation(ExcelDictFormat.class);
+                ExcelDictFormat format = field.getDeclaredAnnotation(ExcelDictFormat.class);
                 String dictType = format.dictType();
                 String converterExp = format.readConverterExp();
-                if (StrUtil.isNotBlank(dictType)) {
+                if (StringUtils.isNotBlank(dictType)) {
                     // 濡傛灉浼犻�掍簡瀛楀吀鍚嶏紝鍒欎緷鎹瓧鍏稿缓绔嬩笅鎷�
                     Collection<String> values = Optional.ofNullable(dictService.getAllDictByDictType(dictType))
                         .orElseThrow(() -> new ServiceException(String.format("瀛楀吀 %s 涓嶅瓨鍦�", dictType)))
                         .values();
                     options = new ArrayList<>(values);
-                } else if (StrUtil.isNotBlank(converterExp)) {
+                } else if (StringUtils.isNotBlank(converterExp)) {
                     // 濡傛灉鎸囧畾浜嗙‘鍒囩殑鍊硷紝鍒欑洿鎺ヨВ鏋愮‘鍒囩殑鍊�
-                    options = StrUtil.split(converterExp, format.separator(), true, true);
+                    List<String> strList = StringUtils.splitList(converterExp, format.separator());
+                    options = StreamUtils.toList(strList, s -> StringUtils.split(s, "=")[1]);
                 }
-            } else if (fields[i].isAnnotationPresent(ExcelEnumFormat.class)) {
+            } else if (field.isAnnotationPresent(ExcelEnumFormat.class)) {
                 // 鍚﹀垯濡傛灉鎸囧畾浜咢ExcelEnumFormat锛屽垯浣跨敤鏋氫妇鐨勯�昏緫
-                ExcelEnumFormat format = fields[i].getDeclaredAnnotation(ExcelEnumFormat.class);
+                ExcelEnumFormat format = field.getDeclaredAnnotation(ExcelEnumFormat.class);
                 List<Object> values = EnumUtil.getFieldValues(format.enumClass(), format.textField());
                 options = StreamUtils.toList(values, String::valueOf);
             }
             if (ObjectUtil.isNotEmpty(options)) {
                 // 浠呭綋涓嬫媺鍙�夐」涓嶄负绌烘椂鎵ц
-                // 鑾峰彇鍒椾笅鏍囷紝榛樿涓哄綋鍓嶅惊鐜鏁�
-                int index = i;
-                if (fields[i].isAnnotationPresent(ExcelProperty.class)) {
-                    // 濡傛灉鎸囧畾浜嗗垪涓嬫爣锛屼互鎸囧畾鐨勪负涓�
-                    index = fields[i].getDeclaredAnnotation(ExcelProperty.class).index();
-                }
                 if (options.size() > 20) {
                     // 杩欓噷闄愬埗濡傛灉鍙�夐」澶т簬20锛屽垯浣跨敤棰濆琛ㄥ舰寮�
                     dropDownWithSheet(helper, workbook, sheet, index, options);
@@ -128,6 +128,9 @@
                 }
             }
         }
+        if (CollUtil.isEmpty(dropDownOptions)) {
+            return;
+        }
         dropDownOptions.forEach(everyOptions -> {
             // 濡傛灉浼犻�掍簡涓嬫媺妗嗛�夋嫨鍣ㄥ弬鏁�
             if (!everyOptions.getNextOptions().isEmpty()) {
@@ -136,8 +139,8 @@
             } else if (everyOptions.getOptions().size() > 10) {
                 // 褰撲竴绾ч�夐」鍙傛暟涓暟澶т簬10锛屼娇鐢ㄩ澶栬〃鐨勫舰寮�
                 dropDownWithSheet(helper, workbook, sheet, everyOptions.getIndex(), everyOptions.getOptions());
-            } else if (everyOptions.getOptions().size() != 0) {
-                // 褰撲竴绾ч�夐」涓暟涓嶄负绌猴紝浣跨敤榛樿褰㈠紡
+            } else {
+                // 鍚﹀垯浣跨敤榛樿褰㈠紡
                 dropDownWithSimple(helper, sheet, everyOptions.getIndex(), everyOptions.getOptions());
             }
         });
@@ -168,9 +171,23 @@
         Sheet linkedOptionsDataSheet = workbook.createSheet(WorkbookUtil.createSafeSheetName(linkedOptionsSheetName));
         // 灏嗕笅鎷夎〃闅愯棌
         workbook.setSheetHidden(workbook.getSheetIndex(linkedOptionsDataSheet), true);
-        // 瀹屽杽妯悜鐨勪竴绾ч�夐」鏁版嵁琛�
+        // 閫夐」鏁版嵁
         List<String> firstOptions = options.getOptions();
         Map<String, List<String>> secoundOptionsMap = options.getNextOptions();
+
+        // 閲囩敤鎸夎濉厖鏁版嵁鐨勬柟寮忥紝閬垮厤EasyExcel鍑虹幇鏁版嵁鏃犳硶鍐欏叆鐨勯棶棰�
+        // Attempting to write a row in the range that is already written to disk
+
+        // 浣跨敤ArrayList璁拌浇鏁版嵁锛岄槻姝贡搴�
+        List<String> columnNames = new ArrayList<>();
+        // 鍐欏叆绗竴琛岋紝鍗崇涓�绾х殑鏁版嵁
+        Row firstRow = linkedOptionsDataSheet.createRow(0);
+        for (int columnIndex = 0; columnIndex < firstOptions.size(); columnIndex++) {
+            String columnName = firstOptions.get(columnIndex);
+            firstRow.createCell(columnIndex)
+                .setCellValue(columnName);
+            columnNames.add(columnName);
+        }
 
         // 鍒涘缓鍚嶇О绠$悊鍣�
         Name name = workbook.createName();
@@ -187,28 +204,12 @@
         // 璁剧疆鏁版嵁鏍¢獙涓哄簭鍒楁ā寮忥紝寮曠敤鐨勬槸鍚嶇О绠$悊鍣ㄤ腑鐨勫埆鍚�
         this.markOptionsToSheet(helper, sheet, options.getIndex(), helper.createFormulaListConstraint(linkedOptionsSheetName));
 
-        for (int columIndex = 0; columIndex < firstOptions.size(); columIndex++) {
-            // 鍏堟彁鍙栦富琛ㄤ腑涓�绾т笅鎷夌殑鍒楀悕
+        // 鍒涘缓浜岀骇閫夐」鐨勫悕绉扮鐞嗗櫒
+        for (int columIndex = 0; columIndex < columnNames.size(); columIndex++) {
+            // 鍒楀悕
             String firstOptionsColumnName = getExcelColumnName(columIndex);
-            // 涓�娆″惊鐜槸姣忎竴涓竴绾ч�夐」
-            int finalI = columIndex;
-            // 鏈寰幆鐨勪竴绾ч�夐」鍊�
-            String thisFirstOptionsValue = firstOptions.get(columIndex);
-            // 鍒涘缓绗竴琛岀殑鏁版嵁
-            Optional.ofNullable(linkedOptionsDataSheet.getRow(0))
-                // 濡傛灉涓嶅瓨鍦ㄥ垯鍒涘缓绗竴琛�
-                .orElseGet(() -> linkedOptionsDataSheet.createRow(finalI))
-                // 绗竴琛屽綋鍓嶅垪
-                .createCell(columIndex)
-                // 璁剧疆鍊间负褰撳墠涓�绾ч�夐」鍊�
-                .setCellValue(thisFirstOptionsValue);
-
-            // 绗簩琛屽紑濮嬶紝璁剧疆绗簩绾у埆閫夐」鍙傛暟
-            List<String> secondOptions = secoundOptionsMap.get(thisFirstOptionsValue);
-            if (CollUtil.isEmpty(secondOptions)) {
-                // 蹇呴』淇濊瘉鑷冲皯鏈変竴涓叧鑱旈�夐」锛屽惁鍒欏皢瀵艰嚧Excel瑙f瀽閿欒
-                secondOptions = Collections.singletonList("鏆傛棤_0");
-            }
+            // 瀵瑰簲鐨勪竴绾у��
+            String thisFirstOptionsValue = columnNames.get(columIndex);
 
             // 浠ヨ涓�绾ч�夐」鍊煎垱寤哄瓙鍚嶇О绠$悊鍣�
             Name sonName = workbook.createName();
@@ -219,7 +220,9 @@
                 linkedOptionsSheetName,
                 firstOptionsColumnName,
                 firstOptionsColumnName,
-                secondOptions.size() + 1
+                // 浜岀骇閫夐」瀛樺湪鍒欒缃负(閫夐」涓暟+1)琛岋紝鍚﹀垯璁剧疆涓�2琛�
+                Math.max(Optional.ofNullable(secoundOptionsMap.get(thisFirstOptionsValue))
+                    .orElseGet(ArrayList::new).size(), 1) + 1
             );
             // 璁剧疆鍚嶇О绠$悊鍣ㄧ殑寮曠敤浣嶇疆
             sonName.setRefersToFormula(sonFunction);
@@ -232,25 +235,51 @@
                 // 浜岀骇鍙兘涓昏〃姣忎竴琛岀殑姣忎竴鍒楁坊鍔犱簩绾ф牎楠�
                 markLinkedOptionsToSheet(helper, sheet, i, options.getNextIndex(), helper.createFormulaListConstraint(secondOptionsFunction));
             }
+        }
 
-            for (int rowIndex = 0; rowIndex < secondOptions.size(); rowIndex++) {
-                // 浠庣浜岃寮�濮嬪~鍏呬簩绾ч�夐」
-                int finalRowIndex = rowIndex + 1;
-                int finalColumIndex = columIndex;
-
-                Row row = Optional.ofNullable(linkedOptionsDataSheet.getRow(finalRowIndex))
-                    // 娌℃湁鍒欏垱寤�
-                    .orElseGet(() -> linkedOptionsDataSheet.createRow(finalRowIndex));
-                Optional
-                    // 鍦ㄦ湰绾т竴绾ч�夐」鎵�鍦ㄧ殑鍒�
-                    .ofNullable(row.getCell(finalColumIndex))
-                    // 涓嶅瓨鍦ㄥ垯鍒涘缓
-                    .orElseGet(() -> row.createCell(finalColumIndex))
-                    // 璁剧疆浜岀骇閫夐」鍊�
-                    .setCellValue(secondOptions.get(rowIndex));
+        // 灏嗕簩绾ф暟鎹鐞嗕负鎸夎鍖哄垎
+        Map<Integer, List<String>> columnValueMap = new HashMap<>();
+        int currentRow = 1;
+        while (currentRow >= 0) {
+            boolean flag = false;
+            List<String> rowData = new ArrayList<>();
+            for (String columnName : columnNames) {
+                List<String> data = secoundOptionsMap.get(columnName);
+                if (CollUtil.isEmpty(data)) {
+                    // 娣诲姞绌哄瓧绗︿覆濉厖浣嶇疆
+                    rowData.add(" ");
+                    continue;
+                }
+                // 鍙栫涓�涓�
+                String str = data.get(0);
+                rowData.add(str);
+                // 閫氳繃绉婚櫎鐨勬柟寮忛伩鍏嶉噸澶�
+                data.remove(0);
+                // 璁剧疆鍙互缁х画
+                flag = true;
+            }
+            columnValueMap.put(currentRow, rowData);
+            // 鍙互缁х画锛屽垯澧炲姞琛屾暟锛屽惁鍒欑疆涓鸿礋鏁拌烦鍑哄惊鐜�
+            if (flag) {
+                currentRow++;
+            } else {
+                currentRow = -1;
             }
         }
 
+        // 濉厖绗簩绾ч�夐」鏁版嵁
+        columnValueMap.forEach((rowIndex, rowValues) -> {
+            Row row = linkedOptionsDataSheet.createRow(rowIndex);
+            for (int columnIndex = 0; columnIndex < rowValues.size(); columnIndex++) {
+                String rowValue = rowValues.get(columnIndex);
+                // 濉厖浣嶇疆鐨勯儴鍒嗕笉娓叉煋
+                if (StrUtil.isNotBlank(rowValue)) {
+                    row.createCell(columnIndex)
+                        .setCellValue(rowValue);
+                }
+            }
+        });
+
         currentLinkedOptionsSheetIndex++;
     }
 

--
Gitblit v1.9.3