forked from luyan/epmet-cloud-lingshan
				
			
				 9 changed files with 8 additions and 223 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 冻结标题 |  * desc:easyExcel 冻结标题 | ||||
					Loading…
					
					
				
		Reference in new issue