当前位置:首页 > 科技

【怎么查看excel内存】Apache POI Excel读取和写入大量数据

通过Excel导入导出的场景在软件系统开发中很常见,Java开发人员通常使用Apache POI库处理Excel。这是非常受欢迎的Java API for Microsoft Documents。

阅读XSSFWorkbook Excel

最常用的读取代码如下:

workbook workbook=new xssfworkbook([输入流]);

In (0,workbook.getnumberofsheets())。forearch(

图纸索引-{

sheet sheet=workbook . getsheet at(sheet index);

//数据处理

}

)如果导入的数据量少,通常可以正常工作,但如果导入的Excel数据量非常大,操作环境内存不足,则会出现内存溢出错误。为了进行测试,我们构建了包含8000行数据的Excel,设置了JVM参数“-Xms32M -Xmx32M”,出现了以下错误:

Exception in thread 'main '

Java . lang . out of memory error : Java heapspace此文件仅占用279K的磁盘大小。由于xlsx默认为压缩的XML文件堆,并且是XML,因此POI处理Excel文件时使用的内存远大于279K。如果将此XML放入未压缩内存中,内存消耗将增加10倍,计算出添加

XSSFReader读取Excel

为了解决内存使用问题,XSSF可以导入基本XML数据并自行处理。需要学习一些xlsx文件的结构,但可以使用相对较小的安装内存读取大量数据的XLSX文件。

XML解析也分为DOM解析和SAX解析。使用DOM很简单,但占用大量内存,而SAX解析将XML文件作为流读取,并通过事件触发器通知代码。对于XLSX文件格式,未填充内容的单元格在XML中不存在。也就是说,并非每一行都有相同数量的单元格Cell元素,因此必须通过代码解决这些问题。

解压缩的Excel文件

要在Excel中查看XML信息,请将Excel后缀设置为“.zip”,然后打开“XL workSheets”以查看该图纸的标签节点信息。

如前面的屏幕快照所示,sheet标签包含row(行标签)、c(单元格标签)、r(Cell的Excel编号属性)、t(Cell的Type属性)等节点,您可以访问Microsoft以了解XML的结构

接下来,创建XSSFReader实例,并使用SAX解析读取数据。示例代码如下:

Public class XSSFReaderExample {

public static void main(string[]args){

Opc软件包pkg=OPC软件包。open(文件路径);

XSS freader r=new XSS freader(pkg);

sharedstringstable SST=r . getsharedstringstable();

XML reader parser=XML hel();

content handler handler=new sheet handler(SST);

(处理程序);

从//XML取得Id,通常是rId# or rSheet#

inputstream sheet=r . get sheet(' rid 1 ');

input source sheet source=new input source(sheet);

(图纸来源);

();

}

private static class sheet handler extends default handler {

私有final sharedstringstable SST

私有字符串lastContents

专用布尔扩展;

//Row

数据,使用TreeMap保持顺序 private Map<String, String> rowData = new TreeMap<>(); private int cellSeq = 0; // Cell序列,处理Cell为空的情况 private int rowSeq = 0; // Row序列 private OrderSheetHandler(SharedStringsTable sst) { = sst; } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) { if ("row")) { cellSeq = 0; rowSeq = In("r")); } // c => cell if ("c")) { String cellSeqStr = CellReference .convertNumToColString(cellSeq++) + rowSeq; String readCellStr = a("r"); while (!cellSeqS(readCellStr)) { rowDa(cellSeqStr, ""); cellSeqStr = CellRe(cellSeq++) + rowSeq; } String cellType = a("t"); if (cellType != null && cellTy("s")) { nextIsString = true; } else { nextIsString = false; } } // Clear contents cache lastContents = ""; } @Override public void endElement(String uri, String localName, String qName) { if ("row")) { // 处理行数据rowData rowDa(); } if (nextIsString) { // sheet xml中存储的是文字索引 int idx = In(lastContents); lastContents = (idx).getString(); nextIsString = false; } // v => 单元格的内容 if ("v")) { rowDa( CellRe(cellSeq - 1) + rowSeq, lastContents); } } // 接收元素内字符数据 @Override public void characters(char[] ch, int start, int length) { lastContents += new String(ch, start, length); } } }

采用XSSFWorkbook案例相同的内存配置,使用上述代码读取大数据量Excel,能轻松处理,不会出现内存溢出的现象。

XSSFWorkbook写入Excel

XSSF是POI提供的常用Excel写入工具,示例代码如下:

XSSFWorkbook wb = new XSSFWorkbook(); Sheet sh = wb.createSheet("order"); AtomicInteger rownum = new AtomicInteger(0); Row headerRow = ()); (0).setCellValue("Title-1"); (1).setCellValue("Title-2"); (2).setCellValue("Title-3"); (3).setCellValue("Title-4"); InClosed(), 8000) .forEach( idx -> { Row row = ()); row.createCell(0).setCellValue("value-column-1" + idx); row.createCell(1).setCellValue("value-column-2" + idx); row.createCell(2).setCellValue("value-column-3" + idx); row.createCell(3).setCellValue("value-column-4" + idx); }); wb.write(new FileOutputStream(filePath));

