在Java Web開發中,常常須要導出大量的數據到Excel,動輒就上千,上萬行的數據讓咱們的程序感受壓力很大,甚至都出現沒法導出的狀況,使用POI、JXL直接生成Excel,很容易就形成內存溢出了。即便不溢出,因爲代碼執行耗時過久也會長時間阻塞web頁面,致使web系統併發訪問性能急劇降低。web
怎麼解決內存溢出問題呢?用POI處理的話,畢竟數據仍是一次性在內存中進行保存的,數據量太大JVM就內存溢出了,這時咱們想是否是能夠導出多個Excel呢?編程
沿着這個思路去想問題,首先咱們要肯定數據量有多大,而後肯定一個Excel導出多少條數據,這樣就能夠肯定導出的Excel的數量,因而咱們就能夠循環的導出Excel並保存在任意的臨時目錄中去,這樣若是內存不夠的話虛擬機就會去進行回收已經保存的Excel在內存中的空間。服務器
假設咱們咱們已經成功的生成了多個Excel,這時咱們怎麼把這N個Excel文檔傳到客戶端展現呢?其實一個一個的傳也何嘗不可,可是考慮那樣對用戶來講體驗不夠好,用戶保存一個個文件到本地再打開,再一個一個瀏覽或者打印非常不方便。併發
用生成多個文件發送到客戶端的方案增長了開發難度,生成文件的速度也更慢了。若是換一種方式,繞過JVM的內存限制問題應該怎麼解決呢?能夠在客戶端生成文件。ide
網上能找到幾家作在線編輯office文件的產品,有的提供了js調用Office的VBA接口的對象,採用在客戶端打開文件時,用js經過VBA接口把數據填充到Excel單元格中去生成文件,這樣就繞過了服務器上內存溢出的問題,減輕了服務器的壓力,是否是可行呢?經測試,此方式生成幾千行數據的Excel表格速度就比較慢了,一旦上萬行數據,執行效率就會急速下降甚至程序死掉。更爲可怕的是,怎麼把後臺代碼查詢的數據集的上萬行數據傳遞給前臺頁面的js,編程更痛苦。沒有更好的方法了嗎?也不是。性能
本人最近研究了一個國產的商業軟件PageOffice,本質上也是在客戶端生成Excel表格的,可是這個產品提供的是服務器端的編程對象,接口很簡單,調用起來比js舒服多了,經過對這個產品提供的服務器端Excel操做對象編程,客戶端就能在用戶須要Excel表格的時候實時生成,也同時解決了文件的在線預覽和打印問題。PageOffice確定是對Excel的接口作過深度優化的,本人測試的結果,填充上萬行數據也能瞬間完成,還支持賦值公式、單元格樣式和文本樣式的設置(因爲本人開發的項目中無需處理這些,對於這些功能沒作研究,因此沒法作深刻的描述),因此在此與你們分享一下,有興趣能夠去PageOffice的官網下載一個試用版測試。測試
附本人測試PageOffice導出2萬行Excel表格的代碼:優化
Workbook wb =new Workbook();spa
Sheet sheet1 =wb.openSheet("Sheet1");orm
Table table =sheet1.openTable("B1:F2");
for(int i=0;i<20000;i++) {
table.getDataFields().get(0).setValue(String.valueOf(i));//B列
table.getDataFields().get(1).setValue("測試");//C列
table.getDataFields().get(2).setValue("測試");//D列
table.getDataFields().get(3).setValue("測試");//E列
table.getDataFields().get(4).setValue("測試");//F列
table.nextRow();
}
table.close()
PageOfficeCtrlpoCtrl1 = new PageOfficeCtrl(request);
poCtrl1.setServerPage("poserver.do");//此行必須
poCtrl1.webOpen("doc/template.xlsx",OpenModeType.xlsSubmitForm, "");
poCtrl1.setTagId("PageOfficeCtrl1");//此行必須