Alibaba EasyExcel【踩坑日记】:使用CellWriteHandle自定义单元格样式

1,702 阅读1分钟

问题

在开发工作中,我们经常使用EasyExcel做导出的功能。其中的一种实现方式就是创建一个** CustomCellWriteHandler 类,实现 CellWriteHandler 接口:。具体方法可以查看如下:

EasyExcel使用文档

现有的导出功能就是类似于这个文档中的实现的。但,当我们需要给特殊的文本加单元格样式时,我就希望可以换个颜色来提醒用户

那么就需要用到afterCellDispose方法,对自定义样式,代码逻辑如下:

  1. 自定义handler实现CellWriteHandler
  2. 重写afterCellDispose方法,判断不同的文本类型,给不同的样式

这里就涉及到两个问题

  • 如果为每个单元格都创建一次样式,就会无限的去创建CellStyle,直到超出阈值,POI及其封装的工具基本上都是64000或者4000,最后会报一个
The maximum number of Cell Styles was exceeded. You can define up to 64000 style in a .xlsx
  • 如果复用CellStyle会有workbook不同源,样式失效的问题

解决方案

  1. 在自定义的Handler中创建一个缓存: key:样式类型 value: CellStyle
  2. 在每次setCellStyle时,不要直接set,在 Excel 中,因为多个 cell 会共用一个 style,使用style.cloneStyleFrom先复制一份
Cell cell = context.getCell();
Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
if(!myCache.containsKey(type){
	CellStyle style = workbook.createCellStyle();
	style.cloneStyleFrom(cell.getCellStyle());    
	// todo 自定义样式
	// style.set...
	cell.setCellStyle(style);
	myCache.put(type,style)	
}
//todo 取缓存
  1. 把 WriteCellData的样式清空context.getFirstCellData().setWriteCellStyle(null);

最后,以上的方式可以解决样式超过阈值的问题,但是,如果是多次导出,就可能出现二次导出时样式就失效了的问题。

解决方案: 缓存设为非静态的Map,这样每一次请求导出时,就会开始初始化缓存数据。