From 6e5ff559023efd2d24fdca2adcb7268d06420e46 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期二, 24 三月 2026 15:38:34 +0800
Subject: [PATCH] #打印+导出

---
 rsf-server/src/main/java/com/vincent/rsf/server/common/utils/ExcelUtil.java |  425 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 359 insertions(+), 66 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..1c12cc5 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,12 +13,14 @@
 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.Method;
 import java.lang.reflect.Modifier;
 import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
@@ -48,7 +47,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);
@@ -134,6 +133,262 @@
         return workbook;
     }
 
+    public static Workbook create(List<?> list, List<ColumnMeta> columns) {
+        return create(list, columns, null);
+    }
+
+    public static Workbook create(List<?> list, List<ColumnMeta> columns, ReportMeta reportMeta) {
+        XSSFWorkbook workbook = new XSSFWorkbook();
+        Sheet sheet = workbook.createSheet("export");
+        List<ColumnMeta> safeColumns = columns == null ? Collections.emptyList() : columns;
+        int sheetColumnCount = safeColumns.size() + 1;
+        configureA4PrintLayout(sheet);
+
+        CellStyle titleStyle = createTitleStyle(workbook);
+        CellStyle metaLabelStyle = createMetaLabelStyle(workbook);
+        CellStyle metaValueStyle = createMetaValueStyle(workbook);
+        CellStyle headerStyle = createHeaderStyle(workbook);
+        CellStyle bodyStyle = createBodyStyle(workbook);
+        CellStyle serialStyle = createCenteredBodyStyle(workbook);
+
+        int rowIndex = 0;
+        if (reportMeta != null) {
+            Row titleRow = sheet.createRow(rowIndex++);
+            titleRow.setHeightInPoints(28);
+            Cell titleCell = titleRow.createCell(0);
+            titleCell.setCellValue(StringUtils.defaultIfBlank(reportMeta.getTitle(), "鎶ヨ〃"));
+            titleCell.setCellStyle(titleStyle);
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, Math.max(0, sheetColumnCount - 1)));
+
+            Row metaRow = sheet.createRow(rowIndex++);
+            int metaCol = 0;
+            metaCol = writeMetaPair(metaRow, metaCol, "鎶ヨ〃鏃ユ湡", reportMeta.getReportDate(), metaLabelStyle, metaValueStyle);
+            writeMetaPair(metaRow, metaCol, "鎵撳嵃浜�", reportMeta.getPrintedBy(), metaLabelStyle, metaValueStyle);
+
+            rowIndex++;
+        }
+
+        int headerRowIndex = rowIndex;
+        Row header = sheet.createRow(rowIndex++);
+        Cell serialHeaderCell = header.createCell(0);
+        serialHeaderCell.setCellValue("搴忓彿");
+        serialHeaderCell.setCellStyle(headerStyle);
+
+        for (int i = 0; i < safeColumns.size(); i++) {
+            ColumnMeta column = safeColumns.get(i);
+            Cell headerCell = header.createCell(i + 1);
+            headerCell.setCellValue(
+                    StringUtils.isBlank(column.getLabel()) ? column.getSource() : column.getLabel()
+            );
+            headerCell.setCellStyle(headerStyle);
+        }
+
+        if (list != null) {
+            int serialNo = 1;
+            for (Object rowObj : list) {
+                Row row = sheet.createRow(rowIndex++);
+                Cell serialCell = row.createCell(0);
+                serialCell.setCellValue(String.format("%03d", serialNo++));
+                serialCell.setCellStyle(serialStyle);
+                for (int i = 0; i < safeColumns.size(); i++) {
+                    Object value = getColumnValue(rowObj, safeColumns.get(i).getSource());
+                    Cell cell = row.createCell(i + 1);
+                    cell.setCellStyle(bodyStyle);
+                    if (value != null) {
+                        if (value instanceof Date) {
+                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                            cell.setCellValue(sdf.format((Date) value));
+                        } else {
+                            cell.setCellValue(value.toString());
+                        }
+                    }
+                }
+            }
+        }
+
+        for (int i = 0; i <= safeColumns.size(); i++) {
+            sheet.autoSizeColumn(i);
+            sheet.setColumnWidth(i, Math.min(sheet.getColumnWidth(i) + 1024, 12000));
+        }
+
+        sheet.setRepeatingRows(CellRangeAddress.valueOf((headerRowIndex + 1) + ":" + (headerRowIndex + 1)));
+
+        return workbook;
+    }
+
+    private static void configureA4PrintLayout(Sheet sheet) {
+        sheet.setAutobreaks(true);
+        sheet.setFitToPage(true);
+        sheet.setHorizontallyCenter(true);
+        sheet.setDisplayGridlines(false);
+
+        PrintSetup printSetup = sheet.getPrintSetup();
+        printSetup.setPaperSize(PrintSetup.A4_PAPERSIZE);
+        printSetup.setLandscape(true);
+        printSetup.setFitWidth((short) 1);
+        printSetup.setFitHeight((short) 0);
+
+        sheet.setMargin(Sheet.LeftMargin, 0.3);
+        sheet.setMargin(Sheet.RightMargin, 0.3);
+        sheet.setMargin(Sheet.TopMargin, 0.4);
+        sheet.setMargin(Sheet.BottomMargin, 0.4);
+    }
+
+    private static int writeMetaPair(Row row, int startCol, String label, String value, CellStyle labelStyle, CellStyle valueStyle) {
+        Cell labelCell = row.createCell(startCol);
+        labelCell.setCellValue(label + "锛�");
+        labelCell.setCellStyle(labelStyle);
+
+        Cell valueCell = row.createCell(startCol + 1);
+        valueCell.setCellValue(StringUtils.defaultString(value));
+        valueCell.setCellStyle(valueStyle);
+        return startCol + 2;
+    }
+
+    private static CellStyle createTitleStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        style.setBorderBottom(BorderStyle.THICK);
+        Font font = workbook.createFont();
+        font.setBold(true);
+        font.setFontHeightInPoints((short) 16);
+        style.setFont(font);
+        return style;
+    }
+
+    private static CellStyle createMetaLabelStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+        style.setAlignment(HorizontalAlignment.LEFT);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        style.setBorderBottom(BorderStyle.THIN);
+        Font font = workbook.createFont();
+        font.setBold(true);
+        style.setFont(font);
+        return style;
+    }
+
+    private static CellStyle createMetaValueStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+        style.setAlignment(HorizontalAlignment.LEFT);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        style.setBorderBottom(BorderStyle.THIN);
+        return style;
+    }
+
+    private static CellStyle createHeaderStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
+        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+        Font font = workbook.createFont();
+        font.setBold(true);
+        style.setFont(font);
+        return style;
+    }
+
+    private static CellStyle createBodyStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+        style.setAlignment(HorizontalAlignment.LEFT);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        return style;
+    }
+
+    private static CellStyle createCenteredBodyStyle(Workbook workbook) {
+        CellStyle style = workbook.createCellStyle();
+        style.setAlignment(HorizontalAlignment.CENTER);
+        style.setVerticalAlignment(VerticalAlignment.CENTER);
+        return style;
+    }
+
+    private static Object getColumnValue(Object rowObj, String source) {
+        if (rowObj == null || StringUtils.isBlank(source)) {
+            return null;
+        }
+
+        if (rowObj instanceof Map) {
+            return getValueFromMap((Map<?, ?>) rowObj, source);
+        }
+
+        String extendFieldKey = extractExtendFieldKey(source);
+        if (extendFieldKey != null) {
+            Object extendFields = getBeanValue(rowObj, "extendFields");
+            if (extendFields instanceof Map) {
+                return ((Map<?, ?>) extendFields).get(extendFieldKey);
+            }
+            return null;
+        }
+
+        return getBeanValue(rowObj, source);
+    }
+
+    private static Object getValueFromMap(Map<?, ?> rowObj, String source) {
+        String extendFieldKey = extractExtendFieldKey(source);
+        if (extendFieldKey != null) {
+            Object extendFields = rowObj.get("extendFields");
+            if (extendFields instanceof Map) {
+                return ((Map<?, ?>) extendFields).get(extendFieldKey);
+            }
+            return null;
+        }
+        return rowObj.get(source);
+    }
+
+    private static String extractExtendFieldKey(String source) {
+        if (source == null || !source.startsWith("extendFields.[")) {
+            return null;
+        }
+        int startIndex = source.indexOf('[');
+        int endIndex = source.indexOf(']');
+        if (startIndex < 0 || endIndex <= startIndex) {
+            return null;
+        }
+        return source.substring(startIndex + 1, endIndex);
+    }
+
+    private static Object getBeanValue(Object rowObj, String source) {
+        Object value = invokeGetter(rowObj, source);
+        if (value != null) {
+            return value;
+        }
+        Field field = findField(rowObj.getClass(), source);
+        if (field == null) {
+            return null;
+        }
+        try {
+            field.setAccessible(true);
+            return field.get(rowObj);
+        } catch (IllegalAccessException ignore) {
+            return null;
+        }
+    }
+
+    private static Object invokeGetter(Object target, String source) {
+        String suffix = Character.toUpperCase(source.charAt(0)) + source.substring(1);
+        String[] methodNames = new String[] { "get" + suffix, "is" + suffix };
+        for (String methodName : methodNames) {
+            try {
+                Method method = target.getClass().getMethod(methodName);
+                return method.invoke(target);
+            } catch (Exception ignore) {
+            }
+        }
+        return null;
+    }
+
+    private static Field findField(Class<?> clazz, String source) {
+        Class<?> current = clazz;
+        while (current != null && current != Object.class) {
+            try {
+                return current.getDeclaredField(source);
+            } catch (NoSuchFieldException ignore) {
+                current = current.getSuperclass();
+            }
+        }
+        return null;
+    }
+
     /**
      * 娣诲姞瀵煎叆excel閰嶇疆鍙傛暟
      * 娉細榛樿閰嶇疆鍙弧瓒冲綋鍓嶉渶姹�
@@ -143,69 +398,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;
     }
 
     /**
@@ -285,5 +481,102 @@
         return false;
     }
 
+    public static class ColumnMeta {
+        private String key;
+        private String source;
+        private String label;
+        private Boolean extendField;
+
+        public String getKey() {
+            return key;
+        }
+
+        public ColumnMeta setKey(String key) {
+            this.key = key;
+            return this;
+        }
+
+        public String getSource() {
+            return source;
+        }
+
+        public ColumnMeta setSource(String source) {
+            this.source = source;
+            return this;
+        }
+
+        public String getLabel() {
+            return label;
+        }
+
+        public ColumnMeta setLabel(String label) {
+            this.label = label;
+            return this;
+        }
+
+        public Boolean getExtendField() {
+            return extendField;
+        }
+
+        public ColumnMeta setExtendField(Boolean extendField) {
+            this.extendField = extendField;
+            return this;
+        }
+    }
+
+    public static class ReportMeta {
+        private String title;
+        private String companyName;
+        private String printedBy;
+        private String reportDate;
+        private String reportDateValue;
+
+        public String getTitle() {
+            return title;
+        }
+
+        public ReportMeta setTitle(String title) {
+            this.title = title;
+            return this;
+        }
+
+        public String getCompanyName() {
+            return companyName;
+        }
+
+        public ReportMeta setCompanyName(String companyName) {
+            this.companyName = companyName;
+            return this;
+        }
+
+        public String getReportDate() {
+            return reportDate;
+        }
+
+        public ReportMeta setReportDate(String reportDate) {
+            this.reportDate = reportDate;
+            return this;
+        }
+
+        public String getReportDateValue() {
+            return reportDateValue;
+        }
+
+        public ReportMeta setReportDateValue(String reportDateValue) {
+            this.reportDateValue = reportDateValue;
+            return this;
+        }
+
+        public String getPrintedBy() {
+            return printedBy;
+        }
+
+        public ReportMeta setPrintedBy(String printedBy) {
+            this.printedBy = printedBy;
+            return this;
+        }
+    }
+
 
 }
+

--
Gitblit v1.9.1