2011-12-04 117 views
3

正在嘗試從Excel工作簿中讀取數據,發現需要很長時間才能讀取3560行7列大約1分17秒的表。我所做的只是遍歷整個工作表並將值存儲在一個列表中。Excel工作簿 - 從C#讀取速度很慢?

這是正常的,還是我做錯了什麼?

static void Main(string[] args) 
    { 
     List<string> testList = new List<string>(); 
     Excel.Application excelApp = new Excel.Application(); 
     Excel.Workbook workbook = excelApp.Workbooks.Open(@"C:\Users\rnewell\Desktop\FxData.xlsx"); 
     Excel.Worksheet worksheet = workbook.Sheets[1]; 
     Excel.Range range = worksheet.UsedRange; 

     int rowCount = range.Rows.Count; 
     int colCount = range.Columns.Count; 



     int rowCounter = 1; 
     int colCounter = 1; 

     while (rowCounter < rowCount) 
     { 
      colCounter = 1; 
      while (colCounter <= colCount) 
      { 
       //Console.Write(range.Cells[rowCounter, colCounter].Value2.ToString() + " "); 
       testList.Add(range.Cells[rowCounter, colCounter].Value2.ToString()); 
       colCounter++; 
      } 
      Console.WriteLine(); 
      rowCounter++; 


     } 



     Console.ReadKey(); 
     excelApp.Workbooks.Close(); 


    } 
+3

您不需要遍歷單元格來讀取範圍:您可以在一個操作中完成。看到謝爾蓋的答案在這裏:http://stackoverflow.com/questions/7919964/low-performance-when-reading-data-from-excel-workbook-to-arraylist-in-c-sharp從.NET自動化的Excel通常是(每個操作)比使用VBA慢,因爲您在跨進程而不是在同一進程內運行。 –

+0

暫時我會忍受滯後。如果數據集變得太大,我將使用此線程上建議的解決方案。謝謝 – Roge

回答

4

因爲你是從開放式XML數據加載(* .xlsx)格式的文件格式,我會建議你使用Open XML SDK。它不會在後臺啓動Excel,這總是一件好事,特別是如果您需要運行代碼non-interactively

我還訪問Excel中的數據,你可能會發現有用的不同的方法寫的blog post

2

一般來說,它應該是一個秒的問題。

但是當你正在創建的Excel本身的實例,包括它的插件可能需要很長的時間來初始化您的實例的一切。

爲了您的目的,您可以使用任何公共領域的Excel表單閱讀庫,它不會啓動Excel。

+0

當我計時時,我剛進入while循環之前就開始計時,所以理論上我沒有包括啓動Excel的時間。不過,我同意使用完整的excel實例可能是這裏的罪魁禍首。 – Roge

4

@TimWilliams的評論是正確的答案。讀取單個單元需要讀取任意大小的範圍。這是與COM層交談的開銷,並且您正在發生數千次。您應該將範圍寫入object[,],然後逐個訪問該數組。

int rowCount = range.Rows.Count; 
    int colCount = range.Columns.Count; 

    object[,] values= range.Value2; 

    int rowCounter = 1; 
    int colCounter = 1; 

    while (rowCounter < rowCount) 
    { 
     colCounter = 1; 
     while (colCounter <= colCount) 
     { 
      // check for null? 
      testList.Add(values[rowCounter, colCounter].ToString()); 
     } 
    } 

請注意,數組將是基於一個而不是像普通C#數組那樣基於零的數組。數據將從1到rowCount和從1到colCount,但行和列屬性將返回rowCount和colCount,而不是1 + rowCount和1 + colCount。如果你想寫回數據,你可以使用大小合適的從零開始的數組(實際上你必須AFAIK,因爲你不能創建一個基於數組的數組),並且它可以正常工作。