13 changed files with 121 additions and 265 deletions
			
			
		@ -1,213 +0,0 @@ | 
				
			|||
package com.epmet.commons.tools.utils.poi.excel.handler; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * desc: | 
				
			|||
 * | 
				
			|||
 * @author: LiuJanJun | 
				
			|||
 * @date: 2022/4/26 1:36 下午 | 
				
			|||
 * @version: 1.0 | 
				
			|||
 */ | 
				
			|||
 | 
				
			|||
import com.alibaba.excel.enums.CellDataTypeEnum; | 
				
			|||
import com.alibaba.excel.metadata.Head; | 
				
			|||
import com.alibaba.excel.metadata.data.CellData; | 
				
			|||
import com.alibaba.excel.metadata.data.WriteCellData; | 
				
			|||
import com.alibaba.excel.write.handler.CellWriteHandler; | 
				
			|||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; | 
				
			|||
import com.alibaba.excel.write.metadata.holder.WriteTableHolder; | 
				
			|||
import org.apache.poi.ss.usermodel.Cell; | 
				
			|||
import org.apache.poi.ss.usermodel.CellType; | 
				
			|||
import org.apache.poi.ss.usermodel.Row; | 
				
			|||
import org.apache.poi.ss.usermodel.Sheet; | 
				
			|||
import org.apache.poi.ss.util.CellRangeAddress; | 
				
			|||
 | 
				
			|||
import java.util.List; | 
				
			|||
import java.util.Objects; | 
				
			|||
import java.util.stream.IntStream; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * 相同值合并策略 | 
				
			|||
 */ | 
				
			|||
 | 
				
			|||
public class ExcelMergeStrategy implements CellWriteHandler { | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 合并起始行 | 
				
			|||
     */ | 
				
			|||
 | 
				
			|||
    private int mergeRowIndex; | 
				
			|||
    /** | 
				
			|||
     * 多少行合并一次 | 
				
			|||
     */ | 
				
			|||
 | 
				
			|||
    private int eachRow; | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 合并字段的下标 | 
				
			|||
     */ | 
				
			|||
 | 
				
			|||
    private int[] mergeColumnIndex; | 
				
			|||
 | 
				
