如何使用SXSSF将带模板的大型报表写入字节数组?
如何使用SXSSF将带模板的大型报表写入字节数组?
嘿,我懂你现在的痛点——原来用JXLS 2.14.0生成报表,碰到大数据量的时候内存容易爆,想用SXSSF的流式处理来优化,同时还得保持输出字节数组的形式对吧?这就给你捋清楚怎么改:
首先得明确,JXLS是支持结合POI的SXSSFWorkbook来处理大型报表的,SXSSF会把超出内存阈值的行刷到临时文件,不会把整个报表都存在内存里,完美解决大数据量的内存问题。
直接上修改后的代码,你可以对照原来的方法调整:
public byte[] generateLargeReport(String template, Map<String, Object> data) throws Exception { // 初始化SXSSFWorkbook,设置内存仅保留100行,超过就刷到磁盘临时文件 try (SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(100); InputStream is = new ClassPathResource(template).getInputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream()) { Context context = new Context(data); JxlsHelper helper = JxlsHelper.getInstance(); // 让JXLS使用我们创建的SXSSFWorkbook来处理模板 helper.processTemplate(is, bos, context, sxssfWorkbook); // 确保SXSSF的所有临时数据都写入字节输出流 sxssfWorkbook.write(bos); // 清理SXSSF生成的临时文件,避免磁盘占用 sxssfWorkbook.dispose(); return bos.toByteArray(); } }
这里几个关键细节得注意:
- 用
try-with-resources自动管理所有资源的关闭,不用手动写finally,代码更简洁安全 SXSSFWorkbook(100)里的100是内存保留行数,你可以根据自己的内存情况调整,比如设成500或者200都行,数值越小内存占用越低- 一定要调用
dispose()方法!SXSSF会生成临时文件存在系统临时目录,不清理的话时间久了会占满磁盘 - 额外调用
sxssfWorkbook.write(bos)是确保所有刷到磁盘的临时数据都被写入到字节数组里,避免数据不全
另外还有个小提醒:JXLS 2.14.0和POI的SXSSF兼容没问题,但如果你的模板里有复杂公式或者特殊格式,可能需要额外测试——比如SXSSF对某些公式的支持有限,要是碰到公式计算不对的情况,可以试试在写入前手动触发公式计算:sxssfWorkbook.getCreationHelper().createFormulaEvaluator().evaluateAll()。
内容来源于stack exchange
相关产品推荐
相关产品推荐

