java使用poi导出excel时,createCellStyle过多导致的异常

问题

The maximum number of Cell Styles was exceeded. You can define up to 64000 style in a .xlsx Workbook

问题原因

源代码:

/**
     * Create a cell style in this style table.
     * Note - End users probably want to call {@link XSSFWorkbook#createCellStyle()}
     * rather than working with the styles table directly.
     * @throws IllegalStateException if the maximum number of cell styles has been reached. 
     */
    public XSSFCellStyle createCellStyle() {
        if (getNumCellStyles() > MAXIMUM_STYLE_ID) {
            throw new IllegalStateException("The maximum number of Cell Styles was exceeded. " +
                      "You can define up to " + MAXIMUM_STYLE_ID + " style in a .xlsx Workbook");
        }

        int xfSize = styleXfs.size();
        CTXf xf = CTXf.Factory.newInstance();
        xf.setNumFmtId(0);
        xf.setFontId(0);
        xf.setFillId(0);
        xf.setBorderId(0);
        xf.setXfId(0);
        int indexXf = putCellXf(xf);
        return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, theme);
    }

往里跟可以看到:

EXCEL2007(0x100000, 0x4000, 255, Integer.MAX_VALUE, 64000, 32767);

解决方法

由于我是采用自定义的方式,实现了接口CellWriteHandler,不能直接在for循环外创建对象,所以使用一个map进行存储,每次创建对象前先判断map中是否存在,存在则不再创建。

// 每次调用接口时需要对这两个map进行重新初始化。
private static Map<String,CellStyle> cellStyleMap = Maps.newHashMap();
private static Map<String,Font> fontMap = Maps.newHashMap();
CellStyle cellStyleDeal1 = cellStyleMap.get("cellStyleDeal1");
Font dealFont = fontMap.get("dealFont1");
if(cellStyleDeal1 == null){
    cellStyleDeal1 = workbook.createCellStyle();
    cellStyleMap.put("cellStyleDeal1",cellStyleDeal1);
}
if(dealFont == null){
    dealFont = workbook.createFont();
    fontMap.put("dealFont1",dealFont);
}

完整代码

@Component
public class CustomCellWriteHandler implements CellWriteHandler {

    private static Map<String,CellStyle> cellStyleMap = Maps.newHashMap();
    private static Map<String,Font> fontMap = Maps.newHashMap();

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        Cell cell = context.getCell();
        int rowIndex = cell.getRowIndex();
        String sheetName = cell.getSheet().getSheetName();
        Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
        // 设置背景色,内容不同行不同背景色
        byte[] rgb1 = new byte[]{(byte)235, (byte)242, (byte)254};
        byte[] rgb2 = new byte[]{(byte)227, (byte)236, (byte)251};
        byte[] rgbHead = new byte[]{(byte)203, (byte)226, (byte)248};



        // 4. 自定义样式处理,当前事件会在 数据设置到poi的cell里面才会回调,判断不是头的情况 如果是fill 的情况 这里会==null 所以用not true
        if (BooleanUtils.isNotTrue(context.getHead())) {
            
           CellStyle cellStyleDeal1 = cellStyleMap.get("cellStyleDeal1");
            Font dealFont = fontMap.get("dealFont1");
            if(cellStyleDeal1 == null){
                cellStyleDeal1 = workbook.createCellStyle();
                cellStyleMap.put("cellStyleDeal1",cellStyleDeal1);
            }
            if(dealFont == null){
                dealFont = workbook.createFont();
                fontMap.put("dealFont1",dealFont);
            }
            // 字体
            dealFont.setFontHeightInPoints((short)12);
            dealFont.setFontName("宋体");
            byte[] rgbFontDeal = new byte[]{(byte) 138, (byte) 138, (byte) 138};
            XSSFFont xssfDealFont = (XSSFFont)dealFont;
            xssfDealFont.setColor(new XSSFColor(rgbFontDeal,null));
            // 样式
            cellStyleDeal1.setFont(dealFont);
            cellStyleDeal1.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            cellStyleDeal1.setAlignment(HorizontalAlignment.CENTER);
            cellStyleDeal1.setVerticalAlignment(VerticalAlignment.CENTER);
            cellStyleDeal1.setBorderLeft(BorderStyle.THIN);
            cellStyleDeal1.setBorderBottom(BorderStyle.THIN);
            cellStyleDeal1.setBorderRight(BorderStyle.THIN);
            cellStyleDeal1.setBorderTop(BorderStyle.THIN);
            XSSFCellStyle xssfCellColorStyleDeal1 = (XSSFCellStyle) cellStyleDeal1;
            xssfCellColorStyleDeal1.setFillForegroundColor(new XSSFColor(rgb1, null));
            cell.setCellStyle(cellStyleDeal1);

        }
    }
// 2.0 重置handler的属性map
 customCellWriteHandler.cellStyleMap = Maps.newHashMap();
 customCellWriteHandler.fontMap = Maps.newHashMap();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值