			|||
    public ExcelMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex, int eachRow) { | 
				
			|||
 | 
				
			|||
        if (mergeRowIndex < 0) { | 
				
			|||
 | 
				
			|||
            throw new IllegalArgumentException("mergeRowIndex must be greater than 0"); | 
				
			|||
 | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        if (eachRow < 0) { | 
				
			|||
 | 
				
			|||
            throw new IllegalArgumentException("eachRow must be greater than 0"); | 
				
			|||
 | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
        this.mergeRowIndex = mergeRowIndex; | 
				
			|||
 | 
				
			|||
        this.mergeColumnIndex = mergeColumnIndex; | 
				
			|||
 | 
				
			|||
        this.eachRow = eachRow; | 
				
			|||
 | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    @Override | 
				
			|||
 | 
				
			|||
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    @Override | 
				
			|||
 | 
				
			|||
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
   // @Override
 | 
				
			|||
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { | 
				
			|||
 | 
				
			|||
        int curRowIndex = cell.getRowIndex(); | 
				
			|||
 | 
				
			|||
//当前列
 | 
				
			|||
 | 
				
			|||
        int curColIndex = cell.getColumnIndex(); | 
				
			|||
 | 
				
			|||
//合并条件:
 | 
				
			|||
 | 
				
			|||
//1.当前行>合并起始行,默认标题行(0)不参加合并
 | 
				
			|||
 | 
				
			|||
//2.间隔行(eachRow)的上下两条不参加合并
 | 
				
			|||
 | 
				
			|||
//2.1间隔行(eachRow)==0时,不设置间隔
 | 
				
			|||
 | 
				
			|||
        if (isMerge(curRowIndex)) { | 
				
			|||
 | 
				
			|||
            IntStream.range(0, mergeColumnIndex.length).anyMatch(i -> { | 
				
			|||
 | 
				
			|||
                if (curColIndex == mergeColumnIndex[i]) { | 
				
			|||
 | 
				
			|||
                    mergeWithPrevRow(writeSheetHolder, cellData, cell, curRowIndex, curColIndex); | 
				
			|||
 | 
				
			|||
                    return true; | 
				
			|||
 | 
				
			|||
                } | 
				
			|||
 | 
				
			|||
                return false; | 
				
			|||
 | 
				
			|||
            }); | 
				
			|||
 | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    @Override | 
				
			|||
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    /** | 
				
			|||
     * 判断是否合并 | 
				
			|||
     * <p> | 
				
			|||
     * 1.当前位置必须大于开始位置:curRowIndex > mergeRowIndex | 
				
			|||
     * <p> | 
				
			|||
     * 2.根据eachRow 判断数据分割的间隔 | 
				
			|||
     * <p> | 
				
			|||
     * 2.1如果根据eachRow=0,默认不合并 | 
				
			|||
     * <p> | 
				
			|||
     * 2.2如果1如果根据eachRow>0,分割后的第一条数据不会与之前的合并:(curRowIndex-mergeRowIndex)%eachRow==0 | 
				
			|||
     * | 
				
			|||
     * @return | 
				
			|||
     */ | 
				
			|||
 | 
				
			|||
    private boolean isMerge(Integer curRowIndex) { | 
				
			|||
        if ((curRowIndex > mergeRowIndex) && eachRow > 0) { | 
				
			|||
 | 
				
			|||
            if ((curRowIndex - mergeRowIndex) % eachRow == 0) { | 
				
			|||
 | 
				
			|||
                return false; | 
				
			|||
 | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
            return true; | 
				
			|||
 | 
				
			|||
        } | 
				
			|||
        return false; | 
				
			|||
 | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, CellData cellData, Cell cell, int curRowIndex, int curColIndex) { | 
				
			|||
 | 
				
			|||
//获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并
 | 
				
			|||
 | 
				
			|||
        Object curData = cellData.getType() == CellDataTypeEnum.STRING ? cellData.getStringValue() : cellData.getNumberValue(); | 
				
			|||
 | 
				
			|||
        Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex); | 
				
			|||
 | 
				
			|||
        Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : | 
				
			|||
 | 
				
			|||
                preCell.getNumericCellValue(); | 
				
			|||
 | 
				
			|||
// 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行
 | 
				
			|||
 | 
				
			|||
        if (Objects.equals(curData, preData)) { | 
				
			|||
 | 
				
			|||
            Sheet sheet = writeSheetHolder.getSheet(); | 
				
			|||
 | 
				
			|||
            List<CellRangeAddress> mergeRegions = sheet.getMergedRegions(); | 
				
			|||
 | 
				
			|||
            boolean isMerged = false; | 
				
			|||
 | 
				
			|||
            for (int i = 0; i < mergeRegions.size() && !isMerged; i++) { | 
				
			|||
 | 
				
			|||
                CellRangeAddress cellRangeAddr = mergeRegions.get(i); | 
				
			|||
 | 
				
			|||
// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
 | 
				
			|||
 | 
				
			|||
                if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) { | 
				
			|||
 | 
				
			|||
                    sheet.removeMergedRegion(i); | 
				
			|||
 | 
				
			|||
                    cellRangeAddr.setLastRow(curRowIndex); | 
				
			|||
 | 
				
			|||
                    sheet.addMergedRegion(cellRangeAddr); | 
				
			|||
 | 
				
			|||
                    isMerged = true; | 
				
			|||
 | 
				
			|||
                } | 
				
			|||
 | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
// 若上一个单元格未被合并,则新增合并单元
 | 
				
			|||
 | 
				
			|||
            if (!isMerged) { | 
				
			|||
 | 
				
			|||
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, | 
				
			|||
 | 
				
			|||
                        curColIndex); | 
				
			|||
 | 
				
			|||
                sheet.addMergedRegion(cellRangeAddress); | 
				
			|||
 | 
				
			|||
            } | 
				
			|||
 | 
				
			|||
        } | 
				
			|||
 | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
} | 
				
			|||
 | 
				
			|||
@ -1,4 +1,4 @@ | 
				
			|||
package com.epmet.commons.tools.utils.poi.excel; | 
				
			|||
package com.epmet.commons.tools.utils.poi.excel.handler; | 
				
			|||
 | 
				
			|||
/** | 
				
			|||
 * desc:easyExcel 冻结标题 | 
				
			|||
					Loading…
					
					
				
		Reference in new issue