From d963031435c593b761436d819268f5493923c41d Mon Sep 17 00:00:00 2001
From: liusheng <337615773@qq.com>
Date: 星期二, 22 九月 2026 18:37:52 +0800
Subject: [PATCH] 1.导出新增图表

---
 ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java |  156 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 156 insertions(+), 0 deletions(-)

diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
index 06e482e..814a4c5 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -442,6 +442,162 @@
     }
 
     /**
+     * 瀵煎嚭鍖呭惈涓や釜Sheet鐨凟xcel
+     * Sheet1: 鍩轰簬褰撳墠娉涘瀷绫诲瀷T鐨勬敞瑙e鍑�
+     * Sheet2: 鍩轰簬浼犲叆鐨刢lazz2绫诲瀷鐨勬敞瑙e鍑�
+     *
+     * @param response   杩斿洖鏁版嵁
+     * @param list1      绗竴涓猄heet鐨勬暟鎹泦鍚�
+     * @param sheetName1 绗竴涓猄heet鐨勫悕绉�
+     * @param list2      绗簩涓猄heet鐨勬暟鎹泦鍚�
+     * @param sheetName2 绗簩涓猄heet鐨勫悕绉�
+     * @param clazz2     绗簩涓猄heet鏁版嵁瀵硅薄鐨凜lass
+     */
+    public void exportExcelTwoSheet(HttpServletResponse response,
+                                    List<T> list1, String sheetName1,
+                                    List<?> list2, String sheetName2, Class<?> clazz2) {
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+        response.setCharacterEncoding("utf-8");
+        // 鍒濆鍖栧苟鍐欏叆Sheet1
+        this.init(list1, sheetName1, StringUtils.EMPTY, Type.EXPORT);
+        writeSheet();
+        // 杩藉姞鍐欏叆Sheet2
+        writeAdditionalSheet(list2, sheetName2, clazz2);
+        // 杈撳嚭鍒板搷搴旀祦
+        try {
+            wb.write(response.getOutputStream());
+        } catch (Exception e) {
+            log.error("瀵煎嚭Excel寮傚父{}", e.getMessage());
+        } finally {
+            IOUtils.closeQuietly(wb);
+        }
+    }
+
+    /**
+     * 鍥捐〃Sheet鏋勫缓鍥炶皟锛氱敱璋冪敤鏂瑰湪缁欏畾宸ヤ綔绨夸笂杩藉姞涓�涓紙鎴栧涓級甯﹀浘琛ㄧ殑Sheet
+     */
+    public interface ChartSheetBuilder {
+        void build(XSSFWorkbook workbook);
+    }
+
+    /**
+     * 鍙栧簳灞� XSSFWorkbook锛圫XSSF 娴佸紡宸ヤ綔绨夸篃鏀寔鎸傚師鐢熷浘琛級锛屼笉鏀寔鏃惰繑鍥� null
+     */
+    public XSSFWorkbook getXssfWorkbook() {
+        if (wb instanceof SXSSFWorkbook) {
+            return ((SXSSFWorkbook) wb).getXSSFWorkbook();
+        }
+        if (wb instanceof XSSFWorkbook) {
+            return (XSSFWorkbook) wb;
+        }
+        return null;
+    }
+
+    /**
+     * 瀵煎嚭涓や釜鏁版嵁Sheet + 涓�涓浘琛⊿heet锛堝浘琛ㄥ唴瀹圭敱璋冪敤鏂归�氳繃 builder 杩藉姞锛�
+     *
+     * @param response   杩斿洖鏁版嵁
+     * @param list1      绗竴涓猄heet鐨勬暟鎹泦鍚�
+     * @param sheetName1 绗竴涓猄heet鐨勫悕绉�
+     * @param list2      绗簩涓猄heet鐨勬暟鎹泦鍚�
+     * @param sheetName2 绗簩涓猄heet鐨勫悕绉�
+     * @param clazz2     绗簩涓猄heet鏁版嵁瀵硅薄鐨凜lass
+     * @param chartBuilder 鍥捐〃Sheet鏋勫缓鍥炶皟锛屽彲涓虹┖锛堜负绌烘椂涓庝袱Sheet瀵煎嚭瀹屽叏涓�鏍凤級
+     */
+    public void exportExcelTwoSheetWithChart(HttpServletResponse response,
+                                             List<T> list1, String sheetName1,
+                                             List<?> list2, String sheetName2, Class<?> clazz2,
+                                             ChartSheetBuilder chartBuilder) {
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+        response.setCharacterEncoding("utf-8");
+        // 鍒濆鍖栧苟鍐欏叆Sheet1
+        this.init(list1, sheetName1, StringUtils.EMPTY, Type.EXPORT);
+        writeSheet();
+        // 杩藉姞鍐欏叆Sheet2
+        writeAdditionalSheet(list2, sheetName2, clazz2);
+        // 杩藉姞鍥捐〃Sheet
+        if (chartBuilder != null) {
+            XSSFWorkbook xssfWorkbook = getXssfWorkbook();
+            if (xssfWorkbook != null) {
+                chartBuilder.build(xssfWorkbook);
+            } else {
+                log.warn("褰撳墠宸ヤ綔绨夸笉鏀寔鍘熺敓鍥捐〃锛岃烦杩囧浘琛⊿heet");
+            }
+        }
+        // 杈撳嚭鍒板搷搴旀祦
+        try {
+            wb.write(response.getOutputStream());
+        } catch (Exception e) {
+            log.error("瀵煎嚭Excel寮傚父{}", e.getMessage());
+        } finally {
+            IOUtils.closeQuietly(wb);
+        }
+    }
+
+    /**
+     * 鍚戝綋鍓嶅伐浣滅翱杩藉姞鍐欏叆涓�涓猄heet
+     *
+     * @param dataList  鏁版嵁闆嗗悎
+     * @param sheetName Sheet鍚嶇О
+     * @param dataClazz 鏁版嵁瀵硅薄鐨凜lass
+     */
+    @SuppressWarnings("unchecked")
+    public void writeAdditionalSheet(List<?> dataList, String sheetName, Class<?> dataClazz) {        if (dataList == null) {
+            dataList = new ArrayList<>();
+        }
+        // 淇濆瓨鍘熷鐘舵��
+        Class<T> originClazz = this.clazz;
+        List<Object[]> originFields = this.fields;
+        List<T> originList = this.list;
+        String originSheetName = this.sheetName;
+        int originRownum = this.rownum;
+        List<Field> originSubFields = this.subFields;
+        Method originSubMethod = this.subMethod;
+        int originSubMergedFirstRowNum = this.subMergedFirstRowNum;
+        int originSubMergedLastRowNum = this.subMergedLastRowNum;
+        Map<Integer, Double> originStatistics = this.statistics;
+        short originMaxHeight = this.maxHeight;
+
+        // 璁剧疆鏂扮被鍨�
+        this.clazz = (Class<T>) dataClazz;
+        this.list = (List<T>) dataList;
+        this.sheetName = sheetName;
+        this.rownum = 0;
+        this.subFields = null;
+        this.subMethod = null;
+        this.subMergedFirstRowNum = 1;
+        this.subMergedLastRowNum = 0;
+        this.statistics = new HashMap<Integer, Double>();
+
+        // 鍒涘缓鏂癝heet
+        this.sheet = wb.createSheet();
+        wb.setSheetName(wb.getNumberOfSheets() - 1, sheetName);
+
+        // 閲嶆柊鍒涘缓瀛楁
+        createExcelField();
+
+        // 琛ュ厖鏂板瓧娈电殑鏍峰紡
+        this.styles.putAll(annotationHeaderStyles(wb, this.styles));
+        this.styles.putAll(annotationDataStyles(wb));
+
+        // 鍐欏叆鏁版嵁
+        writeSheet();
+
+        // 鎭㈠鍘熷鐘舵��
+        this.clazz = originClazz;
+        this.fields = originFields;
+        this.list = originList;
+        this.sheetName = originSheetName;
+        this.rownum = originRownum;
+        this.subFields = originSubFields;
+        this.subMethod = originSubMethod;
+        this.subMergedFirstRowNum = originSubMergedFirstRowNum;
+        this.subMergedLastRowNum = originSubMergedLastRowNum;
+        this.statistics = originStatistics;
+        this.maxHeight = originMaxHeight;
+    }
+
+    /**
      * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟锛堝甫鏂囦欢鍚嶏級
      *
      * @param response  杩斿洖鏁版嵁

--
Gitblit v1.9.3