JAVA導出上萬行Excel數據的解決方案


Java Web開發中,經常需要導出大量的數據到Excel,動輒就上千,上萬行的數據讓我們的程序感覺壓力很大,甚至都出現無法導出的情況,使用POIJXL直接生成Excel,很容易就造成內存溢出了。即使不溢出,由於代碼執行耗時太久也會長時間阻塞web頁面,導致web系統併發訪問性能急劇下降。


怎麼解決內存溢出問題呢?用POI處理的話,畢竟數據還是一次性在內存中進行保存的,數據量太大JVM就內存溢出了,這時我們想是不是可以導出多個Excel呢?


沿着這個思路去想問題,首先我們要確定數據量有多大,然後確定一個Excel導出多少條數據,這樣就可以確定導出的Excel的數量,於是我們就可以循環的導出Excel並保存在任意的臨時目錄中去,這樣如果內存不夠的話虛擬機就會去進行回收已經保存的Excel在內存中的空間。


假設我們我們已經成功的生成了多個Excel,這時我們怎麼把這NExcel文檔傳到客戶端展示呢?其實一個一個的傳也未嘗不可,但是考慮那樣對用戶來說體驗不夠好,用戶保存一個個文件到本地再打開,再一個一個瀏覽或者打印很是不方便。


用生成多個文件發送到客戶端的方案增加了開發難度,生成文件的速度也更慢了。如果換一種方式,繞過JVM的內存限制問題應該怎麼解決呢?可以在客戶端生成文件。


網上能找到幾家做在線編輯office文件的產品,有的提供了js調用OfficeVBA接口的對象,採用在客戶端打開文件時,用js通過VBA接口把數據填充到Excel單元格中去生成文件,這樣就繞過了服務器上內存溢出的問題,減輕了服務器的壓力,是不是可行呢?經測試,此方式生成幾千行數據的Excel表格速度就比較慢了,一旦上萬行數據,執行效率就會急速降低甚至程序死掉。更爲可怕的是,怎麼把後臺代碼查詢的數據集的上萬行數據傳遞給前臺頁面的js,編程更痛苦。沒有更好的方法了嗎?也不是。


本人最近研究了一個國產的商業軟件PageOffice,本質上也是在客戶端生成Excel表格的,但是這個產品提供的是服務器端的編程對象,接口很簡單,調用起來比js舒服多了,通過對這個產品提供的服務器端Excel操作對象編程,客戶端就能在用戶需要Excel表格的時候實時生成,也同時解決了文件的在線預覽和打印問題。PageOffice肯定是對Excel的接口做過深度優化的,本人測試的結果,填充上萬行數據也能瞬間完成,還支持賦值公式、單元格樣式和文本樣式的設置(由於本人開發的項目中無需處理這些,對於這些功能沒做研究,所以無法做深入的描述),所以在此與大家分享一下,有興趣可以去PageOffice的官網下載一個試用版測試。



本人測試PageOffice導出2萬行Excel表格的代碼:


Workbook wb =new Workbook();

Sheet sheet1 =wb.openSheet("Sheet1");

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");//此行必須



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章