问题描述
之前写了一个导出excel的功能,但是今天在使用时,由于数据量比较大导致报错 报错如下:
Caused by: java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook
问题原因
我们通过 CellStyle contextstyle = wb.createCellStyle();来获取单元格样式,但是将这个方法放到for循环里时,创建的单元格样式超过了4000个就会报错。
解决方法
思考了一下,基本上在导出excel时单元格的样式肯定不会很多,所以我们在自定义单元格样式的时候无需每次去创建一个单元格样式,我们可以创建一个缓存,将之前没有出现过的样式放到缓存里,在为下一个单元格定义样式的时候首先从缓存里查一下,如果没有再创建新的样式。
我们将代码用键值对的方式放到map里作为缓存,先用key到map里匹配没有的话再创建新的。
修改前的代码:
private CellStyle getCellDataStyle(CellStyle contextstyle,DataFormat df, String dataType) {
if (DATA_TYPE_NUM.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("#,##0"));
}else if (DATA_TYPE_MONEY.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("#,##0.00"));
}else if (DATA_TYPE_PER.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("0.00%"));
}else if (DATA_TYPE_DATE.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("yyyy-MM-dd"));
}else if (DATA_TYPE_TIME.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("yyyy-MM-dd hh:mm:ss"));
}
return contextstyle;
}
```
修改后的代码:
private CellStyle getCellDataStyleFromCache(DataFormat df, String dataType,Map<String,CellStyle> contextstyleCache,Workbook wb) {
if(contextstyleCache.containsKey(dataType)){
return contextstyleCache.get(dataType);
}else{
CellStyle contextstyle = wb.createCellStyle();
if (DATA_TYPE_NUM.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("#,##0.00"));
}else if (DATA_TYPE_MONEY.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("#,##0.00"));
}else if (DATA_TYPE_PER.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("0.00%"));
}else if (DATA_TYPE_DATE.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("yyyy-MM-dd"));
}else if (DATA_TYPE_TIME.equals(dataType)) {
contextstyle.setDataFormat(df.getFormat("yyyy-MM-dd hh:mm:ss"));
}
contextstyleCache.put(dataType,contextstyle);
return contextstyle;
}
}