1. 程式人生 > >Java實現百萬行資料分批量匯入Excel的優化方案

Java實現百萬行資料分批量匯入Excel的優化方案

1》場景

  專案中需要從資料庫中匯出100萬行資料,以excel形式下載並且只要一張sheet(開啟這麼大檔案有多慢另說,呵呵)。

psxlsx最大容納1048576行 ,csv最大容納1048576行,xls最大容納65536行,但是存放相同的資料量 檔案大小排序:xls>csv>xlsx xlsbiff8的二進位制檔案,就是個B+樹而xlsxxmlzip壓縮檔案。

2》常規做法

  按照平常的做法,先到資料庫中取數然後迴圈組裝成一個list,然後用excel工具(我用的是POI)生成excel

3》遇到的問題

1' 記憶體經常溢位。

2' 組裝list,生成excel慢,50萬的資料花了一個小時都沒見完成。

4》解決方法

1' POI 改用 SXSSFWorkbook 參看 比如SXSSFWorkbook wb = new SXSSFWorkbook(100);在記憶體中只保留100行記錄,超過100就將之前的儲存到磁盤裡,

      2' 調整JVM 相關的引數 -Xmx....

   3' 迴圈中減少使用new,儘量複用;String改為StringBuffer就不說了,重點是在組裝一行資料時,一直比較喜歡用map來拼裝,但是在我功能上發現還是耗記憶體的,後來的GC時間太長,造成嚴重拖累組裝資料的效率,後來發現由HashMap改為用StringBuffer拼接行資料效率直接就上去了,當然指定合理的StringBuffer

的起始容量效率就更好了。

ps:StringBuffer 的構造器會建立一個預設大小(通常是16)的字元陣列。在使用中,如果超出這個大小,就會重新分配記憶體,建立一個更大的陣列,並將原先的陣列複製過來,再丟棄舊的陣列。在大多數情況下,你可以在建立 StringBuffer的時候指定大小,這樣就避免了在容量不夠的時候自動增長,以提高效能。

      4' 下載任務由同步改為非同步,使用者提交了後只要等待郵件通知即可,我用了quartz

5》效果

    100萬資料組裝以及生成excel大概要10分鐘,平均下來1分鐘10萬條,我的小黑腰不酸腿不疼了。

好了就這些,我也看了,網上匯出很多是分批匯出或者用csv的解決的,但是我就這樣的需求,人家任性沒辦法,我的方法還有待完善的地方,歡迎交流。

更多方法,親請關注微信公眾號,搜尋“90創業啪”或,“gh_1803176216d0”。