Interop Excel很慢

时间:2014-04-22 06:29:30

标签: c# excel excel-interop

我正在编写一个打开Excel工作表并阅读它的应用程序

MyApp = new Excel.Application();
MyBook = MyApp.Workbooks.Open(filename);
MySheet = (Excel.Worksheet)MyBook.Sheets[1]; // Explict cast is not required here
lastRow = MySheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
MyApp.Visible = false;

这需要大约6-7秒才能完成,这是正常的互操作Excel吗?

还有更快的方法来阅读Excel吗?

string[] xx = new string[lastRow];
for (int index = 1; index <= lastRow; index++)
{
   int maxCol = endCol - startCol;
   for (int j = 1; j <= maxCol; j++)
   {
      try
      {
         xx[index - 1] += (MySheet.Cells[index, j] as Excel.Range).Value2.ToString();
      }
      catch
      {    
      }

      if (j != maxCol) xx[index - 1] += "|";
   }
}
MyApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(MySheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(MyBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(MyApp);

4 个答案:

答案 0 :(得分:2)

简短回答:正确,互操作很慢。 (有同样的问题,需要几秒钟才能阅读300行......

使用库:

答案 1 :(得分:2)

追加到@RvdK的答案 - 是的COM互操作很慢。

为什么慢?

这是因为它是如何运作的。每次从.NET调用必须从那里编组到本地COM代理,它必须从一个进程(你的应用程序)封送到COM服务器(Excel)(通过Windows内核中的IPC),然后从服务器转换(调度) #39;将本地代理转换为本机代码,其中参数从OLE自动化兼容类型封送到本机类型,检查其有效性并执行该功能。函数的结果在两个不同的过程之间以相同的方式返回几个层。

因此,每个命令执行起来都非常昂贵,你执行的操作越多,整个过程就越慢。你可以在网络上找到很多文档,因为COM已经老了并且运行良好(不知何故,用Visual Basic 6死了)。

此类文章的一个示例如下:http://www.codeproject.com/Articles/990/Understanding-Classic-COM-Interoperability-With-NE

有更快捷的阅读方式吗?

  1. ClosedXML可以使用Microsoft的OpenXml SDK读取和写入Excel xlsx文件(甚至是公式,格式和东西),请参见:https://closedxml.codeplex.com/wikipage?title=Finding%20and%20extracting%20the%20data&referringTitle=Documentation

  2. Excel数据阅读器声称能够读取旧版和新版Excel数据文件,我自己没有尝试过,请看一下:https://exceldatareader.codeplex.com/

  3. 另一种更快速读取数据的方法是使用Excel自动化将工作表转换为您可以轻松理解的数据文件,并在没有互操作层的情况下进行批处理(例如XML, CSV )。 This答案显示了如何操作

答案 2 :(得分:1)

这个答案只是关于你问题的第二部分。 你在那里使用了许多范围,这些范围不是预期的,而且确实非常慢。

首先阅读整个范围,然后迭代结果,如下所示:

var xx[,] = (MySheet.Cells["A1", "XX100"] as Excel.Range).Value2;
for (int i=0;i<xx.getLength(0);i++)
{
    for (int j=0;j<xx.getLength(1);j++)
    {
         Console.WriteLine(xx[i,j].toString());
    }
}

这会快得多!

答案 3 :(得分:1)

你可以使用这个免费的库,xls&amp;支持xlsx,

Workbook wb = new Workbook();
wb.LoadFromFile(ofd.FileName);

https://freenetexcel.codeplex.com/