POI读写大数据量EXCEL
另一篇文章http://www.cnblogs.com/tootwo2/p/8120053.html里面有xml的一些解释。
大数据量的excel一般都是.xlsx格式的,网上使用POI读写的例子比较多,但是很少提到读写非常大数据量的excel的例子,POI官网上提到XSSF有三种读写excel,POI地址:http://poi.apache.org/spreadsheet/index.html。官网的图片:

可以看到有三种模式:
1、eventmodel方式,基于事件驱动,SAX的方式解析excel(.xlsx是基于OOXML的),CPU和内存消耗非常低,但是只能读不能写
2、usermodel,就是我们一般使用的方式,这种方式可以读可以写,但是CPU和内存消耗非常大
3、SXSSF,POI3.8以后开始支持,这种方式只能写excel
下面介绍下使用方式(官网地址:http://poi.apache.org/spreadsheet/how-to.html):
第一种方式:
pom文件需要添加依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xerces</artifactId>
<version>2.4.0</version>
</dependency>
java官网示例代码:
package excel; import java.io.InputStream;
import java.util.Iterator; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory; public class ExampleEventUserModel { public void processOneSheet(String filename) throws Exception {
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable(); XMLReader parser = fetchSheetParser(sst); // To look up the Sheet Name / Sheet Order / rID,
// you need to process the core Workbook stream.
// Normally it's of the form rId# or rSheet#
InputStream sheet2 = r.getSheet("rId2");
InputSource sheetSource = new InputSource(sheet2);
parser.parse(sheetSource);
sheet2.close();
} public void processAllSheets(String filename) throws Exception {
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable(); XMLReader parser = fetchSheetParser(sst); Iterator<InputStream> sheets = r.getSheetsData();
while(sheets.hasNext()) {
System.out.println("Processing new sheet:\n");
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close();
System.out.println("");
}
} public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
XMLReader parser =
XMLReaderFactory.createXMLReader(
"com.sun.org.apache.xerces.internal.parsers.SAXParser"
);
ContentHandler handler = new SheetHandler(sst);
parser.setContentHandler(handler);
return parser;
} /**
* See org.xml.sax.helpers.DefaultHandler javadocs
*/
private static class SheetHandler extends DefaultHandler {
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString; private SheetHandler(SharedStringsTable sst) {
this.sst = sst;
} public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
if(name.equals("c")) {
// Print the cell reference
System.out.print(attributes.getValue("r") + " - ");
// Figure out if the value is an index in the SST
String cellType = attributes.getValue("t");
if(cellType != null && cellType.equals("s")) {
nextIsString = true;
} else {
nextIsString = false;
}
}
// Clear contents cache
lastContents = "";
} public void endElement(String uri, String localName, String name)
throws SAXException {
// Process the last contents as required.
// Do now, as characters() may be called more than once
if(nextIsString) {
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
nextIsString = false;
} // v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
System.out.println(lastContents);
}
} public void characters(char[] ch, int start, int length)
throws SAXException {
lastContents += new String(ch, start, length);
}
} public static void main(String[] args) throws Exception {
ExampleEventUserModel example = new ExampleEventUserModel();
System.out.println("11");
example.processOneSheet(args[0]);
example.processAllSheets(args[0]);
}
}
运行的时候使用本地的文件地址替代main函数里面的参数就可以运行(亲测可以)。
第三种方式:
其核心是减少存储在内存当中的数据,达到一定行数就存储到硬盘的临时文件中。
pom文件需要增加依赖:
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
</dependency>
java代码如下:
package excel; //import junit.framework.Assert;
import java.io.FileOutputStream; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.streaming.SXSSFWorkbook; public class SXSSFDemo {
public static void main(String[] args) throws Throwable { SXSSFWorkbook wb = new SXSSFWorkbook(100); // 在内存当中保持 100 行 , 超过的数据放到硬盘中
Sheet sh = wb.createSheet();
for(int rownum = 0; rownum < 10000; 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);
} } FileOutputStream out = new FileOutputStream("/Users/tootwo2/Documents/sxssf.xlsx");
wb.write(out);
out.close(); // dispose of temporary files backing this workbook on disk
wb.dispose();
} }
POI读写大数据量EXCEL的更多相关文章
- POI读写大数据量excel,解决超过几万行而导致内存溢出的问题
1. Excel2003与Excel2007 两个版本的最大行数和列数不同,2003版最大行数是65536行,最大列数是256列,2007版及以后的版本最大行数是1048576行,最大列数是16384 ...
- POI 读写大数据量 EXCEL
参考:https://www.cnblogs.com/tootwo2/p/6683143.html
- [转]POI大数据量Excel解决方案
全文转载自:jinshuaiwang的博客 目前处理Excel的开源javaAPI主要有两种,一是Jxl(Java Excel API),Jxl只支持Excel2003以下的版本.另外一种是Apach ...
- POI3.8解决导出大数据量excel文件时内存溢出的问题
POI3.8的SXSSF包是XSSF的一个扩展版本,支持流处理,在生成大数据量的电子表格且堆空间有限时使用.SXSSF通过限制内存中可访问的记录行数来实现其低内存利用,当达到限定值时,新一行数据的加入 ...
- 由“大数据量Excel入库高效方式”瞥见“并联系统”之优势
使用场景: 当你有一个Excel文件,需要把其中的数据高速录入到数据库中,文件中包含10万条以上数据. 设计方案: 我们将整个过程分成三个阶段,A(装载Excel文件). ...
- C#读取大数据量Excel
var worksheet = workbook.Worksheets["工作表1"]; var maxN = worksheet.Range["A1"].En ...
- python3 修改大数据量excel内容
最好使用python3 64位 对excel的修改操作: from openpyxl import load_workbook import time #打开一个excel表格.xlsx wb = l ...
- POI实现大数据EXCLE导入导出,解决内存溢出问题
使用POI能够导出大数据保证内存不溢出的一个重要原因是SXSSFWorkbook生成的EXCEL为2007版本,修改EXCEL2007文件后缀为ZIP打开可以看到,每一个Sheet都是一个xml文件, ...
- poi 操作Excel 以及大数据量导出
maven 依赖 (版本必须一致,否则使用SXSSFworkbook 时程序会报错) <dependency> <groupId>org.apache.poi</grou ...
随机推荐
- 了解C#文件操作
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...
- unity, editorWindow lose data when enter play mode
我写了个editorWindow,其中有个成员变量m_x,在创建editorWindow的时候为m_x赋的值,而在editorWindow的OnGUI里把m_x显示出来. 当我开着这个editorWi ...
- 使用Secure Boot后,导致VMware无法启动虚拟机
最初安装vmware时就报错 Gtk-Message: Failed to load module "canberra-gtk-module": libcanberra-gtk- ...
- Atitit.struts2体系结构大总结
Atitit.struts2体系结构大总结 1. 国际化与异常处理 2 2. 第5章 拦截器 2 3. 第7章 输入校验 2 4. 避免表单重复提交与等待页面 2 5. Struts 2对Ajax的支 ...
- vim -d file01 file02 diff file01 file02 对比两文件的不同
[root@86 vhosts]# vim -d defaul.conf.bak zabbix.xinxianm.com.conf server { | server { listen 80; | l ...
- 信号处理函数(1)-alarm定时器
定义: unsigned int alarm(unsigned int seconds); 表头文件: #include<unistd.h> 说明: alarm()用来设置信号SI ...
- SQL业务审核与优化
审核 什么是业务审核 类似与code review 评审业务Schema和SQL设计 偏重关注性能 是业务优化的主要入口之一 审核提前发现问题,进行优化 上 ...
- (转)Sql Server之旅——第八站 复合索引和include索引到底有多大区别?
索引和锁,这两个主题对我们开发工程师来说,非常的重要...只有理解了这两个主题,我们才能写出高质量的sql语句,在之前的博客中,我所说的 索引都是单列索引...当然数据库不可能只认单列索引,还有我这篇 ...
- Cookie、Session详解
讲解的很全面 https://www.cnblogs.com/andy-zhou/p/5360107.html
- linux 密码破解
(一)Linux 系统密码破解 1.在grub选项菜单按E进入编辑模式 2.编辑kernel那行 /init 1 (或/single) 3.按B重启 4.进入后执行下列命令 root@#passwd ...