zhou zhou
12 小时以前 6241b8acad2651564c1c668a9a54821361fbb4af
rsf-server/src/main/java/com/vincent/rsf/server/common/utils/ExcelUtil.java
@@ -33,6 +33,8 @@
@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();
@@ -136,13 +138,19 @@
    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);
        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++);
@@ -162,26 +170,62 @@
        }
        Row header = sheet.createRow(currentRowIndex++);
        for (int index = 0; index < columns.size(); index++) {
        for (int index = 0; index < effectiveColumns.size(); index++) {
            Cell headerCell = header.createCell(index);
            headerCell.setCellValue(columns.get(index).getLabel());
            headerCell.setCellValue(effectiveColumns.get(index).getLabel());
            headerCell.setCellStyle(headerStyle);
        }
        int rowIndex = currentRowIndex;
        for (Map<String, Object> rowData : rows) {
        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 < columns.size(); columnIndex++) {
                Object value = getRowValue(rowData, columns.get(columnIndex).getSource());
            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 < columns.size(); columnIndex++) {
        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) {
@@ -301,13 +345,26 @@
        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() {
@@ -329,6 +386,41 @@
        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);
        }
    }
    /**