|
|
@@ -0,0 +1,112 @@
|
|
|
+package com.ydtech.modules.inv.utils.excel;
|
|
|
+
|
|
|
+import com.alibaba.excel.metadata.Head;
|
|
|
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
|
|
|
+import org.apache.poi.ss.usermodel.Cell;
|
|
|
+import org.apache.poi.ss.usermodel.Row;
|
|
|
+import org.apache.poi.ss.usermodel.Sheet;
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+public class CustomMultiFieldMergeStrategy extends AbstractMergeStrategy {
|
|
|
+
|
|
|
+ // 存储需要合并的列索引列表
|
|
|
+ private List<Integer> mergeColIndexList;
|
|
|
+ // 用于存储合并区域的列表
|
|
|
+ private List<CellRangeAddress> mergeRegions = new ArrayList<>();
|
|
|
+
|
|
|
+ public CustomMultiFieldMergeStrategy(List<Integer> mergeColIndexList) {
|
|
|
+ this.mergeColIndexList = mergeColIndexList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
|
|
|
+ // 跳过第一行(标题行)和第一行数据
|
|
|
+ if (relativeRowIndex == 0 ) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ int rowIndex = cell.getRowIndex();
|
|
|
+ if (rowIndex >= relativeRowIndex && mergeColIndexList.contains(cell.getColumnIndex())) {
|
|
|
+ // 获取当前行所有单元格的值(考虑多种数据类型)
|
|
|
+ String currentRowValues = getRowValues(sheet, rowIndex);
|
|
|
+ // 获取上一行所有单元格的值(考虑多种数据类型)
|
|
|
+ String previousRowValues = getRowValues(sheet, rowIndex - 1);
|
|
|
+
|
|
|
+ // 获取当前列当前行的值(字符串类型)
|
|
|
+ String currentCellValue = getCellValueAsString(cell);
|
|
|
+ // 获取当前列上一行的值(字符串类型)
|
|
|
+ Cell preCell = sheet.getRow(rowIndex - 1).getCell(cell.getColumnIndex());
|
|
|
+ String previousCellValue = getCellValueAsString(preCell);
|
|
|
+
|
|
|
+ // 判断当前列的值以及整行的值是否都相等
|
|
|
+ if (currentCellValue.equals(previousCellValue) && currentRowValues.equals(previousRowValues)) {
|
|
|
+ int firstRow = rowIndex - 1;
|
|
|
+ int lastRow = rowIndex;
|
|
|
+ int firstCol = cell.getColumnIndex();
|
|
|
+ int lastCol = cell.getColumnIndex();
|
|
|
+ CellRangeAddress cellRangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
|
|
|
+
|
|
|
+ // 检查新的合并区域是否与已有的合并区域重叠,若不重叠则添加合并区域并执行合并操作
|
|
|
+ if (!isOverlappedWithExistingRegions(cellRangeAddress, mergeRegions)) {
|
|
|
+ mergeRegions.add(cellRangeAddress);
|
|
|
+ sheet.addMergedRegion(cellRangeAddress);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isOverlappedWithExistingRegions(CellRangeAddress newRegion, List<CellRangeAddress> existingRegions) {
|
|
|
+ for (CellRangeAddress existingRegion : existingRegions) {
|
|
|
+ // 判断行是否有重叠
|
|
|
+ boolean rowOverlap = (newRegion.getFirstRow() <= existingRegion.getLastRow() && newRegion.getLastRow() >= existingRegion.getFirstRow());
|
|
|
+ // 判断列是否有重叠
|
|
|
+ boolean colOverlap = (newRegion.getFirstColumn() <= existingRegion.getLastColumn() && newRegion.getLastColumn() >= existingRegion.getFirstColumn());
|
|
|
+ if (rowOverlap && colOverlap) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getRowValues(Sheet sheet, int rowIndex) {
|
|
|
+ String rowValues = "";
|
|
|
+ Row row = sheet.getRow(rowIndex);
|
|
|
+ if (row!= null) {
|
|
|
+ for (Cell cell : row) {
|
|
|
+ if(cell.getColumnIndex() == 0){
|
|
|
+ rowValues += getCellValueAsString(cell);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return rowValues;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getCellValueAsString(Cell cell) {
|
|
|
+ if (cell == null) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ switch (cell.getCellType()) {
|
|
|
+ case STRING:
|
|
|
+ return cell.getStringCellValue();
|
|
|
+ case NUMERIC:
|
|
|
+ return String.valueOf(cell.getNumericCellValue());
|
|
|
+ case BOOLEAN:
|
|
|
+ return String.valueOf(cell.getBooleanCellValue());
|
|
|
+ case FORMULA:
|
|
|
+ try {
|
|
|
+ return cell.getStringCellValue();
|
|
|
+ } catch (Exception e) {
|
|
|
+ return String.valueOf(cell.getNumericCellValue());
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<CellRangeAddress> getMergeRegions() {
|
|
|
+ return mergeRegions;
|
|
|
+ }
|
|
|
+}
|