2015-04-23 110 views
1

我需要使用Apache POI將600-700K記錄寫入xlsx文件。 我目前使用的代碼是:性能:使用Java,Apache-POI將Oracle ResultSet寫入XLSX

public void writeRecords(ResultSet rs) { 
      try{ 

      SXSSFWorkbook wb = new SXSSFWorkbook(); 
      wb.setCompressTempFiles(true); 

      SXSSFSheet sh = (SXSSFSheet)wb.createSheet("Sheet 1"); 
      Row row = null; 


      int numColumns = rs.getMetaData().getColumnCount(); 

       // Workbook wb = ExcelFileUtil.createExcelWorkBook(true, 5); 


       sh.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk 
       Row heading = sh.createRow(1); 

       ResultSetMetaData rsmd = rs.getMetaData(); 

       for(int x = 0; x < numColumns; x++) { 
        Cell cell = heading.createCell(x+1); 
        cell.setCellValue(rsmd.getColumnLabel(x+1)); 
       } 

       int rowNumber = 2; 
       int sheetNumber = 0; 

       while(rs.next()) { 

        row = sh.createRow(rowNumber); 
        for(int y = 0; y < numColumns; y++) { 
         row.createCell(y+1).setCellValue(rs.getString(y+1)); 
         // wb.write(bos); 
        } 

        rowNumber++; 
       } 

       FileOutputStream out = new FileOutputStream("C:/Users/test1.xlsx"); 
       wb.write(out); 
       out.close(); 
      } 
       catch (Exception e){ 
        e.printStackTrace(); 

       } 

它工作正常,但它走約50分鐘的時間寫〜65K的記錄。65分鐘記錄的結果集在5-6分鐘內被提取。

有什麼辦法可以在10-15分鐘內用POI寫出600,000-700,000條記錄 。 我們無法將數據導出爲CSV格式,因爲最終用戶只能導入xlsx文件。 關於, Tushar

+1

運行你怎麼知道的ResultSet在7秒內是牽強?在上面的代碼中,您仍然在寫入行時進行提取。 – Thilo

+0

另外,如果Excel將700k行的電子表格放在電子表格中,Excel的行爲如何?那個文件有多大? – Thilo

+0

我之前和之後記錄的時間戳:\t ps = con.prepareStatement(「select * from table_1 where rownum <65000」); \t \t rs = ps.executeQuery(); – Tushar

回答

3

檢查PreparedStatement的fetchSize。如果沒有明確設置,則與表格的實際情況相比,該值可能非常小,並且大中型數據的查詢速度看起來很非常影響

Check this question欲瞭解更多信息。

此外,請考慮是否有必要根本使用setCompressTempFilesSXSSFWorkbook。如果需要,內存中的行值將以成比例的方式影響性能。

0

如果你能夠寫入文件輸出形式爲sqlplus,這將是非常快的。

創建文件,如下mycsv.sql:

SET DEFINE OFF 
    SET ECHO OFF 
    SET SERVEROUTPUT OFF 
    SET TERMOUT OFF 
    SET VERIFY OFF 
    SET FEEDBACK OFF 
    SET PAGESIZE 10000 
    SET ARRAYSIZE 5000 
    REM SET HEAD OFF 
    SET LINE 500 
    spool /tmp/mycsvfile.csv; 
    select * from MY_table; 
    spool off; 
    exit; 

和Linux的提示,你可以像

$> sqlplus username/password @/tmp/mycsv.sql 
+0

根本不回答問題。 – rpax

+0

嗨,我的意思是,你最終的目標是在一個文件中寫輸出,然後使用sqlplus。這樣做sqlplus會更快 – Ramki

+1

嗨。我的意思是,如果你的最終目標是在一個文件中寫入csv輸出,然後使用sqlplus。 1.在sqlplus中執行會更快。 2.如果Apache中的數據非常高,則可能出現內存不足錯誤。 3.從數據庫獲取數據到Apache並寫入一個文件,我說的是刪除中間的Apache層,這將是很好的優勢。我希望這很清楚。 – Ramki