parent
27ee418b60
commit
5088d44039
@ -1,107 +0,0 @@ |
|||||||
package com.hfkj.common.utils; |
|
||||||
|
|
||||||
import com.alibaba.excel.metadata.CellData; |
|
||||||
import com.alibaba.excel.metadata.Head; |
|
||||||
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; |
|
||||||
|
|
||||||
public class ExcelFillCellMergeStrategyUtils implements CellWriteHandler { |
|
||||||
|
|
||||||
/** |
|
||||||
* 需要合并列的下标,从0开始 |
|
||||||
*/ |
|
||||||
private int[] mergeColumnIndex; |
|
||||||
/** |
|
||||||
* 从第几行开始合并,表头下标为0 |
|
||||||
*/ |
|
||||||
private int mergeRowIndex; |
|
||||||
|
|
||||||
public ExcelFillCellMergeStrategyUtils(int mergeRowIndex, int[] mergeColumnIndex) { |
|
||||||
this.mergeRowIndex = mergeRowIndex; |
|
||||||
this.mergeColumnIndex = mergeColumnIndex; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) { |
|
||||||
//当前行
|
|
||||||
int curRowIndex = cell.getRowIndex(); |
|
||||||
//当前列
|
|
||||||
int curColIndex = cell.getColumnIndex(); |
|
||||||
|
|
||||||
if (curColIndex == 0) { |
|
||||||
Row preRow = cell.getSheet().getRow(curRowIndex - 1); |
|
||||||
if (preRow == null) { |
|
||||||
// 当获取不到上一行数据时,使用缓存sheet中数据
|
|
||||||
preRow = writeSheetHolder.getCachedSheet().getRow(curRowIndex - 1); |
|
||||||
} |
|
||||||
if (preRow != null) { |
|
||||||
if (cell.getStringCellValue().equals(preRow.getCell(0).getStringCellValue())) { |
|
||||||
for (int i = 0; i < mergeColumnIndex.length; i++) { |
|
||||||
if (curColIndex == mergeColumnIndex[i]) { |
|
||||||
mergeWithPrevRow(writeSheetHolder, cell, i, i); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
// preRow.getCell(curColIndex);
|
|
||||||
|
|
||||||
/* if (curRowIndex > mergeRowIndex) { |
|
||||||
for (int i = 0; i < mergeColumnIndex.length; i++) { |
|
||||||
if (curColIndex == mergeColumnIndex[i]) { |
|
||||||
mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
}*/ |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) { |
|
||||||
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,186 +0,0 @@ |
|||||||
package com.hfkj.common.utils; |
|
||||||
|
|
||||||
import com.alibaba.excel.metadata.Head; |
|
||||||
import com.alibaba.excel.write.merge.AbstractMergeStrategy; |
|
||||||
import org.apache.commons.lang3.StringUtils; |
|
||||||
import org.apache.poi.ss.usermodel.Cell; |
|
||||||
import org.apache.poi.ss.usermodel.Sheet; |
|
||||||
import org.apache.poi.ss.util.CellRangeAddress; |
|
||||||
|
|
||||||
import java.util.*; |
|
||||||
|
|
||||||
/** |
|
||||||
* @className: MergeCellStrategyHandler |
|
||||||
* @author: HuRui |
|
||||||
* @date: 2024/8/2 |
|
||||||
**/ |
|
||||||
public class MergeCellStrategyHandler extends AbstractMergeStrategy { |
|
||||||
/** |
|
||||||
* 相同列合并 |
|
||||||
*/ |
|
||||||
private boolean alikeColumn; |
|
||||||
|
|
||||||
/** |
|
||||||
* 相同行合并 |
|
||||||
*/ |
|
||||||
private boolean alikeRow; |
|
||||||
|
|
||||||
/** 开始进行合并的行index */ |
|
||||||
private int rowIndex; |
|
||||||
|
|
||||||
/** 跨行合并的列index */ |
|
||||||
private Set<Integer> columns; |
|
||||||
|
|
||||||
private int currentRowIndex = 0; |
|
||||||
|
|
||||||
public MergeCellStrategyHandler(boolean alikeColumn, boolean alikeRow, int rowIndex, Set<Integer> columns){ |
|
||||||
this.alikeColumn = alikeColumn; |
|
||||||
this.alikeRow = alikeRow; |
|
||||||
this.rowIndex = rowIndex; |
|
||||||
this.columns = columns; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 指定是否进行跨列合并单元格 |
|
||||||
* @param alikeColumn |
|
||||||
* @param rowIndex |
|
||||||
*/ |
|
||||||
public MergeCellStrategyHandler(boolean alikeColumn, int rowIndex){ |
|
||||||
this(alikeColumn, false, rowIndex, new HashSet<>()); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 指定是否进行跨行合并单元格 |
|
||||||
* @param alikeRow |
|
||||||
* @param rowIndex |
|
||||||
* @param columns |
|
||||||
*/ |
|
||||||
public MergeCellStrategyHandler(boolean alikeRow, int rowIndex, Set<Integer> columns){ |
|
||||||
this(false, alikeRow, rowIndex, columns); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
@Override |
|
||||||
protected void merge(Sheet sheet, Cell cell, Head head, Integer integer) { |
|
||||||
int rowId = cell.getRowIndex(); |
|
||||||
currentRowIndex = rowId == currentRowIndex ? currentRowIndex : rowId; |
|
||||||
if (rowIndex > rowId) { |
|
||||||
return; |
|
||||||
} |
|
||||||
int columnId = cell.getColumnIndex(); |
|
||||||
// 列合并
|
|
||||||
if (alikeColumn && columnId > 0) { |
|
||||||
String currentCellVal = this.getCellVal(cell); |
|
||||||
Cell preCell = cell.getRow().getCell(columnId - 1); |
|
||||||
String preCellVal = this.getCellVal(preCell); |
|
||||||
if (null != currentCellVal && null != preCellVal && StringUtils.isNotBlank(preCellVal) && StringUtils.isNotBlank(currentCellVal)) { |
|
||||||
// 当前单元格内容与上一个单元格内容相等,进行合并处理
|
|
||||||
if (preCellVal.equals(currentCellVal)) { |
|
||||||
CellRangeAddress rangeAddress = new CellRangeAddress(currentRowIndex, currentRowIndex, columnId - 1, columnId); |
|
||||||
rangeAddress = this.findExistAddress(sheet, rangeAddress, currentCellVal); |
|
||||||
if (null != rangeAddress) { |
|
||||||
sheet.addMergedRegion(rangeAddress); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
// 行合并
|
|
||||||
if (alikeRow && rowIndex < rowId && columns.contains(columnId)) { |
|
||||||
String currentCellVal = this.getCellVal(cell); |
|
||||||
Cell preCell = sheet.getRow(rowId - 1).getCell(columnId); |
|
||||||
String preCellVal = this.getCellVal(preCell); |
|
||||||
if (null != currentCellVal && null != preCellVal && !preCellVal.isBlank() && !currentCellVal.isBlank()) { |
|
||||||
// 当前单元格内容与上一行单元格内容相等,进行合并处理
|
|
||||||
if (preCellVal.equals(currentCellVal)) { |
|
||||||
//sheet.validateMergedRegions();
|
|
||||||
CellRangeAddress rangeAddress = new CellRangeAddress(currentRowIndex - 1, currentRowIndex, columnId, columnId); |
|
||||||
rangeAddress = this.findExistAddress(sheet, rangeAddress, currentCellVal); |
|
||||||
if (null != rangeAddress) { |
|
||||||
sheet.addMergedRegion(rangeAddress); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 合并单元格地址范围,发现存在相同的地址则进行扩容合并 |
|
||||||
* |
|
||||||
* @param isColumn true:跨列合并 false:跨行合并 |
|
||||||
* @param sheet |
|
||||||
* @param rangeAddress : |
|
||||||
* @param currentVal 当前单元格中的值 |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
private CellRangeAddress findExistAddress(Sheet sheet, CellRangeAddress rangeAddress, String currentVal) { |
|
||||||
List<CellRangeAddress> mergedRegions = sheet.getMergedRegions(); |
|
||||||
int existIndex = 0; |
|
||||||
Map<Integer, CellRangeAddress> existIdexMap = new LinkedHashMap<>(); |
|
||||||
if (null != mergedRegions && !mergedRegions.isEmpty()) { |
|
||||||
//验证当前合并的单元格是否存在重复(fixme 重复问题待处理!!!)
|
|
||||||
for (CellRangeAddress mergedRegion : mergedRegions) { |
|
||||||
if (mergedRegion.intersects(rangeAddress)) { |
|
||||||
existIdexMap.put(existIndex, mergedRegion); |
|
||||||
} |
|
||||||
existIndex++; |
|
||||||
} |
|
||||||
} |
|
||||||
if (existIdexMap.isEmpty()) { |
|
||||||
return rangeAddress; |
|
||||||
} |
|
||||||
List<Integer> existIndexList = new ArrayList<>(existIdexMap.size()); |
|
||||||
for (Map.Entry<Integer, CellRangeAddress> addressEntry : existIdexMap.entrySet()) { |
|
||||||
CellRangeAddress exist = addressEntry.getValue(); |
|
||||||
// 自动进行单元格合并处理
|
|
||||||
int firstRow = rangeAddress.getFirstRow(); |
|
||||||
int lastRow = rangeAddress.getLastRow(); |
|
||||||
int firstColumn = rangeAddress.getFirstColumn(); |
|
||||||
int lastColumn = rangeAddress.getLastColumn(); |
|
||||||
|
|
||||||
int firstRow1 = exist.getFirstRow(); |
|
||||||
int lastRow1 = exist.getLastRow(); |
|
||||||
int firstColumn1 = exist.getFirstColumn(); |
|
||||||
int lastColumn1 = exist.getLastColumn(); |
|
||||||
// 跨行合并 最后一列相等, 行不相等
|
|
||||||
if (lastRow > lastRow1 && lastColumn == lastColumn1) { |
|
||||||
// 检查进行跨行合并的单元格是否已经存在跨列合并
|
|
||||||
if (lastColumn > 0 && firstColumn1 != lastColumn1) { |
|
||||||
// 获取当前单元格的前一列单元格
|
|
||||||
String cellVal = this.getCellVal(sheet.getRow(lastRow).getCell(lastColumn - 1)); |
|
||||||
if (null != cellVal && cellVal.equals(currentVal)) { |
|
||||||
exist.setLastRow(lastRow); |
|
||||||
} |
|
||||||
} else { |
|
||||||
exist.setLastRow(lastRow); |
|
||||||
} |
|
||||||
rangeAddress = exist; |
|
||||||
existIndexList.add(addressEntry.getKey()); |
|
||||||
} |
|
||||||
|
|
||||||
// 跨列合并 行相等,列不相等
|
|
||||||
if (lastColumn > lastColumn1 && firstRow == firstRow1 ) { |
|
||||||
exist.setLastColumn(lastColumn); |
|
||||||
rangeAddress = exist; |
|
||||||
existIndexList.add(addressEntry.getKey()); |
|
||||||
} |
|
||||||
} |
|
||||||
// 移除已经存在且冲突的合并数据
|
|
||||||
if (existIndexList.isEmpty()) { |
|
||||||
rangeAddress = null; |
|
||||||
}else { |
|
||||||
sheet.removeMergedRegions(existIdexMap.keySet()); |
|
||||||
} |
|
||||||
return rangeAddress; |
|
||||||
} |
|
||||||
|
|
||||||
private String getCellVal(Cell cell) { |
|
||||||
String val = null; |
|
||||||
try { |
|
||||||
val = cell.getStringCellValue(); |
|
||||||
}catch (Exception e){ |
|
||||||
System.out.printf("读取单元格内容失败:行%d 列%d %n", (cell.getRowIndex() + 1), (cell.getColumnIndex() + 1)); |
|
||||||
} |
|
||||||
return val; |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue