海量数据导出
Hibernate数据量单表哟小于500;
Mybatis/jsbc单表数据大于500,oracle不要超过1亿
Excel2003数据量有限制:65536行,256列
HSSFWorkbook对象只能操作excel2003 xls扩展名
XSSFWorkbook 可以支持excel2007及以上的版本
excel2007 支持的单表sheet:1048576行,16384列
SXSSFWorbook可以支持百万级别数据的POI 但是不支持模版,要求POI3.0版本以上
实现原理:
在初始化SXSSFWorkbook这个对象时,可以指定在内存中所产生的POI导出相关对象的个数(默认100个),一旦内存中对象的个数达到这个指定值时,就将内存中的这些对象写入到磁盘中(xml文件格式),就可以将这些对象从内存中销毁掉,以后只要达到这个值时,都会这样处理。最终excel导出完成时,也会将写入xml文件中的内容一起导出。
缺点:内存与磁盘交互时,需要占用IO流相关操作,它本身也是耗时的,如果机器配置比较低时,就会出现磁盘操作还没有完成,但是内存中有存在了指定数量的对象。
量变引起质变。
JDBC实现百万数据导出
public class POITest2 {
public static void main(String[] args) throws Exception{
String xlsFile = "c:/poiSXSSFDBBigData.xlsx"; //输出文件
Workbook wb = new SXSSFWorkbook(100); //创建excel文件,内存只有100条记录【关键语句】
Sheet sheet = wb.createSheet("我的第一个工作簿"); //建立新的sheet对象
Row nRow = null;
Cell nCell = null;
//使用jdbc链接数据库
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL";
String user = "zgs";
String password = "123456";
/*Class.forName("com.mysql.jdbc.Driver").newInstance();
String url = "jdbc:mysql://localhost:3306/jkmore100?characterEncoding=utf8";
String user = "root";
String password = "root";*/
Connection conn = DriverManager.getConnection(url, user,password);
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
String sql = "SELECT * FROM CONTRACT_PRODUCT_C"; //100万测试数据
//sql = "select name,age,des from customer"; //100万测试数据
ResultSet rs = stmt.executeQuery(sql); //bug 要分次读取,否则记录过多
long startTime = System.currentTimeMillis(); //开始时间
System.out.println("strat execute time: " + startTime);
//context
int rowNo = 0;
int colNo = 0;
while(rs.next()) {
for(int i=0;i<5000;i++){
colNo = 0;
nRow = sheet.createRow(rowNo++);
nCell = nRow.createCell(colNo++);
nCell.setCellValue(rs.getString(colNo));
nCell = nRow.createCell(colNo++);
nCell.setCellValue(rs.getString(colNo));
if(rowNo%100==0){
System.out.println("row no: " + rowNo);
}
}
Thread.sleep(1); //休息一下,防止对CPU占用
}
long finishedTime = System.currentTimeMillis(); //处理完成时间
System.out.println("finished execute time: " + (finishedTime - startTime)/1000 + "m");
FileOutputStream fOut = new FileOutputStream(xlsFile);
wb.write(fOut);
fOut.flush();
fOut.close();
long stopTime = System.currentTimeMillis(); //写文件时间
System.out.println("write xlsx file time: " + (stopTime - startTime)/1000 + "m");
close(rs, stmt, conn);
}
//close resource
private static void close(ResultSet rs, Statement stmt, Connection conn ) throws SQLException{
rs.close();
stmt.close();
conn.close();
}
}
POI的海量数据导出
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.