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 | 314 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 304 insertions(+), 10 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 43131e0..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
@@ -14,20 +14,28 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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);
@@ -44,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);
@@ -111,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++;
}
}
@@ -128,6 +129,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);
+ }
}
/**
@@ -224,3 +517,4 @@
}
+
--
Gitblit v1.9.1