如何快速阅读c#中的Excel电子表格

时间:2011-09-30 17:27:09

标签: c# excel interop

我正在使用Microsoft.Office.Interop.Excel来读取内存中打开的电子表格。

gXlWs = (Microsoft.Office.Interop.Excel.Worksheet)gXlApp.ActiveWorkbook.ActiveSheet;
int NumCols = 7;
string[] Fields = new string[NumCols];
string input = null;
int NumRow = 2;
while (Convert.ToString(((Microsoft.Office.Interop.Excel.Range)gXlWs.Cells[NumRow, 1]).Value2) != null)
{
    for (int c = 1; c <= NumCols; c++)
    {
        Fields[c-1] = Convert.ToString(((Microsoft.Office.Interop.Excel.Range)gXlWs.Cells[NumRow, c]).Value2);
    }
    NumRow++;

    //Do my other processing
}

我有180,000行,结果非常慢。我不确定“转换”是否有效。无论如何我能更快地做到这一点吗?

月球

5 个答案:

答案 0 :(得分:20)

嗨,我找到了一个非常快的方法。

最好使用“get_range”一次读取整个数据。这会将数据加载到内存中,我可以像普通数组一样遍历数据。

Microsoft.Office.Interop.Excel.Range range = gXlWs.get_Range("A1", "F188000");
object[,] values = (object[,])range.Value2;
int NumRow=1;
while (NumRow < values.GetLength(0))
{
    for (int c = 1; c <= NumCols; c++)
    {
        Fields[c - 1] = Convert.ToString(values[NumRow, c]);
    }
    NumRow++;
}

答案 1 :(得分:3)

有几个选项 - 都涉及一些额外的库:

  • OpenXML 2.0(来自MS的免费图书馆)可用于阅读/修改.xlsx的内容,以便您可以根据需要进行操作

  • 一些(商业)第三方库带有网格控件,允许您在应用程序中使用excel文件(可以是Winforms / WPF / ASP.NET ...),例如SpreadsheetGearAspose.Cells等。

答案 2 :(得分:1)

  

我不确定“转换”是否有效。无论如何我能做到   这更快?

是什么让你相信这个?我保证 Convert.ToString()是您发布的代码中最有效的方法。您的问题是您在Excel文档中循环180,000条记录......

你可以拆分工作,因为你知道要做的行数。

为什么要将Value2完全转换为字符串?

答案 3 :(得分:0)

我想这不是转换“减速”来源......

实际上,检索单元格值非常慢。

我认为这种转换不是必需的:

(Microsoft.Office.Interop.Excel.Range)gXlWs

没有它应该可以工作。

你可以直接问:

gXlWs.Cells[NumRow, 1].Value != null

尝试将整个范围或至少整行移动到对象Matrix并使用它而不是范围本身。

答案 4 :(得分:0)

使用OleDB方法。这是最快的,如下所示;

string con =
  @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\temp\test.xls;" + 
  @"Extended Properties='Excel 8.0;HDR=Yes;'";    
using(OleDbConnection connection = new OleDbConnection(con))
{
    connection.Open();
    OleDbCommand command = new OleDbCommand("select * from [Sheet1$]", connection); 
    using(OleDbDataReader dr = command.ExecuteReader())
    {
         while(dr.Read())
         {
             var row1Col0 = dr[0];
             Console.WriteLine(row1Col0);
         }
    }
}