
本文主要是对excel文档中的所有sheet页中,将相同列的相同单元格值进行合并(按列合并),使用Java语言结合easyexcel组件实现。
监听器
采用com.alibaba.excel.write.handler.AbstractWorkbookWriteHandler
进行操作
maven版本依赖
xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
</dependency>
java
import com.alibaba.excel.write.handler.AbstractWorkbookWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.google.common.base.Objects;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
/**
* 按列进行合并单元格
*/
public class ExcelColumnMergeListener extends AbstractWorkbookWriteHandler {
@Override
public void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) {
int numberOfSheets = writeWorkbookHolder.getWorkbook().getNumberOfSheets();
for(int s = 0; s < numberOfSheets; s++) {
Sheet sheet = writeWorkbookHolder.getWorkbook().getSheetAt(s);
int firstRowNum = sheet.getFirstRowNum();
int lastRowNum = sheet.getLastRowNum();
Row row = sheet.getRow(firstRowNum);
short firstCellNum = row.getFirstCellNum();
short lastCellNum = row.getLastCellNum();
for(int i = firstCellNum;i < lastCellNum; i++) {
String value = null;
int startRow = firstRowNum;
int endRow = firstRowNum;
boolean findSame = false;
for (int j = firstRowNum;j <= lastRowNum; j++) {
sheet.getRow(j).getCell(i).getCellTypeEnum();
String stringCellValue = sheet.getRow(j).getCell(i).getStringCellValue();
if(Objects.equal(value, stringCellValue)) {
endRow = j;
findSame = true;
} else {
if(findSame) {
// 说明之前是找到了相同的,则添加合并
sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, i, i));
findSame = false;
}
// 不相等
value = stringCellValue;
startRow = j;
endRow = j;
}
}
if(findSame) {
// 说明之前是找到了相同的,则添加合并
sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, i, i));
}
}
}
}
}
测试
java
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class EasyExcelMergeTest {
public static void main(String[] args) {
List<ValvePoint> vps2 = new ArrayList<>();
ValvePoint vp21 = new ValvePoint();
vp21.setName("PC");
vp21.setDay("2025-3-1");
vp21.setStatus("DOING");
vps2.add(vp21);
vps2.add(vp21);
ValvePoint vp22 = new ValvePoint();
vp22.setName("OTS1");
vp22.setDay("2025-4-1");
vp22.setStatus("TODO");
vps2.add(vp22);
ValvePoint vp23 = new ValvePoint();
vp23.setName("OTS2");
vp23.setDay("2025-4-1");
vp23.setStatus("TODO");
vps2.add(vp23);
ValvePoint vp24 = new ValvePoint();
vp24.setName("OTS3");
vp24.setDay("2025-6-1");
vp24.setStatus("2025-6-1");
vps2.add(vp24);
EasyExcel.write("D:\\test\\test1.xlsx", ValvePoint.class).sheet("测试")
.doWrite(vps2);
EasyExcel.write("D:\\test\\test1-merge.xlsx", ValvePoint.class).sheet("测试")
.registerWriteHandler(new ExcelColumnMergeListener())
.doWrite(vps2);
}
@Data
public static class ValvePoint implements Serializable {
@ExcelProperty(value = "名称")
private String name;
@ExcelProperty(value = "日期")
private String day;
@ExcelProperty(value = "状态")
private String status;
}
}
效果
合并前:
合并后: