首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >JAVA OutOfMemoryError问题使用Excel在Apache POI Stream API中导出150K +数据?

JAVA OutOfMemoryError问题使用Excel在Apache POI Stream API中导出150K +数据?
EN

Stack Overflow用户
提问于 2018-06-12 11:05:33
回答 1查看 0关注 0票数 0

我的Apache POI版本是3.14。我正试图将大量数据导出为ex​​cel?

所以,我有以下List来自我的数据库(PostgresSQL):

List<TransactionDTO> result = new ArrayList<>(); result.addAll(transactionService.findByInDateRange(status, fromDate, toDate));

然后我遵循上面提到的链接(逻辑完全相同)。

代码语言:javascript
复制
   DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_hh_mm_ss");
    String excelFileName = "Statistics_by_partner" + formatter.format(LocalDateTime.now()) + ".xlsx";
    SXSSFWorkbook wb = (new ExportRevisionResponseExcel()).exportExcel(new String[] { "Status",
        "Request",}, result);
    try {
        ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
        wb.write(outByteStream);
        byte[] outArray = outByteStream.toByteArray();
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setContentLength(outArray.length);
        response.setHeader("Expires:", "0"); // eliminates browser caching
        response.setHeader("Content-Disposition", "attachment; filename=" + excelFileName);
        OutputStream outStream = response.getOutputStream();
        outStream.write(outArray);
        outStream.flush();
        wb.dispose();
        wb.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }`

但是,它仍然给我记忆错误。

EN

回答 1

Stack Overflow用户

发布于 2018-06-12 20:57:36

你用完堆空间的最可能原因是你要将整个工作簿流传输到内存中的字节数组缓冲区。

代码语言:javascript
复制
    ByteArrayOutputStream outByteStream = new ByteArrayOutputStream();
    wb.write(outByteStream);

这可消耗最多三次1的实际流长度(字节)。如果您想使用较少的内存,请将数据直接写入响应流:

代码语言:javascript
复制
    OutputStream outStream = response.getOutputStream();
    wb.write(outStream);

显然,这意味着你将无法在响应中设置内容长度。如果这对你来说真的很重要,那么使用临时文件来缓冲数据而不是a ByteArrayOutputStream

1 - BAOS使用内部byte[]缓冲区。当缓冲区已满时,它会分配一个两倍大小的新数据,并将数据从旧数据复制到新数据。当你正在进行复制时,你有2个字节的数组,占据目前缓冲的字节数的3倍。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档