EasyExcel解决自定义样式太多导致的 The maximum number of Cell Styles was exceeded 异常

之前使用自定义样式解决了导出excel时,对不同单元格使用不同样式的需求,但是最近发现,导出大量数据时,就会产生如下异常

1
java.lang.IllegalStateException: The maximum number of Cell Styles was exceeded. You can define up to 64000 style in a .xlsx Workbook

通过查看easyexcel在github上的issue可以发现,有很多人都出现了类似问题,原因是EasyExcel最多支持创建64000个样式对象。但是我写入的数据远远超过了64000,每次写入数据都会去创建一次样式对象,导致生成excel失败。错误的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class CustomCellWriteHandler implements CellWriteHandler {
/**
* 设置拦截器顺序,需要 > 50000
*
* @return 拦截器顺序
*/
@Override
public int order() {
return 60000;
}

@Override
public void afterCellDispose(CellWriteHandlerContext context) {
Cell cell = context.getCell();
if (BooleanUtils.isNotTrue(context.getHead())) {
Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
// 此处代码有问题,每次进入条件,都会重复创建一个XSSFCellStyle对象
XSSFCellStyle cellStyle = (XSSFCellStyle) workbook.createCellStyle();
}
}

解决此问题方法也比较简单,直接使用成员变量,不再重复创建对象。改造后的代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class CustomCellWriteHandler implements CellWriteHandler {

XSSFCellStyle cellStyle;

/**
* 设置拦截器顺序,需要 > 50000
*
* @return 拦截器顺序
*/
@Override
public int order() {
return 60000;
}

@Override
public void afterCellDispose(CellWriteHandlerContext context) {
Cell cell = context.getCell();
if (BooleanUtils.isNotTrue(context.getHead())) {
Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
if (cellStyle == null) {
cellStyle = (XSSFCellStyle) workbook.createCellStyle();
}
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
}
}
}

在创建新样式之前,判断下是不是已经有这个样式了,没有的话再创建,这样就避免了重复创建样式对象导致的异常。