From 6241b8acad2651564c1c668a9a54821361fbb4af Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 30 三月 2026 08:34:21 +0800
Subject: [PATCH] chore: sync rsf-server from isolated worktree

---
 rsf-server/src/main/java/com/vincent/rsf/server/common/utils/ExcelUtil.java |  379 +++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 305 insertions(+), 74 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/ExcelUtil.java b/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/ExcelUtil.java
index aefafe3..10e5db7 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/ExcelUtil.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/common/utils/ExcelUtil.java
@@ -2,12 +2,9 @@
 
 import cn.afterturn.easypoi.excel.annotation.Excel;
 import cn.afterturn.easypoi.excel.entity.ImportParams;
-import com.alibaba.excel.EasyExcel;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.vincent.rsf.framework.common.Cools;
 import com.vincent.rsf.framework.common.SpringUtils;
-import com.vincent.rsf.framework.exception.CoolException;
-import com.vincent.rsf.server.manager.entity.Matnr;
 import com.vincent.rsf.server.manager.entity.excel.MatnrsTemplate;
 import com.vincent.rsf.server.manager.entity.excel.annotation.ExcelComment;
 import com.vincent.rsf.server.system.entity.Fields;
@@ -16,22 +13,29 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.ss.formula.functions.T;
 import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.ss.util.CellRangeAddress;
 
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Created by vincent on 2/17/2024
  */
 @Slf4j
 public class ExcelUtil {
+    private static final Pattern EXTEND_FIELD_SOURCE_PATTERN = Pattern.compile("^extendFields\\.\\[(.+)]$");
+    private static final String SEQUENCE_SOURCE = "sequence";
+    private static final String SEQUENCE_LABEL = "搴忓彿";
+
     public static void build(Workbook workbook, HttpServletResponse response) {
         response.reset();
         Http.cors(response);
@@ -48,7 +52,7 @@
     }
 
     public static <T> Workbook create(List<T> list, Class<T> clz, boolean flagTemplate) {
-        HSSFWorkbook workbook = new HSSFWorkbook();
+        XSSFWorkbook workbook = new XSSFWorkbook();
         Sheet sheet = workbook.createSheet(clz.getSimpleName());
 
         Row header = sheet.createRow(0);
@@ -115,14 +119,7 @@
                     } catch (IllegalAccessException e) {
                         e.printStackTrace();
                     }
-                    if (value != null) {
-                        if (value instanceof Date) {
-                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-                            row.createCell(cellIndex).setCellValue(sdf.format((Date) value));
-                        } else {
-                            row.createCell(cellIndex).setCellValue(value.toString());
-                        }
-                    }
+                    writeCellValue(row, cellIndex, value);
                     cellIndex++;
                 }
             }
@@ -134,6 +131,298 @@
         return workbook;
     }
 
+    public static Workbook create(List<Map<String, Object>> rows, List<ExportColumn> columns) {
+        return create(rows, columns, null);
+    }
+
+    public static Workbook create(List<Map<String, Object>> rows, List<ExportColumn> columns, ExportMeta exportMeta) {
+        XSSFWorkbook workbook = new XSSFWorkbook();
+        Sheet sheet = workbook.createSheet("export");
+        List<ExportColumn> effectiveColumns = buildEffectiveColumns(columns, exportMeta);
+        boolean generatedSequenceColumn = hasGeneratedSequenceColumn(columns, effectiveColumns);
+        int titleColumnCount = Math.max(effectiveColumns.size(), 4);
+        int currentRowIndex = 0;
+
+        CellStyle titleStyle = createTitleStyle(workbook);
+        CellStyle subHeaderStyle = createSubHeaderStyle(workbook);
+        CellStyle headerStyle = createHeaderStyle(workbook);
+        CellStyle bodyStyle = createBodyStyle(workbook);
+
+        if (exportMeta != null && exportMeta.isLandscape()) {
+            sheet.getPrintSetup().setLandscape(true);
+        }
+
+        if (exportMeta != null && StringUtils.isNotBlank(exportMeta.getReportTitle())) {
+            Row titleRow = sheet.createRow(currentRowIndex++);
+            titleRow.setHeightInPoints(24);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue(exportMeta.getReportTitle());
+            titleCell.setCellStyle(titleStyle);
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, titleColumnCount - 1));
+
+            Row subHeaderRow = sheet.createRow(currentRowIndex++);
+            writeSubHeaderCell(subHeaderRow, 0, getSubHeaderText("鎶ヨ〃鏃ユ湡", exportMeta.getReportDate()), subHeaderStyle);
+            writeSubHeaderCell(subHeaderRow, 1, getSubHeaderText("鎵撳嵃浜�", exportMeta.getOperator()), subHeaderStyle);
+            writeSubHeaderCell(subHeaderRow, 2, getSubHeaderText("鎵撳嵃鏃堕棿", exportMeta.getPrintedAt()), subHeaderStyle);
+            writeSubHeaderCell(subHeaderRow, 3, getSubHeaderText("璁板綍鏁�", String.valueOf(exportMeta.getCount())), subHeaderStyle);
+
+            currentRowIndex++;
+        }
+
+        Row header = sheet.createRow(currentRowIndex++);
+        for (int index = 0; index < effectiveColumns.size(); index++) {
+            Cell headerCell = header.createCell(index);
+            headerCell.setCellValue(effectiveColumns.get(index).getLabel());
+            headerCell.setCellStyle(headerStyle);
+        }
+
+        int rowIndex = currentRowIndex;
+        for (int dataIndex = 0; dataIndex < rows.size(); dataIndex++) {
+            Map<String, Object> rowData = rows.get(dataIndex);
+            Row row = sheet.createRow(rowIndex++);
+            for (int columnIndex = 0; columnIndex < effectiveColumns.size(); columnIndex++) {
+                Object value = getExportCellValue(rowData, effectiveColumns.get(columnIndex).getSource(), generatedSequenceColumn, dataIndex);
+                writeCellValue(row, columnIndex, value, bodyStyle);
+            }
+        }
+
+        for (int columnIndex = 0; columnIndex < effectiveColumns.size(); columnIndex++) {
+            sheet.autoSizeColumn(columnIndex);
+        }
+
+        return workbook;
+    }
+
+    private static List<ExportColumn> buildEffectiveColumns(List<ExportColumn> columns, ExportMeta exportMeta) {
+        List<ExportColumn> effectiveColumns = new ArrayList<>(columns);
+        if (exportMeta != null && exportMeta.isShowSequence() && !containsSequenceColumn(columns)) {
+            effectiveColumns.add(0, new ExportColumn(SEQUENCE_SOURCE, SEQUENCE_LABEL));
+        }
+        return effectiveColumns;
+    }
+
+    private static boolean containsSequenceColumn(List<ExportColumn> columns) {
+        for (ExportColumn column : columns) {
+            if (SEQUENCE_SOURCE.equals(column.getSource())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean hasGeneratedSequenceColumn(List<ExportColumn> originalColumns, List<ExportColumn> effectiveColumns) {
+        return effectiveColumns.size() > originalColumns.size()
+                && !effectiveColumns.isEmpty()
+                && SEQUENCE_SOURCE.equals(effectiveColumns.get(0).getSource());
+    }
+
+    private static Object getExportCellValue(
+            Map<String, Object> rowData,
+            String source,
+            boolean generatedSequenceColumn,
+            int dataIndex
+    ) {
+        if (generatedSequenceColumn && SEQUENCE_SOURCE.equals(source)) {
+            return dataIndex + 1;
+        }
+        return getRowValue(rowData, source);
+    }
+
+    private static Object getRowValue(Map<String, Object> rowData, String source) {
+        if (rowData == null || StringUtils.isBlank(source)) {
+            return null;
+        }
+
+        if (rowData.containsKey(source)) {
+            return rowData.get(source);
+        }
+
+        Matcher matcher = EXTEND_FIELD_SOURCE_PATTERN.matcher(source);
+        if (matcher.matches()) {
+            Object extendFields = rowData.get("extendFields");
+            if (extendFields instanceof Map<?, ?> extendFieldMap) {
+                return extendFieldMap.get(matcher.group(1));
+            }
+        }
+
+        return rowData.get(source);
+    }
+
+    private static void writeCellValue(Row row, int cellIndex, Object value) {
+        writeCellValue(row, cellIndex, value, null);
+    }
+
+    private static void writeCellValue(Row row, int cellIndex, Object value, CellStyle cellStyle) {
+        Cell cell = row.createCell(cellIndex);
+        if (cellStyle != null) {
+            cell.setCellStyle(cellStyle);
+        }
+        if (value == null) {
+            return;
+        }
+        if (value instanceof Date) {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            cell.setCellValue(sdf.format((Date) value));
+            return;
+        }
+        cell.setCellValue(value.toString());
+    }
+
+    private static void writeSubHeaderCell(Row row, int cellIndex, String value, CellStyle cellStyle) {
+        Cell cell = row.createCell(cellIndex);
+        cell.setCellValue(value);
+        cell.setCellStyle(cellStyle);
+    }
+
+    private static String getSubHeaderText(String label, String value) {
+        return label + ": " + StringUtils.defaultString(value);
+    }
+
+    private static CellStyle createTitleStyle(Workbook workbook) {
+        CellStyle cellStyle = workbook.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+        Font font = workbook.createFont();
+        font.setBold(true);
+        font.setFontHeightInPoints((short) 14);
+        cellStyle.setFont(font);
+        return cellStyle;
+    }
+
+    private static CellStyle createSubHeaderStyle(Workbook workbook) {
+        CellStyle cellStyle = workbook.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.LEFT);
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+        Font font = workbook.createFont();
+        font.setFontHeightInPoints((short) 10);
+        cellStyle.setFont(font);
+        return cellStyle;
+    }
+
+    private static CellStyle createHeaderStyle(Workbook workbook) {
+        CellStyle cellStyle = workbook.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.CENTER);
+        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+        Font font = workbook.createFont();
+        font.setBold(true);
+        font.setFontHeightInPoints((short) 10);
+        cellStyle.setFont(font);
+        return cellStyle;
+    }
+
+    private static CellStyle createBodyStyle(Workbook workbook) {
+        CellStyle cellStyle = workbook.createCellStyle();
+        cellStyle.setAlignment(HorizontalAlignment.LEFT);
+        cellStyle.setVerticalAlignment(VerticalAlignment.TOP);
+        cellStyle.setWrapText(true);
+        return cellStyle;
+    }
+
+    public static class ExportColumn {
+        private final String source;
+        private final String label;
+
+        public ExportColumn(String source, String label) {
+            this.source = source;
+            this.label = label;
+        }
+
+        public String getSource() {
+            return source;
+        }
+
+        public String getLabel() {
+            return label;
+        }
+    }
+
+    public static class ExportMeta {
+        private final String reportTitle;
+        private final String reportDate;
+        private final String printedAt;
+        private final String operator;
+        private final int count;
+        private final Map<String, Object> reportStyle;
+
+        public ExportMeta(String reportTitle, String reportDate, String printedAt, String operator, int count) {
+            this(reportTitle, reportDate, printedAt, operator, count, Collections.emptyMap());
+        }
+
+        public ExportMeta(
+                String reportTitle,
+                String reportDate,
+                String printedAt,
+                String operator,
+                int count,
+                Map<String, ?> reportStyle
+        ) {
+            this.reportTitle = reportTitle;
+            this.reportDate = reportDate;
+            this.printedAt = printedAt;
+            this.operator = operator;
+            this.count = count;
+            this.reportStyle = normalizeReportStyle(reportStyle);
+        }
+
+        public String getReportTitle() {
+            return reportTitle;
+        }
+
+        public String getReportDate() {
+            return reportDate;
+        }
+
+        public String getPrintedAt() {
+            return printedAt;
+        }
+
+        public String getOperator() {
+            return operator;
+        }
+
+        public int getCount() {
+            return count;
+        }
+
+        public Map<String, Object> getReportStyle() {
+            return reportStyle;
+        }
+
+        public boolean isLandscape() {
+            return "landscape".equalsIgnoreCase(Objects.toString(getReportStyleValue("orientation"), ""));
+        }
+
+        public boolean isShowSequence() {
+            if (reportStyle.isEmpty() || !reportStyle.containsKey("showSequence")) {
+                return true;
+            }
+            Object value = getReportStyleValue("showSequence");
+            if (value instanceof Boolean boolValue) {
+                return boolValue;
+            }
+            return !"false".equalsIgnoreCase(Objects.toString(value, ""));
+        }
+
+        private Object getReportStyleValue(String key) {
+            return reportStyle.get(key);
+        }
+
+        private static Map<String, Object> normalizeReportStyle(Map<String, ?> reportStyle) {
+            if (reportStyle == null || reportStyle.isEmpty()) {
+                return Collections.emptyMap();
+            }
+
+            Map<String, Object> normalizedReportStyle = new HashMap<>();
+            for (Map.Entry<String, ?> entry : reportStyle.entrySet()) {
+                normalizedReportStyle.put(entry.getKey(), entry.getValue());
+            }
+            return Collections.unmodifiableMap(normalizedReportStyle);
+        }
+    }
+
     /**
      * 娣诲姞瀵煎叆excel閰嶇疆鍙傛暟
      * 娉細榛樿閰嶇疆鍙弧瓒冲綋鍓嶉渶姹�
@@ -143,69 +432,10 @@
     public static ImportParams getDefaultImportParams() {
         ImportParams importParams = new ImportParams();
         importParams.setTitleRows(0);
+//        importParams.setNeedVerify(true);
         importParams.setHeadRows(1);
         importParams.setSheetNum(1);
         return importParams;
-    }
-
-    /**
-     * @author Ryan
-     * @description Excel瀵煎嚭Map鏍煎紡琛ㄦ牸
-     * @param
-     * @return
-     * @time 2025/3/18 09:30
-     */
-    public static void exportForMap(HttpServletResponse response, Class cls, String fileName, List<List<Object>> data) {
-        try {
-            response.setContentType("application/octet-stream; charset=utf-8");
-            response.setCharacterEncoding("utf-8");
-            String name = URLEncoder.encode(fileName, "UTF-8");
-            response.setHeader("Content-disposition", "attachment;filename=" + name + ".xlsx");
-            EasyExcel.write(response.getOutputStream()).head(getHeader(cls)).sheet().doWrite(null);
-        } catch (IOException exception) {
-            exception.printStackTrace();
-        }
-    }
-
-    /**
-     * @author Ryan
-     * @description excel瀵煎嚭map妯″紡
-     * @param  Class<T> 妯℃澘绫诲瀷
-     * @return  List<List<String>> 琛ㄥご淇℃伅
-     * @time 2025/3/18 09:26
-     */
-    public static List<List<String>> getHeader(Class<T> t) {
-        List<List<String>> headList = new ArrayList<List<String>>();
-        if (t.getSuperclass().isInstance(MatnrsTemplate.class)) {
-            Field[] allFields = Cools.getAllFields(t);
-            if (Objects.isNull(allFields) ||  allFields.length < 1) {
-                throw new CoolException("妯℃澘鍒椾笉鑳戒负绌猴紒锛�");
-            }
-            for (Field field : allFields) {
-                List<String> list = new ArrayList<String>();
-                String fieldName = "";
-                if (field.isAnnotationPresent(Excel.class)){
-                    fieldName = field.getAnnotation(Excel.class).name();
-                }
-
-                list.add(field.getName());
-                headList.add(list);
-            }
-
-            FieldsService itemService = SpringUtils.getBean(FieldsService.class);
-            List<Fields> sysFields = itemService.list(new LambdaQueryWrapper<Fields>()
-                    .eq(Fields::getStatus, 1)
-                    .eq(Fields::getFlagEnable, 1));
-            //娣诲姞鎵╁睍瀛楁鍒悕
-            if (!sysFields.isEmpty()) {
-                sysFields.forEach(fields1 -> {
-                    List<String> list = new ArrayList<String>();
-                    list.add(fields1.getFieldsAlise());
-                    headList.add(list);
-                });
-            }
-        }
-        return headList;
     }
 
     /**
@@ -287,3 +517,4 @@
 
 
 }
+

--
Gitblit v1.9.1