2014-07-23 10 views
1

我目前使用apache.poi將數據從數據庫提取到excel。我只是想看看是否有可能加快提取過程。我的JSP中有一個選擇值,要求提取3500行數據,這是唯一一種極其緩慢執行的情況。我從提取中創建兩個獨立的Excel文件。我可以使我的數據提取程序(oracle數據庫爲excel)更高效嗎?

第一類是簡單的數據提取:

private void createSiteFieldExcel(String workSheetName, List<String> columnHeader, List<MasterDataDto> masterDatatDtoList) { 
    XSSFSheet sheet = masterDataWorkbook.createSheet(workSheetName); 
    int cellNumber = 0; 
    int rowNumber = 0; 
    Row headerRow = sheet.createRow(rowNumber++); 
    sheet.createFreezePane(0, 1); 
    List<MasterDataDto> dataConsistencyList = new ArrayList<MasterDataDto>(); 
    for (Iterator<String> iterator = columnHeader.iterator(); iterator.hasNext();) { 
     Cell cell = headerRow.createCell(cellNumber++); 
     cell.setCellValue(iterator.next()); 
     // sets the header to be bold 
     cell.setCellStyle(masterDataBoldStyle); 
    } 
    for (MasterDataDto masterDatatDto : masterDatatDtoList) { 
     Row dataRow = sheet.createRow(rowNumber++); 
     cellNumber = 0; 

     Cell cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(masterDatatDto.getDivision()); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(masterDatatDto.getProject()); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(masterDatatDto.getSiteName()); 

     if (columnHeader.size() == 4) { 
      cell = dataRow.createCell(cellNumber++); 
      cell.setCellValue(masterDatatDto.getField1()); 
      if (masterDatatDto.getField1() == null || masterDatatDto.getField1().trim().equals("")) { 
       dataConsistencyList.add(masterDatatDto); 
      } 
     } else if (columnHeader.size() == 5) { 
      cell = dataRow.createCell(cellNumber++); 
      cell.setCellValue(masterDatatDto.getField1()); 

      cell = dataRow.createCell(cellNumber++); 
      cell.setCellValue(masterDatatDto.getField2()); 

      if (masterDatatDto.getField2() == null || masterDatatDto.getField2().trim().equals("")) { 
       dataConsistencyList.add(masterDatatDto); 
      } 

     } 
     // Auto sizes column width 
     for (int i = 0; i <= 5; i++) 
      sheet.autoSizeColumn(i); 
    } 
    createConsistencyCheckFile(dataConsistencyList, columnHeader); 
    // Auto sizes column width for data consistency excel 
    for (int i = 0; i <= 9 ; i++) 
     dataConsistencyWorksheet.autoSizeColumn(i); 
     dataConsistencyWorksheet.createFreezePane(0, 1); 

} 

第二類是檢查數據的一致性(顯示有在數據庫中不存在空白數據)

private void createConsistencyCheckFile(List<MasterDataDto> dataConsistencyList, List<String> columnHeaders) { 
    Cell cell = null; 
    Row dataRow = null; 
    int cellNumber = 0; 
    dataRow = dataConsistencyWorksheet.createRow(dataConsistencyWorksheetRowNumber++); 


    cell = dataRow.createCell(cellNumber++); 
    cell.setCellValue(dataConsistencyWorksheetRowNumber - 1); 


    cell = dataRow.createCell(cellNumber++); 
    cell.setCellValue("SUMMARY"); 

    cell = dataRow.createCell(cellNumber++); 
    cell.setCellValue(columnHeaders.size() - 1); 

    cell = dataRow.createCell(cellNumber++); 
    cell.setCellValue(dataConsistencyList.size()); 

    for (String columnHeader : columnHeaders) { 
     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(columnHeader); 
    } 

    for (MasterDataDto masterDatatDto : dataConsistencyList) { 

     cellNumber = 0; 
     dataRow = dataConsistencyWorksheet.createRow(dataConsistencyWorksheetRowNumber++); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(dataConsistencyWorksheetRowNumber - 1); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue("DETAIL"); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(columnHeaders.size() - 1); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue("N/A"); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(masterDatatDto.getDivision()); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(masterDatatDto.getProject()); 

     cell = dataRow.createCell(cellNumber++); 
     cell.setCellValue(masterDatatDto.getSiteName()); 

     if (columnHeaders.size() == 4) { 
      cell = dataRow.createCell(cellNumber++); 
      cell.setCellValue("???"); 
     } else if (columnHeaders.size() == 5) { 
      cell = dataRow.createCell(cellNumber++); 
      cell.setCellValue(masterDatatDto.getField1()); 

      cell = dataRow.createCell(cellNumber++); 
      cell.setCellValue("???"); 
     } 

    } 

} 