设置JVM启动参数“-Xms16M -Xmx16M”运行上述代码,遇到如下错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at org.a$Tex(Saver.java:1701) ......

原因依然是由于XSSF在内存中组织数据,需要消耗大量的内存。这类错误笔者曾在给某金融公司做顾问时听到他们的抱怨,他们的生产环境在导出几次大量数据的Excel之后,内存占用开始上升,直至遇到内存溢出的错误。

SXSSFWorkbook写入Excel

好消息是Apache POI 引入了SXSSF,用于在电子表格中流式传输非常大量的数据,具有非常好的性能和低内存使用率。示例代码如下:

// .... 与上面的代码一致 SXSSFWorkbook wb = new SXSSFWorkbook); Sheet sh = wb.createSheet("order"); // .... 与上面的代码一致

与上面的代码的区别在于使用SXSSFWorkbook来写入,它的构造函数的参数是允许在内存中的数据行数,当达到行数后row的索引值会被刷新,临时数据会被写入磁盘,通过以下代码可以设置POI使用的临时目录:

Tem( new DefaultTempFileCreationStrategy(new File(poiTempDir)));

此时运行代码可以观察到POI处理数据时所生成的临时文件,如下图:

POI Temp File

这两种处理Excel写入的方式内存占用差异见下图,前部分是SXSSF方式的内存占用,非常稳定,后部分是XSSF方式,内存占用非常大。

XSSF与SXSSF内存占用对比

此外大数据量的写入不都是像示例代码中这样通过逻辑写入数据,通常是将数据库中的数据读取出来组织后写入Excel,要注意设置好JDBC featchSize参数,流式读取以防止内存占用过大造成OOM。

本文总结

  1. POI读取的2种方式:XSSF与SAX解析,读取大数据量用SAX解析防止OOM;
  2. POI写入的2种方式:XSSF与SXSSF,写入大数据量用SXSSF方式OOM;
  3. JDBC读取大数据量设置featchSize参数,流失读取防止大量内存占用;

参考资料

另:示例代码POI版本:4.1.2

1.《【怎么查看excel内存】Apache POI Excel读取和写入大量数据》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《【怎么查看excel内存】Apache POI Excel读取和写入大量数据》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/2531592.html

上一篇

【怎么检查Excel排序】在Excel中有多种排序方法?各有什么使用场景?你会吗?

【怎么查看excel内存】Excel表(Excel 2016概述常用办公软件的使用方法)

【怎么查看excel内存】Excel表(Excel 2016概述常用办公软件的使用方法)

怎么查看excel内存相关介绍,1.Excel的功能 电子表格利用计算机强大的计算功能,以数字方式处理表单中的数据。缩短处理时间,确保数据处理的准确性和准确性,还可以进一步分析和重复使用数据。 Excel 2016是微软推出的办公套...

【怎么查看excel内存】减少Excel文件容量的妙法

【怎么查看excel内存】减少Excel文件容量的妙法

怎么查看excel内存相关介绍,同事需要向客户发送excel文件,但文件容量很大,超过80万亿美元。给顾客发邮件不容易。一般来说,邮件大小最大3m以下为宜,邮件太大,发送时间慢,客人收到邮件时体验会很差。(大卫亚设,Northern...

【怎么查看excel内存】Windows win7 SP1系统使用excel显示内存不足的问题

  • 【怎么查看excel内存】Windows win7 SP1系统使用excel显示内存不足的问题
  • 【怎么查看excel内存】Windows win7 SP1系统使用excel显示内存不足的问题
  • 【怎么查看excel内存】Windows win7 SP1系统使用excel显示内存不足的问题

【怎么查看excel内存】方便灵活地读取EasyExcel Excel内容

  • 【怎么查看excel内存】方便灵活地读取EasyExcel Excel内容
  • 【怎么查看excel内存】方便灵活地读取EasyExcel Excel内容
  • 【怎么查看excel内存】方便灵活地读取EasyExcel Excel内容

【怎么查看excel内存】打开Excel文件提示:内存或磁盘空间不足

  • 【怎么查看excel内存】打开Excel文件提示:内存或磁盘空间不足
  • 【怎么查看excel内存】打开Excel文件提示:内存或磁盘空间不足
  • 【怎么查看excel内存】打开Excel文件提示:内存或磁盘空间不足

【怎么查看excel内存】标题句-使用仪表板在Excel中动态监视内存状态

  • 【怎么查看excel内存】标题句-使用仪表板在Excel中动态监视内存状态
  • 【怎么查看excel内存】标题句-使用仪表板在Excel中动态监视内存状态
  • 【怎么查看excel内存】标题句-使用仪表板在Excel中动态监视内存状态

【怎么查看excel内存】EXCEL表占用大量内存,很难打开,但内容很少

  • 【怎么查看excel内存】EXCEL表占用大量内存,很难打开,但内容很少
  • 【怎么查看excel内存】EXCEL表占用大量内存,很难打开,但内容很少
  • 【怎么查看excel内存】EXCEL表占用大量内存,很难打开,但内容很少