jxl warning: Maximum number of format records exceeded 格式记录数超出最大数限制

问题描述

采用jxl处理 excel文件生成时,产生如下报错:

Warning:  Maximum number of format records exceeded.  Using default format.
Warning:  Maximum number of format records exceeded.  Using default format.
Warning:  Maximum number of format records exceeded.  Using default format.

相关代码:

for (int j = 0; j < colNames.length; j++){
    // 根据 column format 格式来写入
    String format = colFormats[j];
    if ( format != null && format.length()>0) {
        WritableCellFormat wcf = new WritableCellFormat(new NumberFormat(format)); // 设置数字格式,例如:"#0.00"
        BigDecimal val =(BigDecimal) maptemp.get(colNames[j]);
        jxl.write.Number labelNF = new jxl.write.Number(j, rowNum, val.doubleValue(), wcf); // 格式化数值
        sheet.addCell(labelNF);
    } else {
        // 否则按照字符串文本格式来处理
        sheet.addCell(new Label(j,  rowNum,  StringDateUtil.obj2Str(maptemp.get(colNames[j]))));
    }
}

在添加单元格时,需要提供相关格式信息。因此,在for循环内部,new了很多WritableCellFormat对象出来,以至于超过jxl内部约束的format records最大数限制。

原因分析

一方面,jxl允许的每个workbook(一个excel文件)中的WritableCellFormat对象个数不超过441个,超过部分的单元格格式会自动丢弃,转而采用默认格式代替,并提示如上所述的warning信息。
相关源码:

//jxl.biff.FormattingRecords
private static final int maxFormatRecordsIndex = 0x1b9;

另一方面,其实这些 单元格格式对象(WritableCellFormat对象)是可以复用的,没有必要为每个单元格重复创建如此多的格式对象。

解决方法

通过对需求的分析,我们期望生成的excel表格,不太可能存在超过400多个以上的格式。因此,我们可以将这些格式对象只创建一次,并保存到Map容器里,在使用时,按照format格式,找到相应的对象并使用。

如下是修改后的代码:

HashMap<String, WritableCellFormat> wcfMap = new HashMap<String, WritableCellFormat>();

for (int j = 0; j < colNames.length; j++){
    // 根据 column format 格式来写入
    String format = colFormats[j];
    if ( format != null && format.length()>0) {

        // WritableCellFormat wcf = new WritableCellFormat(new NumberFormat(format)); // 设置数字格式,例如:"#0.00"
        // 这里不需要 new 这么多的 单元格格式对象!
        // 只有在format不同时,才创建对象,否则复用已有对象即可!
        WritableCellFormat wcf = null;
        if (wcfMap.containsKey(format)) {
            wcf = wcfMap.get(format);
        } else {
            wcf = new WritableCellFormat(new NumberFormat(format)); // 设置数字格式,例如:"#0.00"
            wcfMap.put(format, wcf);
        }

        BigDecimal val =(BigDecimal) maptemp.get(colNames[j]);
        jxl.write.Number labelNF = new jxl.write.Number(j, rowNum, val.doubleValue(), wcf); // 格式化数值
        sheet.addCell(labelNF);
    } else {
        // 否则按照字符串文本格式来处理
        sheet.addCell(new Label(j,  rowNum,  StringDateUtil.obj2Str(maptemp.get(colNames[j]))));
    }
}

另外,通过网上找到的解决方法,是修改jxl源码包的 最大格式记录数限制:

private static final int maxFormatRecordsIndex = Integer.MAX_VALUE;

这实际上是非常脑残的做法,非常不推荐!

在实际生成excel文件时,需要根据需求,把单元格格式梳理清楚,一共有几种、然后,为每一种格式做一个format标识,这样,只要创建少数的格式对象即可,完全没有必要为每个单元格去单独创建一套格式。

猜你喜欢

转载自blog.csdn.net/pierre_/article/details/70157441
今日推荐