本來我剛上過第一堂課,雖然需要時間才能完成。由於我添加了數據一致性類部分,因此它在創建的第一個表單後超時。

我最初使用Apache POI是因爲當我使用JXL時,它不允許我在一張紙上插入超過65,500條記錄(行)。我有很多提取。請讓我知道是否需要提供更多我的程序以更清楚地瞭解我的問題。我真的很感謝你的幫助提前

我還有一個問題,我想補充到這一點。我正在考慮將數據庫數據提取到CSV文件中,然後將CSV文件導入到Excel中。我有一個問題,因爲我原本是在工作簿中解壓縮多個工作表,有沒有辦法可以導出到多個CSV文件?然後從多個CSV文件中,我如何將它們添加到工作簿中的不同工作表中?

再次感謝 桑尼

你好道格 這裏是我的查詢代碼:

public List<MasterDataDto> getDFMasterData(int siteValueId, int firstColumnId, int secondColumnId, int divisionId) throws IOException, ClassNotFoundException, SQLException { 
    List<MasterDataDto> masterDatatDtoList = new ArrayList<MasterDataDto>(); 
    Connection con = null; 
    PreparedStatement ps = null; 
    ResultSet rs = null; 
    try { 
     StringBuilder query = new StringBuilder(); 
     query.append("Select Distinct Dt.Name Division, Pr.Name Project, Addtl_Type.Name Site_Name, Atprt.Name col1, Atchd.Name col2"); 
     query.append(" From Addtl_Type_Rel Attr, Addtl_Type_Rel Attchd, Addtl_Type_Rel Attgrch, Addtl_Type Atprt, Project Pr, Addtl_Type Atchd, Addtl_Type, Division_Type Dt"); 
     query.append(" Where Pr.Id = Attr.Parent_N_Value"); 
     query.append(" And Attr.Id = Attchd.Previous_Rel_Id"); 
     query.append(" And Pr.Division_Type = Dt.Id"); 
     query.append(" And Atchd.Id = Attgrch.Child_N_Value"); 
     query.append(" And Attgrch.Parent_Field_Id = Attchd.Child_Field_Id"); 
     query.append(" And Attchd.Id = Attgrch.Previous_Rel_Id"); 
     query.append(" And Attr.Child_Field_Id = Attchd.Parent_Field_Id"); 
     query.append(" And Atprt.Id = Attchd.Child_N_Value"); 
     query.append(" And Attchd.Parent_N_Value = Addtl_Type.Id"); 
     query.append(" And Attr.Parent_Field_Id = ?"); 
     query.append(" And Attr.Child_Field_Id = ?"); 
     query.append(" And Attchd.Child_Field_Id = ?"); 
     query.append(" And Attgrch.Child_Field_Id = ?"); 
     query.append(" And Dt.Id = ?"); 
     if (siteValueId != 0) { 
      query.append(" And Attr.Child_N_Value = ?"); 
     } 
     query.append(" Order By Project, Site_Name, col1, col2"); 

     con = getConnection(); 
     ps = con.prepareStatement(query.toString()); 
     ps.setInt(1, MasterDataConstants.PROJECT); 
     ps.setInt(2, MasterDataConstants.SITE_NAME_ID); 
     ps.setInt(3, firstColumnId); 
     ps.setInt(4, secondColumnId); 
     ps.setInt(5, divisionId); 
     if (siteValueId != 0) { 
      ps.setInt(6, siteValueId); 
     } 
     rs = ps.executeQuery(); 
     while (rs.next()) { 
      MasterDataDto masterDataDto = new MasterDataDto(); 
      masterDataDto.setDivision(rs.getString("Division")); 
      masterDataDto.setProject(rs.getString("Project")); 
      masterDataDto.setSiteName(rs.getString("Site_Name")); 
      masterDataDto.setField1(rs.getString("col1")); 
      masterDataDto.setField2(rs.getString("col2")); 
      System.out.println(masterDataDto.getDivision() + "\t" + masterDataDto.getProject() + "\t" + masterDataDto.getSiteName() + "\t" + masterDataDto.getField1() + "\t" 
        + masterDataDto.getField2()); 
      masterDatatDtoList.add(masterDataDto); 
     } 
    } finally { 

     cleanUp(con, ps, rs); 
    } 
    return masterDatatDtoList; 

我怎麼能做出這樣更有效率? 謝謝 桑尼

你好,我有一個新的問題,與此計劃。我已經刪除了autoSizeColumn,並且它已經到達要寫入Excel工作簿的地方。我現在正在得到一個java.lang.OutOfMemoryError。 以下是錯誤的完整堆棧跟蹤: 例外

javax.servlet.ServletException:Servlet的執行引發了異常

根源

java.lang.OutOfMemoryError: GC overhead limit exceeded 
org.apache.xmlbeans.impl.store.Saver$TextSaver.resize(Saver.java:1592) 
org.apache.xmlbeans.impl.store.Saver$TextSaver.preEmit(Saver.java:1223) 
org.apache.xmlbeans.impl.store.Saver$TextSaver.emit(Saver.java:1144) 
org.apache.xmlbeans.impl.store.Saver$TextSaver.emitElement(Saver.java:926) 
org.apache.xmlbeans.impl.store.Saver.processElement(Saver.java:456) 
org.apache.xmlbeans.impl.store.Saver.process(Saver.java:307) 
org.apache.xmlbeans.impl.store.Saver$TextSaver.saveToString(Saver.java:1727) 
org.apache.xmlbeans.impl.store.Cursor._xmlText(Cursor.java:546) 
org.apache.xmlbeans.impl.store.Cursor.xmlText(Cursor.java:2436) 
org.apache.xmlbeans.impl.values.XmlObjectBase.xmlText(XmlObjectBase.java:1455) 
org.apache.poi.xssf.model.SharedStringsTable.getKey(SharedStringsTable.java:130) 
org.apache.poi.xssf.model.SharedStringsTable.addEntry(SharedStringsTable.java:176) 
org.apache.poi.xssf.usermodel.XSSFCell.setCellValue(XSSFCell.java:350) 
org.apache.poi.xssf.usermodel.XSSFCell.setCellValue(XSSFCell.java:320) 
master.service.MasterDataService.createSiteFieldExcel(MasterDataService.java:1102) 
master.service.MasterDataService.createMasterDataFile(MasterDataService.java:886) 
master.service.MasterDataServlet.doGet(MasterDataServlet.java:22) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 

我在哪裏必須增加JVM大小在日食。如果這有幫助,我正在運行Tomcat。 謝謝 Sonny

+2

我不是專家,但是您是否嘗試過使用任何分析工具來確定程序中的大部分執行時間?只是一個可能會對你有用的想法。 –

+0

我感謝您的評論。是的,我在程序中添加了'println'跳棋。將數據提取到eclipse控制檯沒有問題,但花費大量時間獲取控制檯值並將它們放入Excel中。 Sonny – Sonny

+0

我沒有看到您的查詢;但是,讓數據庫完成繁重的工作。更改您的查詢以在您的WHERE子句中執行篩選。最近,我嘗試着與SSRS做類似的事情;我遇到了內存和速度問題。數據庫經過優化,可以進行篩選和選擇。使用你的jsp只寫excel文件。 – Doug

回答

0

您可能需要使用適用於Excel的JDBC驅動程序,可能是JDBC ODBC橋,需要一些Windows操作。 這將是最優的,因爲您需要遍歷數據庫查詢並可以立即將其寫入Excel「數據庫」。

http://www.coderanch.com/t/465901/JDBC/databases/insert-data-excel-file-java

做不到這一點,這樣做沒有用的DTO的名單,但每立即rs.next/DTO添加到Excel工作表。

相關問題