一、问题背景
在导出信号矩阵时,为了对不同类型的数据针对性的设置样式,定义了一个CellWriteHandler来实现单元格样式的设置;但是在后面的测试过程当中,发现了在数据量大的情况下会报错:
根据错误信息可以看到是CellStyle的数量超过了64000
二、问题分析
根据报错定位可以看到是在createCellStyle这一行进行报错:
此时猜测在工作表中每次新建单元格样式会有一个计数的机制,并且会判断当前的数量是否超过了设定的阈值。为了验证猜想,跟踪源码(此处使用的是XSSFWorkbook中的实现方法),发现在createCellStyle方法中存在一个判断语句:
此处抛出的异常与上面的报错相吻合,在新建单元格样式时会判断当前数量是否超过了设定的阈值MAXIMUM_STYLE_ID,如果超过就会抛出异常;否则将单元格样式添加到样式集合中:
至于为什么是超过64000会抛出异常则跟阈值的设定有关:
此处EXCEL2007是个枚举量,其MaxCellStyles值便是64000:
看到这里,我们大概就可以知道问题产生的原因了,由于每次单元格写完之后调用回调函数就会新建一个单元格样式,导致了CellStyle的数量很快超出指定阈值。
三、解决方案
既然不能产生过多数量的单元格样式,我们可以利用Map分类存放不同的CellStyle,将所需的CellStyle全都存放在Map中,后续复用即可,而无需每个单元格都createCellStyle。
代码如下:
此处只需三种CellStyle。
Style复用
以上便是CellStyle数量超出阈值的解决方案。