gpt4 book ai didi

POIExcel单元格样式超过最大数(4000或64000)的解决方案

转载 作者:我是一只小鸟 更新时间:2023-03-22 22:32:02 25 4
gpt4 key购买 nike

                        
                          aliases: []
tags   : " #QA #Java "
summary: [POI生成Excel超出的单元格样式的最大数量]
author : [yaenli]
notekey: [20230322-100908]

                        
                      

问题现象

使用Apache POI生成Excel时,如果创建的单元格样式过多,会报样式超出最大数的错误, 。

.xls 的异常错误:

                        
                          java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:1144)
	at org.apache.poi.hssf.usermodel.HSSFWorkbook.createCellStyle(HSSFWorkbook.java:88)

                        
                      

.xlsx 的异常错误:

                        
                          java.lang.IllegalStateException: The maximum number of Cell Styles was exceeded. You can define up to 64000 style in a .xlsx Workbook
	at org.apache.poi.xssf.model.StylesTable.createCellStyle(StylesTable.java:830)
	at org.apache.poi.xssf.usermodel.XSSFWorkbook.createCellStyle(XSSFWorkbook.java:750)


                        
                      

问题分析

同一个Workbook创建CellStyle有最大数限制,其中 .xls(Excel 97) 的最大数是4000, .xlsx(Excel 2007) 的最大数是64000 .

xls 参数限制于 org.apache.poi.hssf.usermodel.HSSFWorkbook

                        
                          private static final int MAX_STYLES = 4030;

public HSSFCellStyle createCellStyle() {
    if (this.workbook.getNumExFormats() == MAX_STYLES) {
      throw new IllegalStateException("The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook");
    }
    
    ExtendedFormatRecord xfr = this.workbook.createCellXF();
    short index = (short)(getNumCellStyles() - 1);
    return new HSSFCellStyle(index, xfr, this);
}

                        
                      

xlsx 参数限制于 org.apache.poi.xssf.model.StylesTable

                        
                          private static final int MAXIMUM_STYLE_ID = SpreadsheetVersion.EXCEL2007.getMaxCellStyles();// 64000

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 = this.styleXfs.size();
    CTXf xf = CTXf.Factory.newInstance();
    xf.setNumFmtId(0L);
    xf.setFontId(0L);
    xf.setFillId(0L);
    xf.setBorderId(0L);
    xf.setXfId(0L);
    int indexXf = putCellXf(xf);
    return new XSSFCellStyle(indexXf - 1, xfSize - 1, this, this.theme);
}

                        
                      

因此,在生成Excel时,如果同一个Workbook不停的创建CellStyle,超限时就会产生样式最大数异常,最直接的体现就是在某些代码中,对每个单元格去独立的设置样式,生成大数据量的Excel报错.

解决方案

网上最热门的解决方案是所谓的将 createCellStyle 放在循环外面,这只能应付表格样式单一的情况.

由于单元格样式 CellStyle 并不是单元独立拥有的,每个单元格只是保存了样式的索引,一般的Excel真正使用到的样式也不会超过 4000/64000 ,因此更好的解决方案是实现单元格样式的复用( 注意不同的Workbook创建的CellStyle是不能混用的 ).

方案1:缓存样式实现复用

提取样式关键字作为key,将CellStyle缓存至Map:

                        
                          Workbook workBook = new HSSFWorkbook();// or new XSSFWorkbook();
Sheet sheet = workBook.createSheet(strSheetName);
Map cellStyleMap = new HashMap<String, CellStyle>();// 缓存样式

// 样式代码
for (int rowIndex = 0; rowIndex < maxRow; rowIndex++) {
    Row row = sheet.createRow(rowIndex);
    for (int colIndex = 0; colIndex < maxCol; colIndex++) {
        Cell cell = row.createCell((short) colIndex);
        String styKey = getCellStyleKey(rowIndex, colIndex);// 根据获取样式key
        CellStyle cellStyle = (CellStyle) cellStyleMap.computeIfAbsent(styKey, k-> workBook.createCellStyle());// 获取样式
        cell.setCellStyle(cellStyle);
    }
}

                        
                      

方案2:修改限制参数

修改POI中的限制参数( org.apache.poi.hssf.usermodel.HSSFWorkbook.MAX_STYLES 或 org.apache.poi.ss.SpreadsheetVersion.EXCEL2007 ).

过多的创建样式会影响性能,建议仅在真正使用的样式超过限制时再去修改此参数.

方案3:延迟指定单元格样式实现复用

参见文章: POI 操作Excel的单元格样式超过64000的异常问题解决 根据模版填充Excel并导出的工具 · GitCode 。

最后此篇关于POIExcel单元格样式超过最大数(4000或64000)的解决方案的文章就讲到这里了,如果你想了解更多关于POIExcel单元格样式超过最大数(4000或64000)的解决方案的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com