Caused by: java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook
最近在写excel导出功能,要求按照不同的成品进行sheet分页。需要按照将第一个模板复制多份
需要循环多次复制sheet,因为样式库只能存放4000种样式,对于单张sheet复制肯定是足够了,
对于多张的sheet导出,会引起样式库容量不足报错!
根据传入的size决定生成sheet的数量:
// 创建新的excel
HSSFWorkbook wbCreat = new HSSFWorkbook();
HSSFSheet sheet = wb.getSheetAt(0);
//创建对应成品品号数量的sheet数
for(int i = 0 ; i < size ; i++){
HSSFSheet sheetCreat = wbCreat.createSheet("sheet"+i);
copySheet(wb,wbCreat, sheet, sheetCreat, true );
}
报错的代码:因为每进行一个单元格的复制,就会创建一个新的样式,4000格以内不存在问题。
newstyle=wbCreat.createCellStyle();
copyCellStyle(srcCell.getCellStyle(), newstyle);
//样式
distCell.setCellStyle(newstyle);
看了很多解决方案,大部分是让wb.CreatCellStyle()方法放到循环外边,我试了一下,对于单张sheet的复制可行
对于多张sheet复制,又会报一个异常,我没有保存,大概意思就是:你是否要将一张sheet中的样式作用于另一张sheet中。
那么说我的解决方案:新建一个样式库,存储已有的单元格样式,在新建之前判断样式是否存在就行了,亲测有效
//设置样式库缓存池
public static ArrayList<HSSFCellStyle> styleList = new ArrayList<HSSFCellStyle>();
/**
* 判断样式是否已经存在于样式库当中
* @param style
* @return 如果有则返回
*/
public static HSSFCellStyle getStyleIfExists (HSSFCellStyle style , HSSFCell srcCell) {
for( HSSFCellStyle existStyle : styleList){
if(
existStyle.getBorderBottom()==style.getBorderBottom()
&&existStyle.getBorderLeft()==style.getBorderLeft()
&&existStyle.getBorderRight()==style.getBorderRight()
&&existStyle.getBorderTop()==style.getBorderTop()
&&existStyle.getTopBorderColor()==style.getTopBorderColor()
&&existStyle.getBottomBorderColor()==style.getBottomBorderColor()
&&existStyle.getRightBorderColor()==style.getRightBorderColor()
&&existStyle.getLeftBorderColor()==style.getLeftBorderColor()
&&existStyle.getFillBackgroundColor()==style.getFillBackgroundColor()
&&existStyle.getFillForegroundColor()==style.getFillForegroundColor()
&&existStyle.getFillPattern()==style.getFillPattern()
&&existStyle.getHidden()==style.getHidden()
&&existStyle.getIndention()==style.getIndention()
&&existStyle.getLocked()==style.getLocked()
&&existStyle.getRotation()==style.getRotation()
&&existStyle.getVerticalAlignment()==style.getVerticalAlignment()
&&existStyle.getWrapText()==style.getWrapText()
&&existStyle.getAlignment()==style.getAlignment()
){
return existStyle;
}
}
return null;
}
思路:先获取想要赋值的单元格样式与样式库中的样式进行比对,如果都相同则返回样式库中已经存在的样式(避免一次创建),如果没有相同的就创建一个新的
/**
* 复制单元格
*
* @param srcCell
* @param distCell
* @param copyValueFlag
* true则连同cell的内容一起复制
*/
public static void copyCell(HSSFWorkbook wb, HSSFWorkbook wbCreat ,HSSFCell srcCell, HSSFCell distCell,
boolean copyValueFlag) {
//创建样式并赋值
HSSFCellStyle newstyle = getStyleIfExists(srcCell.getCellStyle(),wb,wbCreat,srcCell);
if(newstyle==null){
newstyle=wbCreat.createCellStyle();
copyCellStyle(srcCell.getCellStyle(), newstyle);
//创建字体样式并赋值
HSSFFont fonts = wbCreat.createFont();
fonts.setFontName("微软雅黑");
newstyle.setFont(fonts);
styleList.add(newstyle);
}
//样式
distCell.setCellStyle(newstyle);
//评论
if (srcCell.getCellComment() != null) {
distCell.setCellComment(srcCell.getCellComment());
}
// 不同数据类型处理
int srcCellType = srcCell.getCellType();
distCell.setCellType(srcCellType);
if (copyValueFlag) {
if (srcCellType == HSSFCell.CELL_TYPE_NUMERIC) {
if (HSSFDateUtil.isCellDateFormatted(srcCell)) {
distCell.setCellValue(srcCell.getDateCellValue());
} else {
distCell.setCellValue(srcCell.getNumericCellValue());
}
} else if (srcCellType == HSSFCell.CELL_TYPE_STRING) {
distCell.setCellValue(srcCell.getRichStringCellValue());
} else if (srcCellType == HSSFCell.CELL_TYPE_BLANK) {
// nothing21
} else if (srcCellType == HSSFCell.CELL_TYPE_BOOLEAN) {
distCell.setCellValue(srcCell.getBooleanCellValue());
} else if (srcCellType == HSSFCell.CELL_TYPE_ERROR) {
distCell.setCellErrorValue(srcCell.getErrorCellValue());
} else if (srcCellType == HSSFCell.CELL_TYPE_FORMULA) {
distCell.setCellFormula(srcCell.getCellFormula());
} else { // nothing29
}
}
}