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标识,这样,只要创建少数的格式对象即可,完全没有必要为每个单元格去单独创建一套格式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pierre_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值