2014-07-07 58 views
0

我在c#中有一個datagridview,我在那裏顯示records.Now根據我的要求,我必須將其導出到excel.So我已經爲此編寫了以下方法..導出到Excel中的datagridView只在調試時才工作

public static void ExportToExcel(DataGridView dgView) 
    { 
     Microsoft.Office.Interop.Excel.Application excelApp = null; 
     try 
     { 
      // instantiating the excel application class 
      object misValue = System.Reflection.Missing.Value; 
      excelApp = new Microsoft.Office.Interop.Excel.Application(); 
      Microsoft.Office.Interop.Excel.Workbook currentWorkbook = excelApp.Workbooks.Add(Type.Missing); 
      Microsoft.Office.Interop.Excel.Worksheet currentWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)currentWorkbook.ActiveSheet; 
      currentWorksheet.Columns.ColumnWidth = 18; 
      if (dgView.Rows.Count > 0) 
      { 
       currentWorksheet.Cells[1, 1] = DateTime.Now.ToString("s"); 
       int i = 1; 
       foreach (DataGridViewColumn dgviewColumn in dgView.Columns) 
       { 
        // Excel work sheet indexing starts with 1 
        currentWorksheet.Cells[2, i] = dgviewColumn.Name; 
        ++i; 
       } 
       Microsoft.Office.Interop.Excel.Range headerColumnRange = currentWorksheet.get_Range("A2", "G2"); 
       headerColumnRange.Font.Bold = true; 
       headerColumnRange.Font.Color = 0xFF0000; 
       //headerColumnRange.EntireColumn.AutoFit(); 
       int rowIndex = 0; 
       for (rowIndex = 0; rowIndex < dgView.Rows.Count; rowIndex++) 
       { 
        DataGridViewRow dgRow = dgView.Rows[rowIndex]; 
        for (int cellIndex = 0; cellIndex < dgRow.Cells.Count; cellIndex++) 
        { 
         currentWorksheet.Cells[rowIndex + 3, cellIndex + 1] = dgRow.Cells[cellIndex].Value; 
        } 
       } 
       Microsoft.Office.Interop.Excel.Range fullTextRange = currentWorksheet.get_Range("A1", "G" + (rowIndex + 1).ToString()); 
       fullTextRange.WrapText = true; 
       fullTextRange.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignLeft; 
      } 
      else 
      { 
       string timeStamp = DateTime.Now.ToString("s"); 
       timeStamp = timeStamp.Replace(':', '-'); 
       timeStamp = timeStamp.Replace("T", "__"); 
       currentWorksheet.Cells[1, 1] = timeStamp; 
       currentWorksheet.Cells[1, 2] = "No error occured"; 
      } 
      using (SaveFileDialog exportSaveFileDialog = new SaveFileDialog()) 
      { 
       exportSaveFileDialog.Title = "Select Excel File"; 
       exportSaveFileDialog.Filter = "Microsoft Office Excel Workbook(*.xlsx)|*.xlsx"; 

       if (DialogResult.OK == exportSaveFileDialog.ShowDialog()) 
       { 
        string fullFileName = exportSaveFileDialog.FileName; 

        currentWorkbook.SaveAs(fullFileName, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook, System.Reflection.Missing.Value, misValue, false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Microsoft.Office.Interop.Excel.XlSaveConflictResolution.xlUserResolution, true, misValue, misValue, misValue); 
        currentWorkbook.Saved = true; 
        MessageBox.Show("Exported successfully", "Exported to Excel", MessageBoxButtons.OK, MessageBoxIcon.Information); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
     finally 
     { 
      if (excelApp != null) 
      { 
       excelApp.Quit(); 
      } 
     } 
    } 

現在一件奇怪的事情發生了,當我試圖用我的應用程序獲得excel報告時,我無法獲得,而如果我試圖通過調試我的代碼來獲得它,地獄很多時間。 在調試這行代碼..

Microsoft.Office.Interop.Excel.Range fullTextRange = currentWorksheet.get_Range("A1", "G" + (rowIndex + 1).ToString()); 

正在採取相當大量的時間..

請幫助我..

+0

excel文件的大小是多少? –

+0

@LIUFA它的40 kb ..我的代碼有什麼問題...? – user3740016

+0

每次更新單元時,RPC調用都會被編組到Excel過程中。但是你正在使用'Range',這已經是大規模優化了。 –

回答

0

Excel Interop永遠不會將它快如你遠程控制Excel應用程序的一個實例。您可能需要創建一個CSV文件,然後使用Excel Interop將其轉換爲.xls.xlsx文件。

這裏的例子就如何CSV轉換爲XLS

using Excel = Microsoft.Office.Interop.Excel; 

Excel.Application excel = new Excel.Application(); 
Excel.Workbook workBook = excel.Workbooks.Add(); 

var inputFile = new FileInfo("Book1.csv"); 
var sheet = Spreadsheet.Read(inputFile); 

workBook.ActiveSheet = sheet; // unsure about this part, but basically you need to transfer data. 

workBook.SaveAs(@"C:\Temp\fromCsv.xls"); 
workBook.Close(); 
0

我覺得下面的部分會減慢你的代碼很多

int rowIndex = 0; 
for (rowIndex = 0; rowIndex < dgView.Rows.Count; rowIndex++) 
{ 
    DataGridViewRow dgRow = dgView.Rows[rowIndex]; 
    for (int cellIndex = 0; cellIndex < dgRow.Cells.Count; cellIndex++) 
    { 
     currentWorksheet.Cells[rowIndex + 3, cellIndex + 1] = dgRow.Cells[cellIndex].Value; 
    } 
} 

我認爲這將是快得多DataGridView導出到Excel電子表格由而不是每次循環呼叫Cells,因爲每次使用COM時Cells的呼叫都相當昂貴。

我建議你將你的DataGridViewColumn到一個二維數組,然後導出整個DataGridView在一個這樣的:

object[,] toExport = new object[dgView.Rows.Count, dgView.Columns.Count]; 

for (int row = 0; row < dgView.Rows.Count; row++) 
{ 
    DataGridViewRow dgRow = dgView.Rows[row]; 
    for (int column= 0; column < dgRow.Cells.Count; column++) 
    { 
     toExport[row, column] = dgRow.Cells[row].Value; 
    } 
} 

// export in one go instead of looping and accessing Cells each time 
// use Excel.Application.Transpose(array) if needed 
ws.get_Range("A3").set_Value(Type.Missing, toExport); 

此外,你可以在開始添加一個xlApp.ScreenUpdating = false;,然後切換回true時你正在修改工作表。