導航:首頁 > 網路數據 > poi311大數據量

poi311大數據量

發布時間:2022-12-30 07:58:45

java怎麼在數據超過百萬後分頁導出

用過POI的人都知道,在POI以前的版本中並不支持大數據量的處理,如果數據量過多還會常報OOM錯誤,
這時候調整JVM的配置參數
也不是一個好對策(註:
jdk在32位系統中支持的內存不能超過2個G,而在64位中沒有限制,但是在64位的系統中,性能並不是太好
),好在POI3.8版本新出來了一個SXSSFWorkbook對象,它就是用來解決大數據量以及超大數據量的導入導出操作的,但是SXSSFWorkbook只支持.xlsx格式,不支持.xls格式的Excel文件
這里普及一下,在POI中使用HSSF對象時,excel 2003最多隻允許存6553數據,一般用來處理較少的數據量,這時對於百萬級別數據,Excel肯定
容納不了,而且在計算機性能稍低的機器上測試,就很容易導致堆溢出。當我升級到XSSF對象時,它可以直接支持excel2007以上版本,因為它採用
ooxml格式。這時excel可以支持1048576條數據,單個sheet表就支持近104
萬條數據了,雖然這時導出100萬數據能滿足要求,但使用XSSF測試後發現偶爾還是會發生堆溢出,所以也不適合百萬數據的導出。現在我們知道excel2007及以上版本可以輕松實現存儲百萬級別的數據,但是系統中的大量數據是如何能夠快速准確的導入到excel中這好像是個難題,對於一般的web系統,我們為了解決成本,基本都是使用的入門級web伺服器tomcat,既然我們不推薦調整JVM的大小,那我們就要針對我們的代碼來解決我們要解決的問題。在POI3.8之後新增加了一個類,
SXSSFWorkbook
,採用當數據加工時不是類似前面版本的對象,它可以控制excel數據佔用的內存,他通過控制在內存中的行數來實現資源管理,即當創建對象超過了設定的行數,它會自動刷新內存,將數據寫入文件,
這樣導致列印時,佔用的CPU,和內存很少。但有人會說了,我用過這個類啊,他好像並不能完全解決,當數據量超過一定量後還是會內存溢出的,而且時間還很長。對你只是用了這個類,但是你並沒有針對你的需求進行相應的設計,僅僅是用了,所以接下來我要說的問題就是,如何通過SXSSFWorkbook以及相應的寫入設計來實現百萬級別的數據快速寫入。
我先舉個例子,以前我們[資料庫
中存在大量的數據,我們要查詢,怎麼辦?我們在沒有經過設計的時候是這樣來處理的,先寫一個集合,然後執行jdbc,將返回的結果賦值給list,然後再返回到頁面上,但是當數據量大的時候,就會出現數據無法返回,內存溢出的情況,於是我們在有限的時間和空間下,通過分頁將數據一頁一頁的顯示出來,這樣可以避免了[大數據
量數據對內存的佔用,也提高了用戶的體驗,在我們要導出的百萬數據也是一個道理,內存突發性佔用,我們可以限制導出數據所佔用的內存,
這里我先建立一個list容器,list中開辟10000行的存儲空間,每次存儲10000行,用完了將內容清空,然後重復利用
,這樣就可以有效控制內存,所以我們的設計思路就基本形成了,所以分頁數據導出共有以下3個步驟:
1、求資料庫中待導出數據的行數
2、根據行數求數據提取次數
3、按次數將數據寫入文件

㈡ java poi Excel大數據量導入怎麼提高速度

記得有個屬性,

POI3.8的SXSSF包是XSSF的一個擴展版本,支持流處理,在生成大數據量的電子表內格且堆空間有容限時使用。SXSSF通過限制內存中可訪問的記錄行數來實現其低內存利用,當達到限定值時,新一行數據的加入會引起老一行的數據刷新到硬碟。
比如內存中限制行數為100,當行號到達101時,行號為0的記錄刷新到硬碟並從內存中刪除,當行號到達102時,行號為1的記錄刷新到硬碟,並從內存中刪除,以此類推。
rowAccessWindowSize代表指定的內存中緩存記錄數,默認為100,此值可以通過
new SXSSFWorkbook(int rowAccessWindowSize)或SXSSFSheet.setRandomAccessWindowSize(int windowSize)來設置。

㈢ EXCEL大數據量導出的解決方案

EXCEL大數據量導出的解決方案
將web頁面上顯示的報表導出到excel文件里是一種很常見的需求。潤乾報表的類excel模型,支持excel文件數據無失真的導入導出,使用起來非常的方便。然而,當數據量較大的情況下,excel本身的支持最多65535行數據的問題便凸顯出來。下面就給出大數據量導出到excel的解決方案。
首先,對於數據超過了65535行的問題,很自然的就會想到將整個數據分塊,利用excel的多sheet頁的功能,將超出65535行後的數據寫入到下一個sheet頁中,即通過多sheet頁的方式,突破了最高65535行數據的限定。
具體做法就是:
單獨做一個鏈接,使用JSP導出,在JSP上通過程序判斷報錶行數,超過65535行後分SHEET寫入。這樣這個問題就得以解決了。
更進一步地說,在這種大數據量的報表生成和導出中,要佔用大量的內存,尤其是在使用TOMCAT的情況下,JVM最高只能支持到2G內存,則會發生內存溢出的情況。此時的內存開銷主要是兩部分,一部分是該報表生成時的開銷,另一部分是該報表生成後寫入一個EXCEL時的開銷。由於JVM的GC機制是不能強制回收的,因此,對於此種情形,我們給出一個變通的解決方案。
首先,將該報表設置起始行和結束行參數,在API生成報表的過程中,分步計算報表,比如一張20萬行數據的報表,在生成過程中,可通過起始行和結束行分4-5次進行。這樣,就降低了報表生成時的內存佔用,在後面報表生成的過程中,如果發現內存不夠,即可自動啟動JVM的GC機制,回收前面報表的緩存。
導出EXCEL的過程,放在每段生成報表之後立即進行,改多個SHEET頁為多個EXCEL,即在分步生成報表的同時分步生成EXCEL,則通過POI包生成EXCEL的內存消耗也得以降低。通過多次生成,同樣可以在後面EXCEL生成所需要的內存不足時,有效回收前面生成EXCEL時佔用的內存。
再使用文件操作,對每個客戶端的導出請求在伺服器端根據SESSIONID和登陸時間生成唯一的臨時目錄,用來放置所生成的多個EXCEL,然後調用系統控制台,打包多個EXCEL為RAR或者JAR方式,最終反饋給用戶一個RAR包或者JAR包,響應客戶請求後,再次調用控制台刪除該臨時目錄。
使用這種方法,首先是通過分段運算和生成,有效降低了報表從生成結果到生成EXCEL的內存開銷。其次是通過使用壓縮包,響應給用戶的生成文件體積大大縮小,降低了多用戶並發訪問時伺服器下載文件的負擔,有效減少多個用戶導出下載時伺服器端的流量,從而達到進一步減輕伺服器負載的效果。

㈣ xssfworkbook 怎麼解決科學計演算法

POI之前的版本不支持大數據量處理,如果數據過多則經常報OOM錯誤,有時候調整JVM大小效果也不是太好。3.8版本的POI新出來了SXSSFWorkbook,可以支持大數據量的操作,只是SXSSFWorkbook只支持.xlsx格式,不支持.xls格式。
3.8版本的POI對excel的導出操作,一般只使用HSSFWorkbook以及SXSSFWorkbook,HSSFWorkbook用來處理較少的數據量,SXSSFWorkbook用來處理大數據量以及超大數據量的導出。
HSSFWorkbook的使用方法和之前的版本的使用方法一致,這里就不在陳述使用方法了
SXSSFWorkbook的使用例子如下:
import junit.framework.Assert;
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 static void main(String[] args) throws Throwable {
Workbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk
Sheet sh = wb.createSheet();
for(int rownum = 0; rownum < 100000; 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("/temp/sxssf.xlsx");
wb.write(out);
out.close();
}

㈤ poi讀取excel2007(大數據),然後保存到資料庫中

導致內存溢出是因為太多了內存不夠用,你可以先讀一部分然後做個標記,先把讀到的這部分數據寫入到資料庫里。然後再從標記處開始讀一部分再寫入,再讀再寫直到完。不要一次性全部讀完。

㈥ java利用poi讀大數據量xlsx除了用xml方式讀取外,還有其他方法嗎

poi是把excel當做【文來檔】來處理源的,自然只有XSSFWorkbook類來操作它,也就是你說的xml方式。在poi的眼裡,excel文檔里的並不是【數據】而是【表格】。
你如果想要把excel當做【數據源】來處理,應該用odbc的方式,將你需要的excel文件變成一個odbc數據源,然後用ResultSet set = smt.executeQuery("select * from [sheet1$]");來讀取數據,效率跟access表現相當(畢竟excel有數據量上限,實際表現大多數時候都比access還要快)

㈦ poi操作excel表,怎麼將單元格的格式設置為

通過poi導出excel的過程大致是這樣的:
規定單元格的格式

創建單元格

設置單元格的格式

設置數據的格式

把數據存放到單元格中

通過IO流輸出

背景POI導出Excel時設置單元格類型為數值類型
要想存放數值的單元格以數值類型導出,其中最關鍵的步驟就是上面加粗的兩步,設置單元格的格式和向單元格中存放數據。
核心代碼如下:
/**
* 導出Excel-胡玉洋-2015年11月11日
*
*@param outPutParam Excel數據實體,包括要導出的excel標頭、列標題、數據等
* */
private void createContentRows(ExcelParam outPutParam) {
HSSFWorkbook workbook=new HSSFWorkbook(); //創建一個Excel文件
// 遍歷集合數據,產生數據行
for (int i = 0; i < outPutParam.getContent().size(); i++) {
int rowIndex = i + 2;
HSSFRow contentRow = sheet.createRow(rowIndex);
Map<String, Object> rowDate = outPutParam.getContent().get(i);
//遍歷列
for (int j = 0; j < outPutParam.getTitleList().size(); j++) {
Title headTitle = outPutParam.getTitleList().get(j);//獲取第i行第j列列標題
String headerName = headTitle.getName();//獲取第j列列標識
Object data = rowDate.get(headerName);//獲取第i行第j列所放數據
HSSFCellStyle contextstyle =workbook.createCellStyle();
HSSFCell contentCell = contentRow.createCell(j);
Boolean isNum = false;//data是否為數值型
Boolean isInteger=false;//data是否為整數
Boolean isPercent=false;//data是否為百分數
if (data != null || "".equals(data)) {
//判斷data是否為數值型
isNum = data.toString().matches("^(-?\\d+)(\\.\\d+)?$");
//判斷data是否為整數(小數部分是否為0)
isInteger=data.toString().matches("^[-\\+]?[\\d]*$");
//判斷data是否為百分數(是否包含「%」)
isPercent=data.toString().contains("%");
}

//如果單元格內容是數值類型,涉及到金錢(金額、本、利),則設置cell的類型為數值型,設置data的類型為數值類型
if (isNum && !isPercent) {
HSSFDataFormat df = workbook.createDataFormat(); // 此處設置數據格式
if (isInteger) {
contextstyle.setDataFormat(df.getBuiltinFormat("#,#0"));//數據格式只顯示整數
}else{
contextstyle.setDataFormat(df.getBuiltinFormat("#,##0.00"));//保留兩位小數點
}
// 設置單元格格式
contentCell.setCellStyle(contextstyle);
// 設置單元格內容為double類型
contentCell.setCellValue(Double.parseDouble(data.toString()));
} else {
contentCell.setCellStyle(contextstyle);
// 設置單元格內容為字元型
contentCell.setCellValue(data.toString());
}
}
}
}04142434445464748495051

如上,有兩個比較重要的點:
1、先用正則表達式判斷數據是否為數值型,如果為數值型,則設置單元格格式為整數或者小數;
2、然後往單元格中存放數據的時候要設置數據的格式為double類型,如果查看poi的源碼HSSFCell.java會發現設置數據的方法如下,所以用setCellValue(double)方法即可。


優化
到了這里,您可能以為萬事大吉啊了,其實上面的代碼有個陷阱,如果不經過大數據量的測試是發覺不出來的哦~~
如果數據量大的話,系統可能會報錯「The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook」,原因是style創建的次數太多了,解決這個問題的方法很簡單,在循環體外面創建單元格格式contextstyle(即把它當成一個「全局」變數),不要在循環內部創建。
正確的代碼如下:
/**
* 導出Excel-胡玉洋-2015年11月11日
*
*@param outPutParam Excel數據實體,包括要導出的excel標頭、列標題、數據等
* */
private void createContentRows(ExcelParam outPutParam) {
HSSFWorkbook workbook=new HSSFWorkbook(); //創建一個Excel文件
HSSFCellStyle contextstyle =workbook.createCellStyle();
// 遍歷集合數據,產生數據行
for (int i = 0; i < outPutParam.getContent().size(); i++) {
int rowIndex = i + 2;
HSSFRow contentRow = sheet.createRow(rowIndex);
Map<String, Object> rowDate = outPutParam.getContent().get(i);
//遍歷列
for (int j = 0; j < outPutParam.getTitleList().size(); j++) {
Title headTitle = outPutParam.getTitleList().get(j);//獲取第i行第j列列標題
String headerName = headTitle.getName();//獲取第j列列標識
Object data = rowDate.get(headerName);//獲取第i行第j列所放數據
HSSFCell contentCell = contentRow.createCell(j);
Boolean isNum = false;//data是否為數值型
Boolean isInteger=false;//data是否為整數
Boolean isPercent=false;//data是否為百分數
if (data != null || "".equals(data)) {
//判斷data是否為數值型
isNum = data.toString().matches("^(-?\\d+)(\\.\\d+)?$");
//判斷data是否為整數(小數部分是否為0)
isInteger=data.toString().matches("^[-\\+]?[\\d]*$");
//判斷data是否為百分數(是否包含「%」)
isPercent=data.toString().contains("%");
}

//如果單元格內容是數值類型,涉及到金錢(金額、本、利),則設置cell的類型為數值型,設置data的類型為數值類型
if (isNum && !isPercent) {
HSSFDataFormat df = workbook.createDataFormat(); // 此處設置數據格式
if (isInteger) {
contextstyle.setDataFormat(df.getBuiltinFormat("#,#0"));//數據格式只顯示整數
}else{
contextstyle.setDataFormat(df.getBuiltinFormat("#,##0.00"));//保留兩位小數點
}
// 設置單元格格式
contentCell.setCellStyle(contextstyle);
// 設置單元格內容為double類型
contentCell.setCellValue(Double.parseDouble(data.toString()));
} else {
contentCell.setCellStyle(contextstyle);
// 設置單元格內容為字元型
contentCell.setCellValue(data.toString());
}
}
}
}04142434445464748495051

㈧ 求Java poi 大數據量導出(五萬行數據) 例子

我給你個辦法,是要導出excel嗎?別使用poi,使用xml來描述excel即可,就像流文件一樣,多少都不會流出,給你個思路,你自己擴展,希望你能看明白。

/**
* @author J.W
* 2011-06-08
*/
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
try {
DataOutputStream rafs = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(new File(
"d://test.xml"))));
sb.append("<?xml version=\"1.0\"?>");
sb.append("\n");
sb.append("<?mso-application progid=\"Excel.Sheet\"?>");
sb.append("\n");
sb.append("<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"");
sb.append("\n");
sb.append(" xmlns:o=\"urn:schemas-microsoft-com:office:office\"");
sb.append("\n");
sb.append(" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"");
sb.append("\n");
sb.append(" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"");
sb.append("\n");
sb.append(" xmlns:html=\"http://www.w3.org/TR/REC-html40\">");
sb.append("\n");
sb.append(" <Styles>\n");
sb.append(" <Style ss:ID=\"Default\" ss:Name=\"Normal\">\n");
sb.append(" <Alignment ss:Vertical=\"Center\"/>\n");
sb.append(" <Borders/>\n");
sb.append(" <Font ss:FontName=\"宋體\" x:CharSet=\"134\" ss:Size=\"12\"/>\n");
sb.append(" <Interior/>\n");
sb.append(" <NumberFormat/>\n");
sb.append(" <Protection/>\n");
sb.append(" </Style>\n");
sb.append(" </Styles>\n");
int sheetcount = 0;
int recordcount = 20;
int currentRecord = 0;
int total = 100;
int col = 20;
sb.append("<Worksheet ss:Name=\"Sheet0\">");
sb.append("\n");
sb.append("<Table ss:ExpandedColumnCount=\"" + col
+ "\" ss:ExpandedRowCount=\"" + total
+ "\" x:FullColumns=\"1\" x:FullRows=\"1\">");
sb.append("\n");
for (int i = 0; i < total; i++) {
if ((currentRecord == recordcount
|| currentRecord > recordcount || currentRecord == 0)
&& i != 0) {// 一個sheet寫滿
currentRecord = 0;
rafs.write(sb.toString().getBytes());
sb.setLength(0);
sb.append("</Table>");
sb.append("<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">");
sb.append("\n");
sb.append("<ProtectObjects>False</ProtectObjects>");
sb.append("\n");
sb.append("<ProtectScenarios>False</ProtectScenarios>");
sb.append("\n");
sb.append("</WorksheetOptions>");
sb.append("\n");
sb.append("</Worksheet>");
sb.append("<Worksheet ss:Name=\"Sheet" + i / recordcount
+ "\">");
sb.append("\n");
sb.append("<Table ss:ExpandedColumnCount=\"" + col
+ "\" ss:ExpandedRowCount=\"" + recordcount
+ "\" x:FullColumns=\"1\" x:FullRows=\"1\">");
sb.append("\n");
}
sb.append("<Row>");
for (int j = 0; j < col; j++) {
System.out.println(i);
sb.append("<Cell><Data ss:Type=\"String\">10000000000000000123</Data></Cell>");
sb.append("\n");
}
sb.append("</Row>");
if (i % 5000 == 0) {
rafs.write(sb.toString().getBytes());
rafs.flush();
sb.setLength(0);
}
sb.append("\n");
currentRecord++;
}
rafs.write(sb.toString().getBytes());
sb.setLength(0);
sb.append("</Table>");
sb.append("<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">");
sb.append("\n");
sb.append("<ProtectObjects>False</ProtectObjects>");
sb.append("\n");
sb.append("<ProtectScenarios>False</ProtectScenarios>");
sb.append("\n");
sb.append("</WorksheetOptions>");
sb.append("\n");
sb.append("</Worksheet>");
sb.append("</Workbook>");
sb.append("\n");
rafs.write(sb.toString().getBytes());
rafs.flush();
rafs.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

可以直接執行,只是給你個思路。

㈨ java excel poi 大數據量50W 內存溢出

Workbook workbook = new SXSSFWorkbook(1000);
poi有個機制 每次往內存中寫1000條數據,這個1000你可以改的 盡量別大於10000條數據,寫完1000條數據後再內重新寫,這樣就不會內存溢容出了。

㈩ 關於Poi 大數據量Excel 導出時 文件過大的問題 怎麼解決

建議不要導出excel,當前excel中已經有支持cvs文件。
解釋:cvs文件的顯示方式和版xls的顯示方式一樣,並權且此顯示方式的執行效率要高於xls文件的額,因為cvs文件存儲的是數據直接直接用英文逗號分隔,xls是存儲的cell。所以在大量數據的情況下,都是導出為cvs文件。
備註:如果數據過多的話,建議可以分多次查詢導出,不要一次性導出,否則效率會很低。
-

閱讀全文

與poi311大數據量相關的資料

熱點內容
怎麼做編程入門 瀏覽:851
用織夢建手機網站 瀏覽:38
灌南數控編程怎麼學 瀏覽:957
系統apk圖標修改工具 瀏覽:121
蘋果6手機網路沒信號怎麼回事啊 瀏覽:378
手機掃描文件轉換成word 瀏覽:636
手機本地視頻的文件夾在哪裡 瀏覽:908
蘋果11無法安裝app找不到描述文件 瀏覽:363
咋新建cad文件 瀏覽:969
窩窩app怎麼樣自動關 瀏覽:228
蘋果電腦怎麼用wps生成多個文件夾 瀏覽:309
蘋果手機哪裡有賣 瀏覽:83
app登錄狀態為什麼不過期 瀏覽:160
win10創意者無法升級 瀏覽:59
如何查殺後門程序 瀏覽:498
定類數據可以用哪些描述統計方法 瀏覽:278
微信公眾號閱讀全文怎麼跳轉文件 瀏覽:935
迷你編程怎麼免費進入 瀏覽:354
蘋果應用設置密碼 瀏覽:21
windowsmac共享文件夾 瀏覽:274

友情鏈接