2017-01-10 51 views
1

我現在陷入耗時的過程中。我正在用C#創建一個excel文件,並且我在SQL中有一個存儲過程,它需要大約2-3分鐘來執行並返回一個90K行的結果集。但是當我嘗試在C#中執行過程並在while循環中讀取數據時,我花了30分鐘來創建一個excel文件。這是我的代碼SQL讀取器在創建excel文件時需要很多時間

string gpn = cmbGPN.SelectedItem.ToString(); 
      string MRR_Query = " exec sp_MRR_Retention '"+Yr+"','"+Mn+"'"; 

      int xlCol, xlRow, xlMin, xlMax; 

      reader = func.getReader(MRR_Query); 

      object typeMissing = Type.Missing; 
      Excel._Application app = new Excel.Application(); 
      Excel.Workbook workbook = app.Workbooks.Add(typeMissing); 
      Excel.Worksheet sheet = (Excel.Worksheet)workbook.Worksheets.get_Item(1); 
      object misValue = System.Reflection.Missing.Value; 
      sheet.Name = "MRR Retention"; 

      app.ActiveWindow.Zoom = 80; 
      sheet.Application.ActiveWindow.SplitRow = 1; 
      sheet.Application.ActiveWindow.FreezePanes = true; 

      // Column name for raw data sheet 
      sheet.Cells[1, 1] = "Month"; 
      sheet.Cells[1, 2] = "Parent_Name"; 
      sheet.Cells[1, 3] = "Customer_Name"; 
      sheet.Cells[1, 4] = "Customer_Account_No"; 
      sheet.Cells[1, 5] = "Item_Category"; 
      sheet.Cells[1, 6] = "Item_Description_Summary"; 
      sheet.Cells[1, 7] = "Item_Number"; 
      sheet.Cells[1, 8] = "Date_Range"; 
      sheet.Cells[1, 9] = "Activity_Type"; 
      sheet.Cells[1, 10] = "Line_Type"; 
      sheet.Cells[1, 11] = "IBX_Code"; 
      sheet.Cells[1, 12] = "IBX_Country"; 
      sheet.Cells[1, 13] = "Primary_Sales_Rep"; 
      sheet.Cells[1, 14] = "MRC_Amount_USD_Budget_Rate"; 
      sheet.Cells[1, 15] = "Entered_Currency_Code"; 
      sheet.Cells[1, 16] = "MRC_Amount_LC"; 
      sheet.Cells[1, 17] = "UCM_ID"; 
      sheet.Cells[1, 18] = "GAM_TAG"; 
      sheet.Cells[1, 19] = "Client_Services_Manager"; 
      sheet.Cells[1, 20] = "Sales_Program_Type"; 
      sheet.Cells[1, 21] = "SFDC_Account_ID"; 
      sheet.Cells[1, 22] = "Account_Owner"; 

      sheet.Range["A1:W1"].Borders.Color = Color.Black; 
      sheet.Range["A1:W1"].ColumnWidth = 12; 
      sheet.Range["A1:W1"].Interior.Color = Color.YellowGreen; 
      sheet.Range["A1:W1"].Font.Color = Color.Black; 
      sheet.Range["A1:W1"].Font.Bold = true; 
      sheet.Range["A1:W1"].EntireRow.AutoFit(); 


      int row = 2; 

      while (reader.Read()) 
      { 
       sheet.Cells[row, 1] = reader.GetValue(0); 
       sheet.Cells[row, 2] = reader.GetValue(1); 
       sheet.Cells[row, 3] = reader.GetValue(2); 
       sheet.Cells[row, 4] = reader.GetValue(3); 
       sheet.Cells[row, 5] = reader.GetValue(4); 
       sheet.Cells[row, 6] = reader.GetValue(5); 
       sheet.Cells[row, 7] = reader.GetValue(6); 
       sheet.Cells[row, 8] = reader.GetValue(7); 
       sheet.Cells[row, 9] = reader.GetValue(8); 
       sheet.Cells[row, 10] = reader.GetValue(9); 
       sheet.Cells[row, 11] = reader.GetValue(10); 
       sheet.Cells[row, 12] = reader.GetValue(11); 
       sheet.Cells[row, 13] = reader.GetValue(12); 
       sheet.Cells[row, 14] = reader.GetValue(13); 
       sheet.Cells[row, 15] = reader.GetValue(14); 
       sheet.Cells[row, 16] = reader.GetValue(15); 
       sheet.Cells[row, 17] = reader.GetValue(16); 
       sheet.Cells[row, 18] = reader.GetValue(17); 
       sheet.Cells[row, 19] = reader.GetValue(18); 
       sheet.Cells[row, 20] = reader.GetValue(19); 
       sheet.Cells[row, 21] = reader.GetValue(20); 
       sheet.Cells[row, 22] = reader.GetValue(21); 

       row = row + 1; 
      } 

      reader.Close();                    //closing the reader and nullify if any recordset is remaining 
      func.CloseCon(); 

      workbook.SaveAs("D:\\MRR_Retention_Auto.xlsx", typeMissing, typeMissing, typeMissing, typeMissing, typeMissing, Excel.XlSaveAsAccessMode.xlExclusive, typeMissing, typeMissing, typeMissing, typeMissing, typeMissing); 
      workbook.Close(true, typeMissing, typeMissing); 
      app.Quit(); 

任何人都可以請看看這個問題,並告訴我如何使這個過程快。如果我使用SQL數據適配器,它會很快嗎?期待提出建議和解答。

+1

切換到Office的開放式xml SDK而不是Office Interop,您將看到更好的性能 –

+0

不確定讀者是什麼?它是一個二維數組嗎?如果是的話,您可以在Excel(VBA代碼)中轉儲所有數據:'sheet.Cells(row,1).resize(ubound(reader),ubound(reader,1)= reader'另一種轉儲方式來自Excel中的sql數據是'Range.CopyFromRecordSet'方法。 – cyboashu

回答

1

如果你真的想要速度(和緊湊的代碼),讓Excel爲你做所有繁重的工作,並使用Microsoft Query(內置於Excel)而不是手工完成。這裏是你將如何採取查詢,並將其轉換成掛鉤MS查詢Excel表格樣本:

string sql = "select * from foo"; 
string source = "your connection string here"; 

Excel.ListObject lo = sheet.ListObjects.AddEx(Excel.XlListObjectSourceType.xlSrcQuery, 
    source, true, Excel.XlYesNoGuess.xlGuess, range); 

try 
{ 
    lo.QueryTable.CommandText = sql; 
    lo.Refresh(); 
} 
catch (Exception ex) 
{ 
    ErrorMessage = ex.ToString(); 
} 

range將包含在要輸出的左上角單元格的目標的Excel Range對象。

如果您不知道連接字符串是什麼樣的,最好的分解方法是通過Excel生成查詢,然後進入查詢屬性,複製並粘貼連接字符串文本。

另外,如果您的連接是ODBC,則說明"DNS=<dns name>;"就足夠了,Excel將從ODBC屬性中提取所有連接屬性。