之前寫過一篇 Java 讀取 Excel 文件(xls, xlsx) – 使用 Apache POI,記錄用 POI 讀取 Excel 的教學,這篇要補足「寫入」的教學。
小蛙會切割成幾個步驟來講(還沒有下載跟導入 POI 的話,請先看前一篇)
小蛙最近要用到,之前都是這樣子寫,但是後來發現當要寫的資料大到一定程度的時候,這樣的寫法會出問題,所以最後面會加映寫出大量資料時候的作法,不過其實也可以直接用最後面的那種做法就好了!
開啟 Excel – 讀入既有的
程式碼如下,直接看應該不難看懂,多寫 .xls 跟 .xlsx 的判斷,如果自己使用的狀況有固定,就不需要多做這一步驟,直接去建立 xls 對應的 HSSFWorkbook
或 xlsx 對應的 XSSFWorkbook
。
// 讀取既有的 String path = "要匯出的檔案 e.g. C:\\測試.xlsx"; Workbook wb = null; String extString = path.substring(path.lastIndexOf(".")); InputStream is = new FileInputStream(path); if(".xls".equals(extString)){ wb = new HSSFWorkbook(is); }else if(".xlsx".equals(extString)){ wb = new XSSFWorkbook(is); }
開啟 Excel – 建立新的
如果本來沒有這個檔案就要用這段,先直接 new 出對應的 Workbook,在後面的步驟再把 Excel 寫出。
// 開新檔案 String path = "要匯出的檔案 e.g. C:\\測試.xlsx"; Workbook wb = null; String extString = path.substring(path.lastIndexOf(".")); if(".xls".equals(extString)){ wb = new HSSFWorkbook(); }else if(".xlsx".equals(extString)){ wb = new XSSFWorkbook(); }else{ System.out.println("無效檔案"); return; }
設定儲存格資料
POI 對 Excel 的處理脈絡是這樣,先有一個 Workbook,把他看成是一個 Excel,下一層是頁籤 Sheet,再下一層是橫的 Row,最後就是儲存格 Cell,前面的步驟我們建立(取得)了 Workbook,下一步就是要建立 Sheet > Row > Cell,只要記住這個順序很快就可以把自己要寫的資料設定好了,下面的程式碼是把九九乘法表輸出到 Excel 裡。
// 設定儲存格資料 Sheet sheet = wb.createSheet(); Row row = null; Cell cell = null; for(int r = 0; r < 9; r++){ row = sheet.createRow(r); for(int c = 0; c < 9; c++){ cell = row.createCell(c); cell.setCellValue( (c + 1) + " x " + (r + 1) + " = " + ((r + 1) * (c + 1)) ); } }
寫出 Excel
內容都設置好之後,最後一個步驟就是把這些變動寫到 Excel 檔案上啦!
// 寫出 Excel try { FileOutputStream fos = new FileOutputStream(new File(path)); wb.write(fos); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); }
到這邊就結束了!很簡單吧!上面全部組合起來應該就可以動了。
處理大量資料
如果資料量非常大的話,以小蛙的狀況來說要寫的資料量超過 3000 筆的時候,就會一直噴 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
的錯誤,Google 查了一些資料發現除了上面提到的 HSSFWorkbook
跟 XSSFWorkbook
之外,還有一個叫做 SXSSFWorkbook
的類別。
SXSSFWorkbook
的運作方式跟 HSSFWorkbook
及 XSSFWorkbook
不同,SXSSFWorkbook
會先以「暫存檔」的方式寫回硬碟,最後輸出的時候再把他們存回 Excel 裡面,這樣一來就不會出現 Out Of Memory 的問題啦!不過如果內容處理沒弄好也還是會 OOM 就是~附上相關程式碼。
// 大量資料用 SXSSFWorkbook String path = "要匯出的檔案 e.g. C:\\測試.xlsx"; // 設定幾筆之後,就先寫到硬碟的暫存檔 SXSSFWorkbook wb = new SXSSFWorkbook(100); Sheet sheet = wb.createSheet(); FileOutputStream fileOut = new FileOutputStream(path); Row row = null; Cell cell = null; for(int r = 0; r < 9; r++){ row = sheet.createRow(r); for(int c = 0; c < 9; c++){ cell = row.createCell(c); cell.setCellValue( (c + 1) + " x " + (r + 1) + " = " + ((r + 1) * (c + 1))); } } wb.write(fileOut); fileOut.flush(); fileOut.close(); wb.dispose();