From f6fa17a3a817f8cc1743cb881aa9927227ed2867 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子li <15040126243@163.com>
Date: 星期二, 31 五月 2022 13:36:55 +0800
Subject: [PATCH] add 新增 easyexcel 单元格合并注解与处理器
---
ruoyi-common/src/main/java/com/ruoyi/common/annotation/CellMerge.java | 24 ++++++++
ruoyi-common/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java | 114 ++++++++++++++++++++++++++++++++++++++
2 files changed, 138 insertions(+), 0 deletions(-)
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/CellMerge.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/CellMerge.java
new file mode 100644
index 0000000..4af822e
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/CellMerge.java
@@ -0,0 +1,24 @@
+package com.ruoyi.common.annotation;
+
+import com.ruoyi.common.excel.CellMergeStrategy;
+
+import java.lang.annotation.*;
+
+/**
+ * excel 鍒楀崟鍏冩牸鍚堝苟(鍚堝苟鍒楃浉鍚岄」)
+ *
+ * 闇�鎼厤 {@link CellMergeStrategy} 绛栫暐浣跨敤
+ *
+ * @author Lion Li
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface CellMerge {
+
+ /**
+ * col index
+ */
+ int index() default -1;
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java b/ruoyi-common/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java
new file mode 100644
index 0000000..04a1bbb
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/excel/CellMergeStrategy.java
@@ -0,0 +1,114 @@
+package com.ruoyi.common.excel;
+
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import com.ruoyi.common.annotation.CellMerge;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鍒楀�奸噸澶嶅悎骞剁瓥鐣�
+ *
+ * @author Lion Li
+ */
+@AllArgsConstructor
+@Slf4j
+public class CellMergeStrategy extends AbstractMergeStrategy {
+
+ private List<?> list;
+ private boolean hasTitle;
+
+ @Override
+ protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
+ List<CellRangeAddress> cellList = handle(list, hasTitle);
+ // judge the list is not null
+ if (CollectionUtils.isNotEmpty(cellList)) {
+ // the judge is necessary
+ if (cell.getRowIndex() == 1 && cell.getColumnIndex() == 0) {
+ for (CellRangeAddress item : cellList) {
+ sheet.addMergedRegion(item);
+ }
+ }
+ }
+ }
+
+ @SneakyThrows
+ private static List<CellRangeAddress> handle(List<?> list, boolean hasTitle) {
+ List<CellRangeAddress> cellList = new ArrayList<>();
+ if (CollectionUtils.isEmpty(list)) {
+ return cellList;
+ }
+ Class<?> clazz = list.get(0).getClass();
+ Field[] fields = clazz.getDeclaredFields();
+ // 鏈夋敞瑙g殑瀛楁
+ List<Field> mergeFields = new ArrayList<>();
+ List<Integer> mergeFieldsIndex = new ArrayList<>();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ if (field.isAnnotationPresent(CellMerge.class)) {
+ CellMerge cm = field.getAnnotation(CellMerge.class);
+ mergeFields.add(field);
+ mergeFieldsIndex.add(cm.index() == -1 ? i : cm.index());
+ }
+ }
+ // 琛屽悎骞跺紑濮嬩笅鏍�
+ int rowIndex = hasTitle ? 1 : 0;
+ Map<Field, RepeatCell> map = new HashMap<>();
+ // 鐢熸垚涓や袱鍚堝苟鍗曞厓鏍�
+ for (int i = 0; i < list.size(); i++) {
+ for (int j = 0; j < mergeFields.size(); j++) {
+ Field field = mergeFields.get(j);
+ String name = field.getName();
+ String methodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+ Method readMethod = clazz.getMethod(methodName);
+ Object val = readMethod.invoke(list.get(i));
+
+ int colNum = mergeFieldsIndex.get(j);
+ if (!map.containsKey(field)) {
+ map.put(field, new RepeatCell(val, i));
+ } else {
+ RepeatCell repeatCell = map.get(field);
+ Object cellValue = repeatCell.getValue();
+ if (cellValue == null || "".equals(cellValue)) {
+ // 绌哄�艰烦杩囦笉鍚堝苟
+ continue;
+ }
+ if (cellValue != val) {
+ if (i - repeatCell.getCurrent() > 1) {
+ cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
+ }
+ map.put(field, new RepeatCell(val, i));
+ } else if (i == list.size() - 1) {
+ if (i > repeatCell.getCurrent()) {
+ cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
+ }
+ }
+ }
+ }
+ }
+ return cellList;
+ }
+
+ @Data
+ @AllArgsConstructor
+ static class RepeatCell {
+
+ private Object value;
+
+ private int current;
+
+ }
+}
--
Gitblit v1.9.3