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

写 bug 的大耳朵图图
·
  • 之前使用自定义样式解决了导出excel时,对不同单元格使用不同样式的需求,见EasyExcel——自定义单元格样式。但是最近发现,导出大量数据时,就会产生如下异常
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失败。错误的代码如下:
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();
    }
}
  • 解决此问题方法也比较简单,直接使用成员变量,不再重复创建对象。改造后的代码如下
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);
        }
    }
}

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

社区准则 博客 联系 社区 状态
主题