From ca6d2349fb1b0f41358dbaa68dcb06a30df81ad0 Mon Sep 17 00:00:00 2001
From: wujianwei <wjw@11.com>
Date: 星期五, 09 一月 2026 11:22:49 +0800
Subject: [PATCH] 修改发票新增

---
 common/src/main/java/com/ruoyi/common/core/service/BaseService.java |  235 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 234 insertions(+), 1 deletions(-)

diff --git a/common/src/main/java/com/ruoyi/common/core/service/BaseService.java b/common/src/main/java/com/ruoyi/common/core/service/BaseService.java
index 7947c38..165ce08 100644
--- a/common/src/main/java/com/ruoyi/common/core/service/BaseService.java
+++ b/common/src/main/java/com/ruoyi/common/core/service/BaseService.java
@@ -4,18 +4,27 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.github.pagehelper.Page;
 import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.config.RuoYiConfig;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.page.PageDomain;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.common.utils.file.DownloadExportUtil;
 import com.ruoyi.common.utils.poi.ExcelUtil;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.List;
 import java.util.function.Function;
 
@@ -89,6 +98,230 @@
         return fileName;
     }
 
+    /**
+     * 瀵煎嚭涓や釜涓嶅悓sheet鐨勬暟鎹埌鍚屼竴涓狤xcel鏂囦欢
+     *
+     * @param clazz1     绗竴涓猻heet瀵瑰簲鐨勫疄浣撶被
+     * @param clazz2     绗簩涓猻heet瀵瑰簲鐨勫疄浣撶被
+     * @param fileName   鏂囦欢鍚�
+     * @param sheetName1 绗竴涓猻heet鍚嶇О
+     * @param sheetName2 绗簩涓猻heet鍚嶇О
+     * @param dataList1  绗竴涓猻heet鐨勬暟鎹垪琛�
+     * @param dataList2  绗簩涓猻heet鐨勬暟鎹垪琛�
+     * @return 瀵煎嚭鍚庣殑鏂囦欢鍚�
+     */
+    protected <T1, T2> String exportMultiSheetData(Class<T1> clazz1, Class<T2> clazz2, 
+                                                   String fileName, String sheetName1, String sheetName2,
+                                                   List<T1> dataList1, List<T2> dataList2) {
+        
+        // 鍒涘缓绗竴涓猻heet鐨凟xcelUtil骞跺鍑烘暟鎹�
+        ExcelUtil<T1> excelUtil1 = new ExcelUtil<>(clazz1);
+        excelUtil1.initialize(sheetName1, null, Excel.Type.EXPORT);
+        
+        if (dataList1 != null && !dataList1.isEmpty()) {
+            excelUtil1.exportExcel(dataList1);
+        }
+        
+        // 浣跨敤ExcelUtil鐨刦inishExport鏂规硶瀵煎嚭鍒颁复鏃舵枃浠�
+        String tempFileName = "temp_" + System.currentTimeMillis() + ".xlsx";
+        excelUtil1.finishExport(tempFileName);
+        
+        try {
+            // 璇诲彇涓存椂鏂囦欢骞舵坊鍔犵浜屼釜sheet
+            FileInputStream fis = new FileInputStream(getAbsoluteFile(tempFileName));
+            SXSSFWorkbook workbook = new SXSSFWorkbook(new org.apache.poi.xssf.usermodel.XSSFWorkbook(fis));
+            fis.close();
+            
+            // 鍒涘缓绗簩涓猻heet
+            Sheet sheet2 = workbook.createSheet(sheetName2);
+            
+            // 浣跨敤ExcelUtil鐨勬柟寮忓鍑虹浜屼釜sheet鐨勬暟鎹�
+            if (dataList2 != null && !dataList2.isEmpty()) {
+                // 鍒涘缓绗簩涓猻heet鐨凟xcelUtil鐢ㄤ簬鐢熸垚琛ㄥご
+                ExcelUtil<T2> excelUtil2 = new ExcelUtil<>(clazz2);
+                excelUtil2.initialize(sheetName2, null, Excel.Type.EXPORT);
+                
+                // 鑾峰彇琛ㄥご鏍峰紡淇℃伅
+                SXSSFWorkbook tempWorkbook = getWorkbookFromExcelUtil(excelUtil2);
+                Sheet tempSheet = tempWorkbook.getSheetAt(0);
+                Row headerRow = tempSheet.getRow(1); // 琛ㄥご閫氬父鍦ㄧ浜岃
+                
+                // 澶嶅埗琛ㄥご鍒扮浜屼釜sheet
+                if (headerRow != null) {
+                    Row newHeaderRow = sheet2.createRow(0);
+                    copyRow(headerRow, newHeaderRow);
+                }
+                
+                // 瀵煎嚭鏁版嵁鍒扮浜屼釜sheet
+                int startRow = 1;
+                for (T2 data : dataList2) {
+                    Row dataRow = sheet2.createRow(startRow++);
+                    exportDataRow(clazz2, data, dataRow);
+                }
+                
+                tempWorkbook.close();
+            }
+            
+            // 瀹屾垚瀵煎嚭
+            finishMultiSheetExport(workbook, fileName);
+            
+            // 鍒犻櫎涓存椂鏂囦欢
+            new File(getAbsoluteFile(tempFileName)).delete();
+            
+        } catch (Exception e) {
+            logger.error("Failed to export multi-sheet data: {}", e.getMessage(), e);
+            throw new RuntimeException("澶歴heet瀵煎嚭澶辫触", e);
+        }
+        
+        return fileName;
+    }
+
+    /**
+     * 浠嶦xcelUtil涓幏鍙栧伐浣滅翱瀵硅薄
+     */
+    private <T> SXSSFWorkbook getWorkbookFromExcelUtil(ExcelUtil<T> excelUtil) {
+        try {
+            Field workbookField = ExcelUtil.class.getDeclaredField("workbook");
+            workbookField.setAccessible(true);
+            return (SXSSFWorkbook) workbookField.get(excelUtil);
+        } catch (Exception e) {
+            logger.error("Failed to get workbook from ExcelUtil: {}", e.getMessage(), e);
+            throw new RuntimeException("鑾峰彇宸ヤ綔绨垮け璐�", e);
+        }
+    }
+
+    /**
+     * 灏嗘暟鎹鍑哄埌鎸囧畾鐨剆heet
+     */
+    private <T> void exportDataToSheet(Class<T> clazz, Sheet sheet, List<T> dataList) {
+        try {
+            // 鍒涘缓涓存椂ExcelUtil鐢ㄤ簬鐢熸垚琛ㄥご
+            ExcelUtil<T> tempUtil = new ExcelUtil<>(clazz);
+            tempUtil.initialize("temp", null, Excel.Type.EXPORT);
+            
+            // 鑾峰彇琛ㄥご琛�
+            SXSSFWorkbook tempWorkbook = getWorkbookFromExcelUtil(tempUtil);
+            Sheet tempSheet = tempWorkbook.getSheetAt(0);
+            Row headerRow = tempSheet.getRow(1); // 琛ㄥご閫氬父鍦ㄧ浜岃
+            
+            // 澶嶅埗琛ㄥご鍒扮洰鏍噑heet
+            if (headerRow != null) {
+                Row newHeaderRow = sheet.createRow(0);
+                copyRow(headerRow, newHeaderRow);
+            }
+            
+            // 瀵煎嚭鏁版嵁
+            if (dataList != null && !dataList.isEmpty()) {
+                int startRow = 1; // 鏁版嵁浠庣浜岃寮�濮�
+                for (T data : dataList) {
+                    Row dataRow = sheet.createRow(startRow++);
+                    exportDataRow(clazz, data, dataRow);
+                }
+            }
+            
+            tempWorkbook.close();
+        } catch (Exception e) {
+            logger.error("Failed to export data to sheet: {}", e.getMessage(), e);
+            throw new RuntimeException("瀵煎嚭鏁版嵁鍒皊heet澶辫触", e);
+        }
+    }
+
+    /**
+     * 澶嶅埗琛屾暟鎹�
+     */
+    private void copyRow(Row sourceRow, Row targetRow) {
+        if (sourceRow == null || targetRow == null) return;
+        
+        for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
+            Cell sourceCell = sourceRow.getCell(i);
+            Cell targetCell = targetRow.createCell(i);
+            
+            if (sourceCell != null) {
+                // 澶嶅埗鍗曞厓鏍兼牱寮�
+                targetCell.setCellStyle(sourceCell.getCellStyle());
+                
+                // 澶嶅埗鍗曞厓鏍煎��
+                switch (sourceCell.getCellType()) {
+                    case STRING:
+                        targetCell.setCellValue(sourceCell.getStringCellValue());
+                        break;
+                    case NUMERIC:
+                        targetCell.setCellValue(sourceCell.getNumericCellValue());
+                        break;
+                    case BOOLEAN:
+                        targetCell.setCellValue(sourceCell.getBooleanCellValue());
+                        break;
+                    case FORMULA:
+                        targetCell.setCellFormula(sourceCell.getCellFormula());
+                        break;
+                    default:
+                        targetCell.setCellValue("");
+                }
+            }
+        }
+    }
+
+    /**
+     * 瀵煎嚭鏁版嵁琛�
+     */
+    private <T> void exportDataRow(Class<T> clazz, T data, Row row) {
+        try {
+            ExcelUtil<T> tempUtil = new ExcelUtil<>(clazz);
+            tempUtil.initialize("temp", null, Excel.Type.EXPORT);
+            
+            // 鑾峰彇瀛楁淇℃伅
+            Field[] fields = clazz.getDeclaredFields();
+            int columnIndex = 0;
+            
+            for (Field field : fields) {
+                field.setAccessible(true);
+                Excel excel = field.getAnnotation(Excel.class);
+                
+                if (excel != null && excel.isExport()) {
+                    Cell cell = row.createCell(columnIndex++);
+                    Object value = field.get(data);
+                    
+                    if (value != null) {
+                        cell.setCellValue(value.toString());
+                    } else {
+                        cell.setCellValue("");
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Failed to export data row: {}", e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 瀹屾垚澶歴heet瀵煎嚭
+     */
+    private void finishMultiSheetExport(SXSSFWorkbook workbook, String fileName) {
+        try (OutputStream out = Files.newOutputStream(Paths.get(getAbsoluteFile(fileName)))) {
+            workbook.write(out);
+        } catch (Exception e) {
+            logger.error("Failed to finish multi-sheet export: {}", e.getMessage(), e);
+            throw new RuntimeException("澶歴heet瀵煎嚭澶辫触", e);
+        } finally {
+            try {
+                workbook.close();
+            } catch (Exception e) {
+                logger.error("Failed to close workbook: {}", e.getMessage(), e);
+            }
+        }
+    }
+
+    /**
+     * 鑾峰彇鏂囦欢鐨勭粷瀵硅矾寰�
+     */
+    private String getAbsoluteFile(String fileName) {
+        String downloadPath = RuoYiConfig.getDownloadPath();
+        File file = new File(downloadPath + fileName);
+        if (!file.exists()) {
+            file.getParentFile().mkdirs();
+        }
+        return file.getAbsolutePath();
+    }
 
 
-}
+}
\ No newline at end of file

--
Gitblit v1.8.0