2008-11-04 97 views
2

什麼是枚舉工作簿中每個工作表中每個單元格的最有效方法?使用c#在Excel工作簿中枚舉單元格的高效方法

下面的方法似乎適用於工作簿約130,000個單元格。在我的機器上,打開文件需要約26秒,枚舉單元約需5秒鐘。然而,我不是Excel專家,並希望驗證這個代碼片段與更廣泛的社區。

DateTime timer = DateTime.Now; 
Microsoft.Office.Interop.Excel.Application excelApplication = new Microsoft.Office.Interop.Excel.Application(); 
try 
{ 
    exampleFile = new FileInfo(Path.Combine(System.Environment.CurrentDirectory, "Large.xlsx")); 
    excelApplication.Workbooks.Open(exampleFile.FullName, false, false, missing, missing, missing, true, missing, missing, true, missing, missing, missing, missing, missing); 
    Console.WriteLine(string.Format("Took {0} seconds to open file", (DateTime.Now - timer).Seconds.ToString())); 

    timer = DateTime.Now; 
    foreach(Workbook workbook in excelApplication.Workbooks) 
    { 
      foreach(Worksheet sheet in workbook.Sheets) 
      { 
      int i = 0, iRowMax, iColMax; 
      string data = String.Empty; 

      Object[,] rangeData = (System.Object[,]) sheet.UsedRange.Cells.get_Value(missing); 

      if (rangeData != null) 
      { 
       iRowMax = rangeData.GetUpperBound(0);      
       iColMax = rangeData.GetUpperBound(1);              

       for (int iRow = 1; iRow < iRowMax; iRow++) 
       { 
         for(int iCol = 1; iCol < iColMax; iCol++) 
        { 
         data = rangeData[iRow, iCol] != null ? rangeData[iRow, iCol].ToString() : string.Empty; 
         if (i % 100 == 0) 
         { 
          Console.WriteLine(String.Format("Processed {0} cells.", i)); 
         } 

         i++; 
        }                         
       } 
      } 
     } 

     workbook.Close(false, missing, missing); 
    } 

    Console.WriteLine(string.Format("Took {0} seconds to parse file", (DateTime.Now - timer).Seconds.ToString()));    
    } 
    finally 
    { 
     excelApplication.Workbooks.Close();    
     excelApplication.Quit();     
    }     

編輯

值得指出,我想用PIA和互操作,以未通過直接與Excel文件,這些工作API的暴露Excel工作簿的訪問屬性。

回答

2

Excel PIA Interop在處理細胞時非常慢。

您應該簡單地通過閱讀ValueValue2屬性選擇要解壓,就像你與Worksheet.UsedRange財產做,然後閱讀整個範圍的值,一步到位,範圍通過調用get_Value()(或只是,我不記得哪一個)。

這將產生一個object[,],即一個二維數組,它可以很容易枚舉並且可以快速讀取。

編輯:我剛剛閱讀你的實際代碼,並意識到它實際上是我提出的。在回答之前,由於我沒有正確地閱讀問題而感到羞恥。在這種情況下,你不能更快。 Excel PIA Interop很慢。如果你需要更快的解決方案,你必須將jExcelApi從Java遷移到C#(不是一件非常難的事情),或者使用一些商業組件。我建議不惜一切代價避免OLEDB接口,以保持您的理智。

無關,但有幫助的提示:你應該使用?運營商。它非常方便。取而代之的

data = rangeData[iRow, iCol] != null ? rangeData[iRow, iCol].ToString() : string.Empty; 

,你可以只寫

data = Convert.ToString(rangeData[iRow, iCol]) ?? string.Empty; 

在這種情況下,即使是的String.Empty沒有必要的,因爲Convert.ToString(object)轉換null爲空字符串無論如何。

1

我認爲,這是最有效的方式,它怎麼與PIA。 使用「foreach」代替「for」可能會更快,但它不會有戲劇性的變化。

如果效率是您的主要目標,那麼您應該直接使用excel文件 - 無需使用excel應用程序。

2

有一個名爲Koogra的Excel讀寫器的開源實現。它允許您讀取excel文件並使用純託管代碼對其進行修改。 這可能會比現在使用的代碼快得多。

+0

+1感謝您指向Koogra。這將在我的項目中派上用場。 – dcharles 2010-02-04 18:16:57

相關問題