前言
使用EasyExcel 根据单元格数值动态合并单元格
开发中遇到一个需求,需要根据Excel表格中单元格的值,进行列合并的操作
效果如下图:
一、实现思路
1、要动态合并某一行的列的话,可以使用EasyExcel库中的**AbstractHeadStyleStrategy**类来实现。
2、定义了一个**DemoStyleStrategy**类来实现样式策略。
3、判断条件是否成立,就将两个单元格合并。这样,你就可以根据需求自定义样式策略并动态合并某一行的列了。
使用 :
CellRangeAddress cellAddresses = new CellRangeAddress(rowNum, rowNum, 1, 2);
// 合并单元格执行
sheet.addMergedRegion(cellAddresses);
获取Excel表中的单元格的值,进行条件判断,确定需要合并的列,执行合并,EasyExcel写操作注册策略
二、实现步骤
1.拦截策略
自定义类拦截策略类 DemoStyleStrategy,实现AbstractMergeStrategy重写merge方法
merge方法 可以cell进行操作。(可以在方法内打印日志,会发现每个单元格写入的时候都会执行merge内的代码)
代码如下(示例):
public class DemoStyleStrategy extends AbstractMergeStrategy {
public DemoStyleStrategy() {
}
/**
* 初始化时,记录行号和内容
*/
@Override
protected void merge(Sheet sheet, Cell cell, Head head, Integer integer) {
// 1、获取单元格的数据,并且转化为字符串,strValue用于判断该行是否需要合并,避免报错数据获取异常
String strValue = null;
if (cell.getCellType() == CellType.STRING) {
strValue = cell.getStringCellValue();
} else if (cell.getCellType() == CellType.NUMERIC){
double value = cell.getNumericCellValue();
strValue = String.valueOf(value);
}
// 2、判断是否需要合并单元格 当单元格的值为”字符串6“ ,当前行的第1列和第2列进行 合并单元格操作
if (StringUtils.equals(strValue, "字符串6")) {
// 3、获取需要做合并操作的单元格在第几行
int rowNum = cell.getRowIndex();
//
/*
* 设置合并的位置
* org.apache.poi.ss.util.CellRangeAddressBase 合并单元格参数设置
* 例子:CellRangeAddress(1,1, 3, 4)
* 表示 第1行的第3和第4单元格合并为一个单元格,
*
* */
CellRangeAddress cellAddresses = new CellRangeAddress(rowNum, rowNum, 1, 2);
// 3、合并单元格执行
sheet.addMergedRegion(cellAddresses);
}
}
}
2.EasyExcel写操作
registerWriteHandler(new DemoStyleStrategy())
代码如下(示例):
@RestController
public class DownloadController {
@RequestMapping("/download")
public void downloadExcel() {
//简单写入磁盘,官网有web写入规范,自行查看
//https://easyexcel.opensource.alibaba.com/docs/2.x/quickstart/write#web%E4%B8%AD%E7%9A%84%E5%86%99
String writeFile = "D:\\filltext2.xls";
EasyExcel.write(writeFile, DemoData.class)
.sheet("qr")
.registerWriteHandler(new DemoStyleStrategy()) //关键 注册自定义拦截器(进行单元格处理)
.doWrite(this::data);
}
//案例初始化的数据 https://easyexcel.opensource.alibaba.com/docs/2.x/quickstart/write
private List<DemoData> data() {
List<DemoData> list = ListUtils.newArrayList();
for (int i = 0; i < 10; i++) {
DemoData data = new DemoData();
data.setString("字符串" + i);
data.setDate(new Date());
data.setDoubleData(0.56);
list.add(data);
}
return list;
}
}