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
}
}
}