POI之SXSSFWorkbook大量數據導出至excel

一:簡介
          SXSSFWorkbook是用來生成海量excel數據文件,主要原理是藉助臨時存儲空間生成excel,
          SXSSFWorkbook專門處理大數據,對於大型excel的建立且不會內存溢出的,就只有SXSSFWorkbook了。
          它的原理很簡單,用硬盤空間換內存(就像hashmap用空間換時間同樣)。 SXSSFWorkbook是streaming
          版本的XSSFWorkbook,它只會保存最新的excel rows在內存裏供查看,在此以前的excel rows都會被寫入到
          硬盤裏(Windows電腦的話,是寫入到C盤根目錄下的temp文件夾)。被寫入到硬盤裏的rows是不可見的/不
          可訪問的。只有還保存在內存裏的才能夠被訪問到。 
          注:HSSFWorkbook和XSSFWorkbook的Excel Sheet導出條數上限(<=2003版)是65535行、256列,(>=2007版)
               是1048576行,16384列,若是數據量超過了此上限,那麼能夠使用SXSSFWorkbook來導出。實際上上萬條數據,
               甚至上千條數據就能夠考慮使用SXSSFWorkbook了。
        注意:首先須要引入依賴:注意:4.0.0版本的JDK須要1.8以上,若是JDK是1.7的,那麼就使用3.9版本的依賴java

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml-schemas -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.0</version>
</dependency>
二:實例一,咱們使用SXSSFWorkbook向Excel中寫入50萬條數據,只須要         34秒左右,內存佔用率最多在700M左右,CPU使用率在25%左右           
        apache

           代碼以下:windows

package com.test.POI;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class SXSSFWORKBookUtils {

@SuppressWarnings("resource")
public static void main(String[] args) throws FileNotFoundException, InvalidFormatException {
long startTime = System.currentTimeMillis();
String filePath = "E:\\txt\\111.xlsx";
SXSSFWorkbook sxssfWorkbook = null;
BufferedOutputStream outputStream = null;
try {
//這樣表示SXSSFWorkbook只會保留100條數據在內存中,其它的數據都會寫到磁盤裏,這樣的話佔用的內存就會不多
sxssfWorkbook = new SXSSFWorkbook(getXSSFWorkbook(filePath),100);
//獲取第一個Sheet頁
SXSSFSheet sheet = sxssfWorkbook.getSheetAt(0);
for (int i = 0; i < 50; i++) {
for (int z = 0; z < 10000; z++) {
SXSSFRow row = sheet.createRow(i*10000+z);
for (int j = 0; j < 10; j++) {
row.createCell(j).setCellValue("你好:"+j);
}
}
}
outputStream = new BufferedOutputStream(new FileOutputStream(filePath));
sxssfWorkbook.write(outputStream);
outputStream.flush();
sxssfWorkbook.dispose();// 釋放workbook所佔用的全部windows資源
} catch (IOException e) {
e.printStackTrace();
}finally {
if(outputStream!=null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
}


/**
* 先建立一個XSSFWorkbook對象
* @param filePath
* @return
*/
public static XSSFWorkbook getXSSFWorkbook(String filePath) {
XSSFWorkbook workbook = null;
BufferedOutputStream outputStream = null;
try {
File fileXlsxPath = new File(filePath);
outputStream = new BufferedOutputStream(new FileOutputStream(fileXlsxPath));
workbook = new XSSFWorkbook();
workbook.createSheet("測試Sheet");
workbook.write(outputStream);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(outputStream!=null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return workbook;
}

}
  效果:
      xss

三:咱們使用XSSFWorkbook常規的方法分批向excel中寫入50萬條數據,內         存佔用率最多在  2.1個G左右(佔用了很大的內存),CPU使用率在90%           左右 ,最後內存 溢出了
          
          代碼以下:
          測試

package com.test;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class POIController {
/**
* 這種方式效率比較低而且特別佔用內存,數據量越大越明顯
* @param args
* @throws FileNotFoundException
* @throws InvalidFormatException
*/
public static void main(String[] args) throws FileNotFoundException, InvalidFormatException {
long startTime = System.currentTimeMillis();
BufferedOutputStream outPutStream = null;
XSSFWorkbook workbook = null;
FileInputStream inputStream = null;
String filePath = "E:\\txt\\666.xlsx";
try {
workbook = getWorkBook(filePath);
XSSFSheet sheet = workbook.getSheetAt(0);
for (int i = 0; i < 50; i++) {
for (int z = 0; z < 10000; z++) {
XSSFRow row = sheet.createRow(i*10000+z);
for (int j = 0; j < 10; j++) {
row.createCell(j).setCellValue("你好:"+j);
}
}
//每次要獲取新的文件流對象,避免將以前寫入的數據覆蓋掉
outPutStream = new BufferedOutputStream(new FileOutputStream(filePath));
workbook.write(outPutStream);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(outPutStream!=null) {
try {
outPutStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream!=null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(workbook!=null) {
try {
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long endTime = System.currentTimeMillis();
System.out.println(endTime-startTime);
}
/**
* 先建立一個XSSFWorkbook對象
* @param filePath
* @return
*/
public static XSSFWorkbook getWorkBook(String filePath) {
XSSFWorkbook workbook = null;
try {
File fileXlsxPath = new File(filePath);
BufferedOutputStream outPutStream = new BufferedOutputStream(new FileOutputStream(fileXlsxPath));
workbook = new XSSFWorkbook();
workbook.createSheet("測試");
workbook.write(outPutStream);
} catch (Exception e) {
e.printStackTrace();
}
return workbook;
}

}
效果:
   
        
————————————————
版權聲明:本文爲CSDN博主「愛上口袋的天空」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/k_520_w/article/details/84404652大數據

相關文章
相關標籤/搜索