1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 大数据excel导出 内存溢出解决方案(SXSSF流用户模型)

大数据excel导出 内存溢出解决方案(SXSSF流用户模型)

时间:2021-01-01 18:37:19

相关推荐

大数据excel导出 内存溢出解决方案(SXSSF流用户模型)

SXSSF(流用户模型 API)

SXSSF(包:org.apache.poi.xssf.streaming)是 XSSF 的一个 API 兼容的流扩展,当必须生成非常大的电子表格并且堆空间有限时使用。SXSSF 通过限制对滑动窗口内的行的访问来实现其低内存占用,而 XSSF 允许访问文档中的所有行。不再出现在窗口中的旧行将无法访问,因为它们被写入磁盘。

您可以在工作簿构建时通过new SXSSFWorkbook(int windowSize)指定窗口大小,也可以通过SXSSFSheet#setRandomAccessWindowSize(int windowSize) 为每页设置它

当通过 createRow() 创建新行并且未刷新的记录总数将超过指定的窗口大小时,具有最低索引值的行将被刷新并且无法再通过 getRow() 访问。

默认窗口大小为100,由 SXSSFWorkbook.DEFAULT_WINDOW_SIZE 定义。

windowSize 为 -1 表示无限制访问。在这种情况下,所有未被调用 flushRows() 刷新的记录都可用于随机访问。

请注意,SXSSF通过调用 dispose 方法分配您必须始终明确清除的临时文件。

SXSSFWorkbook 默认使用内联字符串而不是共享字符串表。这是非常有效的,因为不需要将文档内容保存在内存中,但也已知会生成与某些客户端不兼容的文档。启用共享字符串后,文档中的所有唯一字符串都必须保存在内存中。根据您的文档内容,这可能比禁用共享字符串使用更多的资源。

请注意,根据您使用的功能,仍有一些内容可能会消耗大量内存,例如合并区域、超链接、评论……仍然只存储在内存中,因此可能需要大量内存,如果广泛使用。

在决定是否启用共享字符串之前,请仔细检查您的内存预算和兼容性需求。

下面的示例编写了一个带有 100 行窗口的工作表。当行数达到 101 时,将 rownum=0 的行刷新到磁盘并从内存中删除,当 rownum 达到 102 时,则刷新 rownum=1 的行,以此类推。

mport junit.framework.Assert;mport org.apache.poi.ss.usermodel.Cell;mport org.apache.poi.ss.usermodel.Row;mport org.apache.poi.ss.usermodel.Sheet;mport org.apache.poi.ss.usermodel.Workbook;mport org.apache.poi.ss.util.CellReference;mport org.apache.poi.xssf.streaming.SXSSFWorkbook;public static void main(String[] args) throws Throwable {SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to diskSheet sh = wb.createSheet();for(int rownum = 0; rownum < 1000; rownum++){Row row = sh.createRow(rownum);for(int cellnum = 0; cellnum < 10; cellnum++){Cell cell = row.createCell(cellnum);String address = new CellReference(cell).formatAsString();cell.setCellValue(address);}}// Rows with rownum < 900 are flushed and not accessiblefor(int rownum = 0; rownum < 900; rownum++){Assert.assertNull(sh.getRow(rownum));}// ther last 100 rows are still in memoryfor(int rownum = 900; rownum < 1000; rownum++){Assert.assertNotNull(sh.getRow(rownum));}FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");wb.write(out);out.close();// dispose of temporary files backing this workbook on diskwb.dispose();}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。