文章目录
-
- [EasyExcel 文件导出 - 合并某些列值相同的行](#EasyExcel 文件导出 - 合并某些列值相同的行)
- 最终效果
- 实现思路
- 创建单元格合并的策略类
- 使用
EasyExcel 文件导出 - 合并某些列值相同的行
在数据处理与文件导出的过程中,我们常常会遇到各种特定的需求。今天,我们就来探讨一下使用 EasyExcel 进行文件导出时,如何合并某些列值相同的行,以实现更加高效和整洁的数据呈现。
最终效果
下面对2、3、4列进行单元格合并。
实现思路
判断当前行与上一行对应的值是否相等,若相等则进行合并操作。整个过程十分简洁明了。
创建单元格合并的策略类
注意:下面有使用lombok包,我的EasyExcel版本是4.0.2
。
java
public class RowSameValueMergeStrategy extends AbstractMergeStrategy {
/**
* 需要合并的列位置索引
*/
private int[] mergeColumnIndexArray;
// 记录mergeColumnIndexArray中每一列的上一行的值和索引
private Map<Integer, ValueAndIndex> lastValueMap;
/**
* 用来记录上一次的值和索引,用于判断是否需要合并
*/
@Data
@AllArgsConstructor
static class ValueAndIndex {
private String value;
private int index;
}
public RowSameValueMergeStrategy(int[] mergeColumnIndexArray) {
this.mergeColumnIndexArray = mergeColumnIndexArray;
int initialCapacity = (int) Math.ceil(mergeColumnIndexArray.length / 0.75);
lastValueMap = new HashMap<>(initialCapacity);
}
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
if (head == null) {
return;
}
if (mergeColumnIndexArray == null) {
return;
}
for (int i = 0; i < mergeColumnIndexArray.length; i++) {
int mergeIndex = mergeColumnIndexArray[i];
if (head.getColumnIndex() == mergeIndex) {
String value = cell.getStringCellValue();
int rowIndex = cell.getRowIndex();
if (lastValueMap.get(mergeIndex) == null) {
lastValueMap.put(mergeIndex, new ValueAndIndex(value, rowIndex));
}
ValueAndIndex valueAndIndex = lastValueMap.get(mergeIndex);
Integer lastRowIndex = valueAndIndex.getIndex();
String lastValue = valueAndIndex.getValue();
// 合并值相同的相邻单元格,当前单元格合并上一个单元格
if (Objects.equals(value, lastValue) && lastRowIndex != rowIndex) {
sheet.addMergedRegionUnsafe(new CellRangeAddress(
lastRowIndex, // 起始行
rowIndex, // 结束行
mergeIndex, // 起始列
mergeIndex // 结束列
));
}
lastValueMap.put(mergeIndex, new ValueAndIndex(value, rowIndex));
}
}
}
}
使用
使用registerWriteHandler
把上面的合并单元格的策略类注册即可。
java
int[] mergeColumnIndexArray = {2, 3, 4}; // 要合并的列
excelWriter = EasyExcel.write(outputStream, clazz)
.registerWriteHandler(new RowSameValueMergeStrategy(mergeColumnIndexArray))
.build();