From 44ac1c9a2a6ee6ac9f618f4a63510f8f94d1b1a9 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期三, 25 三月 2026 15:43:51 +0800
Subject: [PATCH] #打印+导出

---
 rsf-server/src/main/java/com/vincent/rsf/server/common/utils/ExcelUtil.java |  401 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 367 insertions(+), 34 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 ebffe54..4b3649a 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
@@ -1,25 +1,38 @@
 package com.vincent.rsf.server.common.utils;
 
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import cn.afterturn.easypoi.excel.entity.ImportParams;
+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.server.manager.entity.excel.MatnrsTemplate;
+import com.vincent.rsf.server.manager.entity.excel.annotation.ExcelComment;
+import com.vincent.rsf.server.system.entity.Fields;
+import com.vincent.rsf.server.system.service.FieldsService;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
+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.Date;
-import java.util.List;
+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\\.\\[(.+)]$");
 
     public static void build(Workbook workbook, HttpServletResponse response) {
         response.reset();
@@ -28,16 +41,27 @@
         try {
             response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("export", "UTF-8"));
             workbook.write(response.getOutputStream());
-        } catch (IOException ignore) {}
+        } catch (IOException ignore) {
+        }
     }
 
     public static <T> Workbook create(List<T> list, Class<T> clz) {
-        HSSFWorkbook workbook = new HSSFWorkbook();
+        return create(list, clz, false);
+    }
+
+    public static <T> Workbook create(List<T> list, Class<T> clz, boolean flagTemplate) {
+        XSSFWorkbook workbook = new XSSFWorkbook();
         Sheet sheet = workbook.createSheet(clz.getSimpleName());
 
         Row header = sheet.createRow(0);
         Field[] fields = Cools.getAllFields(clz);
         int headerIdx = 0;
+        FieldsService itemService = SpringUtils.getBean(FieldsService.class);
+        List<Fields> sysFields = itemService.list(new LambdaQueryWrapper<Fields>()
+                .eq(Fields::getStatus, 1)
+                .eq(Fields::getFlagEnable, 1));
+
+
         for (Field field : fields) {
             if (Modifier.isFinal(field.getModifiers())
                     || Modifier.isStatic(field.getModifiers())
@@ -45,44 +69,59 @@
                 continue;
             }
             String memo = "Undefined";
+            if (flagTemplate) {
+                memo = field.getName();
+            } else {
+                if (field.isAnnotationPresent(Excel.class)) {
+                    memo = field.getAnnotation(Excel.class).name();
+                }
+            }
             if (field.isAnnotationPresent(ApiModelProperty.class)) {
                 memo = field.getAnnotation(ApiModelProperty.class).value();
             }
             header.createCell(headerIdx).setCellValue(memo);
             headerIdx++;
         }
-
-        int rowIndex = 1;
-        for (T t : list) {
-            Row row = sheet.createRow(rowIndex++);
-
-            int cellIndex = 0;
-            for (Field field : fields) {
-                if (Modifier.isFinal(field.getModifiers())
-                        || Modifier.isStatic(field.getModifiers())
-                        || Modifier.isTransient(field.getModifiers())) {
-                    continue;
-                }
-
-                field.setAccessible(true);  // 姝よ寰堥噸瑕侊紝鐗瑰埆鏄瓧娈典负private鏃�
-                Object value = null;
-                try {
-                    value = field.get(t);
-                } 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));
+        if (clz.equals(MatnrsTemplate.class)) {
+            //娣诲姞鎵╁睍瀛楁鍒悕
+            if (!sysFields.isEmpty()) {
+                for (Fields field : sysFields) {
+                    if (flagTemplate) {
+                        header.createCell(headerIdx).setCellValue(field.getFields());
                     } else {
-                        row.createCell(cellIndex).setCellValue(value.toString());
+                        header.createCell(headerIdx).setCellValue(field.getFieldsAlise());
                     }
+                    headerIdx++;
                 }
-                cellIndex++;
             }
         }
 
+        int rowIndex = 1;
+        if (!Objects.isNull(list)) {
+            for (T t : list) {
+                Row row = sheet.createRow(rowIndex++);
+
+                int cellIndex = 0;
+                for (Field field : fields) {
+                    if (Modifier.isFinal(field.getModifiers())
+                            || Modifier.isStatic(field.getModifiers())
+                            || Modifier.isTransient(field.getModifiers())) {
+                        continue;
+                    }
+
+                    // 姝よ寰堥噸瑕侊紝鐗瑰埆鏄瓧娈典负private鏃�
+                    field.setAccessible(true);
+                    Object value = null;
+                    try {
+                        value = field.get(t);
+                    } catch (IllegalAccessException e) {
+                        e.printStackTrace();
+                    }
+                    writeCellValue(row, cellIndex, value);
+                    cellIndex++;
+                }
+            }
+        }
         for (int i = 0; i <= fields.length; i++) {
             sheet.autoSizeColumn(i);
         }
@@ -90,6 +129,300 @@
         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");
+        int titleColumnCount = Math.max(columns.size(), 4);
+        int currentRowIndex = 0;
+
+        CellStyle titleStyle = createTitleStyle(workbook);
+        CellStyle subHeaderStyle = createSubHeaderStyle(workbook);
+        CellStyle headerStyle = createHeaderStyle(workbook);
+        CellStyle bodyStyle = createBodyStyle(workbook);
+
+        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 < columns.size(); index++) {
+            Cell headerCell = header.createCell(index);
+            headerCell.setCellValue(columns.get(index).getLabel());
+            headerCell.setCellStyle(headerStyle);
+        }
+
+        int rowIndex = currentRowIndex;
+        for (Map<String, Object> rowData : rows) {
+            Row row = sheet.createRow(rowIndex++);
+            for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
+                Object value = getRowValue(rowData, columns.get(columnIndex).getSource());
+                writeCellValue(row, columnIndex, value, bodyStyle);
+            }
+        }
+
+        for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
+            sheet.autoSizeColumn(columnIndex);
+        }
+
+        return workbook;
+    }
+
+    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;
+
+        public ExportMeta(String reportTitle, String reportDate, String printedAt, String operator, int count) {
+            this.reportTitle = reportTitle;
+            this.reportDate = reportDate;
+            this.printedAt = printedAt;
+            this.operator = operator;
+            this.count = count;
+        }
+
+        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;
+        }
+    }
+
+    /**
+     * 娣诲姞瀵煎叆excel閰嶇疆鍙傛暟
+     * 娉細榛樿閰嶇疆鍙弧瓒冲綋鍓嶉渶姹�
+     *
+     * @return
+     */
+    public static ImportParams getDefaultImportParams() {
+        ImportParams importParams = new ImportParams();
+        importParams.setTitleRows(0);
+//        importParams.setNeedVerify(true);
+        importParams.setHeadRows(1);
+        importParams.setSheetNum(1);
+        return importParams;
+    }
+
+    /**
+     * 鏍规嵁 {@code tClass} 鐩稿叧鎴愬憳鍙橀噺鐨� {@link ExcelComment#example()} 瀛楁鍒涘缓妯℃嫙鏁版嵁锛屾殏涓嶆敮鎸� 澶嶆潅绫诲瀷
+     *
+     * @param tClass
+     * @return
+     */
+    public static <T> T mockData(Class<T> tClass) {
+        if (tClass == null) {
+            return null;
+        }
+        T instance = null;
+
+        try {
+            instance = tClass.newInstance();
+            Field[] declaredFields = tClass.getDeclaredFields();
+            for (Field declaredField : declaredFields) {
+                ExcelComment comment = declaredField.getAnnotation(ExcelComment.class);
+                if (comment == null) {
+                    continue;
+                }
+                declaredField.setAccessible(true);
+                Class<?> fieldType = declaredField.getType();
+
+                String exampleValue = comment.example();
+                Object value = null;
+
+                if (fieldType == int.class || fieldType == Integer.class) {
+                    value = StringUtils.isBlank(exampleValue) ? 0 : Integer.parseInt(exampleValue);
+                } else if (fieldType == short.class || fieldType == Short.class) {
+                    value = StringUtils.isBlank(exampleValue) ? 0 : Short.parseShort(exampleValue);
+                } else if (fieldType == long.class || fieldType == Long.class) {
+                    value = StringUtils.isBlank(exampleValue) ? 0 : Long.parseLong(exampleValue);
+                } else if (fieldType == double.class || fieldType == Double.class) {
+                    value = StringUtils.isBlank(exampleValue) ? 0 : Double.parseDouble(exampleValue);
+                } else if (fieldType == boolean.class || fieldType == Boolean.class) {
+                    value = StringUtils.isNotBlank(exampleValue) && Boolean.parseBoolean(exampleValue);
+                } else if (fieldType == String.class) {
+                    value = exampleValue;
+                } else if (fieldType == Date.class) {
+                    value = DateUtils.parse(exampleValue);
+                }
+
+                if (value == null && !isBaseType(fieldType)) {
+                    declaredField.set(instance, null);
+                } else {
+                    declaredField.set(instance, value);
+                }
+            }
+        } catch (Exception e) {
+            log.error("鏁版嵁鏋勯�犲け璐ワ紝璇锋煡璇㈣缁嗕俊鎭�", e);
+            return instance;
+        }
+
+        return instance;
+    }
+
+
+    /**
+     * 鏄惁鏄熀纭�鏁版嵁绫诲瀷
+     *
+     * @param className
+     * @return
+     */
+    private static boolean isBaseType(Class<?> className) {
+        if (className.equals(java.lang.Integer.class) ||
+                className.equals(java.lang.Byte.class) ||
+                className.equals(java.lang.Long.class) ||
+                className.equals(java.lang.Double.class) ||
+                className.equals(java.lang.Float.class) ||
+                className.equals(java.lang.Character.class) ||
+                className.equals(java.lang.Short.class) ||
+                className.equals(java.lang.Boolean.class)) {
+            return true;
+        }
+        return false;
+    }
 
 
 }
+

--
Gitblit v1.9.1