From b471ab5edf72439cf6e37c4635c07e7a5fc08a4f Mon Sep 17 00:00:00 2001
From: xiaoyi <908147524@qq.com>
Date: 星期二, 03 十一月 2026 19:10:14 +0800
Subject: [PATCH] fix(excel): Excel 导入报错统一转为可读中文提示,不再出现「系统异常」500

---
 yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java |   63 ++++++++++++++++++++++++++++++-
 1 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java
index fc9995e..e27d523 100644
--- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java
+++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/util/ExcelUtils.java
@@ -1,9 +1,16 @@
 package cn.iocoder.yudao.framework.excel.core.util;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.exceptions.ExceptionUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.idev.excel.ExcelWriter;
 import cn.idev.excel.FastExcelFactory;
 import cn.idev.excel.converters.longconverter.LongStringConverter;
+import cn.idev.excel.exception.ExcelAnalysisException;
+import cn.idev.excel.exception.ExcelCommonException;
+import cn.idev.excel.exception.ExcelDataConvertException;
 import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
+import lombok.extern.slf4j.Slf4j;
 import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy;
 import cn.iocoder.yudao.framework.excel.core.handler.DateAsTextCellWriteHandler;
 import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler;
@@ -14,11 +21,15 @@
 import java.io.InputStream;
 import java.util.List;
 
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.excel.core.enums.ExcelErrorCodeConstants.*;
+
 /**
  * Excel 宸ュ叿绫�
  *
  * @author 瓒呯骇绠$悊鍛�
  */
+@Slf4j
 public class ExcelUtils {
 
     /**
@@ -82,13 +93,61 @@
         response.setContentType("application/vnd.ms-excel;charset=UTF-8");
     }
 
-    public static <T> List<T> read(MultipartFile file, Class<T> head) throws IOException {
+    /**
+     * 璇诲彇 Excel 鏂囦欢
+     *
+     * <p>鎵�鏈夊鍏ユ帴鍙i兘缁忚繃杩欓噷锛屽洜姝ゅ湪杩欓噷缁熶竴鎶娿�屽潖鏂囦欢 / 绌烘枃浠� / 妯℃澘涓嶅尮閰� / 鍗曞厓鏍兼牸寮忛敊銆�
+     * 绛夊悇绉嶅簳灞傚紓甯革紝杞崲鎴愬彲璇荤殑涓枃鎻愮ず锛圫erviceException锛夈��
+     * 杩欐牱涓氬姟鎺ュ彛涓嶅繀鍚勮嚜鍐� try-catch锛屼篃涓嶄細鍐嶅嚭鐜板惈绯婄殑銆岀郴缁熷紓甯搞��500銆�</p>
+     *
+     * @param file Excel 鏂囦欢
+     * @param head 琛ㄥご瀵瑰簲鐨� VO 绫�
+     * @return 瑙f瀽缁撴灉
+     */
+    public static <T> List<T> read(MultipartFile file, Class<T> head) {
+        // 1. 鏂囦欢鏈韩涓虹┖
+        if (file == null || file.isEmpty()) {
+            throw exception(EXCEL_FILE_EMPTY);
+        }
+        // 2. 瑙f瀽锛堥�愮被璇嗗埆寮傚父锛岀粰鍑哄彲璇绘彁绀猴級
+        List<T> list;
         // 鍙傝�� https://t.zsxq.com/zM77F 甯栧瓙锛屽鍔� try 澶勭悊锛屽吋瀹� windows 鍦烘櫙
         try (InputStream inputStream = file.getInputStream()) {
-            return FastExcelFactory.read(inputStream, head, null)
+            list = FastExcelFactory.read(inputStream, head, null)
                     .autoCloseStream(false) // 涓嶈鑷姩鍏抽棴锛屼氦缁� Servlet 鑷繁澶勭悊
                     .doReadAllSync();
+        } catch (IOException ex) {
+            log.warn("[read][Excel 鏂囦欢璇诲彇澶辫触锛屾枃浠跺悕({})]", file.getOriginalFilename(), ex);
+            throw exception(EXCEL_FILE_READ_FAILED);
+        } catch (ExcelDataConvertException ex) {
+            // 鍗曞厓鏍兼暟鎹牸寮忎笉瀵癸紝渚嬪鏂囨湰鍒楀~浜嗘暟瀛椼�佹棩鏈熷垪濉簡涔辩爜
+            String detail = StrUtil.blankToDefault(ex.getMessage(), "鍐呭涓庡垪绫诲瀷涓嶅尮閰�");
+            log.warn("[read][Excel 鍗曞厓鏍兼暟鎹牸寮忛敊璇紝琛�({}) 鍒�({})]", ex.getRowIndex(), ex.getColumnIndex(), ex);
+            throw exception(EXCEL_DATA_CONVERT_FAILED,
+                    (ex.getRowIndex() == null ? 0 : ex.getRowIndex()) + 1,
+                    (ex.getColumnIndex() == null ? 0 : ex.getColumnIndex()) + 1,
+                    StrUtil.maxLength(detail, 60));
+        } catch (ExcelAnalysisException ex) {
+            // 鏂囦欢鎹熷潖銆佸姞瀵嗐�佷笉鏄湡姝g殑 Excel銆佽〃澶翠笌妯℃澘瀵逛笉涓婄瓑
+            String rootMsg = StrUtil.blankToDefault(ExceptionUtil.getRootCauseMessage(ex), "");
+            log.warn("[read][Excel 瑙f瀽澶辫触锛屾枃浠跺悕({})锛屽師鍥�({})]", file.getOriginalFilename(), rootMsg, ex);
+            if (StrUtil.containsAnyIgnoreCase(rootMsg, "head", "Can not find", "autoTrim", "Convert")) {
+                throw exception(EXCEL_HEAD_NOT_MATCH);
+            }
+            throw exception(EXCEL_TEMPLATE_NOT_MATCH);
+        } catch (ExcelCommonException ex) {
+            log.warn("[read][Excel 閫氱敤寮傚父锛屾枃浠跺悕({})]", file.getOriginalFilename(), ex);
+            throw exception(EXCEL_FILE_READ_FAILED);
+        } catch (Exception ex) {
+            // 鍏滃簳锛氫换浣曟湭棰勬枡鐨勮В鏋愬紓甯搁兘杞垚鍙鎻愮ず锛岄伩鍏嶇洿鎺� 500銆岀郴缁熷紓甯搞��
+            log.warn("[read][Excel 瑙f瀽鍑虹幇鏈鏈熷紓甯革紝鏂囦欢鍚�({})]", file.getOriginalFilename(), ex);
+            throw exception(EXCEL_FILE_READ_FAILED);
         }
+        // 3. 瑙f瀽鍑烘潵鏄┖琛紙鍙湁琛ㄥご銆佹病鏈夋暟鎹锛�
+        if (CollUtil.isEmpty(list)) {
+            throw exception(EXCEL_FILE_EMPTY_CONTENT);
+        }
+        return list;
     }
 
 }

--
Gitblit v1.9.3