解决java poi之SXSSFWorkbook导出大数据量时自适应列宽效果异常问题

场景:使用SXSSFWorkbook导出大数据量(百万行)excel报表,表格样式统一使用自适应列宽时,发现导出表头行格式异常,异常情况如下图所示:

分析:从导出效果看,应该是忽略了表头数据长度,根据数据内容的长度进行了自适应列宽调整。但是代码中自适应宽度操作是放在导出方法最后的,届时已完成表格数据渲染,理论上应该对所有表头标题数据进行自适应列宽调整。自适应列宽部分代码如下:

  //自动调整列宽
  sheet.trackAllColumnsForAutoSizing();
  for (int i = 0; i < head.size(); i++) {
     sheet.autoSizeColumn(i);
     //手动调整列宽,解决中文不能自适应问题
     //单元格单行最长支持255*256宽度(每个单元格样式已经设置自动换行,超出即换行)
     sheet.setColumnWidth(i, Math.min(255*256, sheet.getColumnWidth(i) * 12 / 10));
  }

排查:该导出功能之前经过自测,并没有发现这个问题。猜测是自测数据没有触发异常情况。遂,重新本地自测,依然无法复现。对比了自测数据和异常场景之间数据的差异,发现区别点是本地自测导出数据量比较少,只有几十行。于是加大数据量进行导出测试,问题复现。

解决:目前已知是数据量的区别,导致了自适应列宽效果异常。于是灵光一闪,想到了SXSSFWorkbook的特性。SXSSFWorkbook非常适合大数据量导出场景,因为使用之前的poi(HSSFWorkbook/XSSFWorkbook)进行大数据量导出时,会因内存不够导致OOM,而SXSSFWorkbook只在内存中加载一部分数据,其余大部分数据是加载到磁盘里面的。导致在导出大数据量的时候,表格自适应宽度只会对最后几百行的数据生效,而忽略了表头行,因此表头行的格式会异常。临时的解决方案是最后对各列的自适应宽度做一个判断,不能少于一个默认宽度大小,以免表头样式过于难看。修改后的代码如下:

//自动调整列宽
   sheet.trackAllColumnsForAutoSizing();
   for (int i = 0; i < data.getHead().size(); i++) {
      sheet.autoSizeColumn(i);
      //手动调整列宽,解决中文不能自适应问题
      //单元格单行最长支持255*256宽度(每个单元格样式已经设置自动换行,超出即换行)
      //设置最低列宽度,列宽约六个中文字符
      int width = Math.max(15 * 256, Math.min(255 * 256, sheet.getColumnWidth(i) * 12 / 10));
      sheet.setColumnWidth(i, width);
    }

修改后的导出效果如下图所示:

总结:至此,我明白了SXSSFWorkbook也是一把双刃剑,想要正常导出大数据量的表格,必须得用它的特性,不会占大量内存,但也正是因为它的特性,在使用过程中得仔细思考潜在的问题。还有,功能测试的时候,必须考虑周密,严格按照实际情况导出测试。

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值