Interop Excel很慢

我正在编写一个应用程序来打开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); 

这个答案只是关于你的问题的第二部分。 你正在使用很多的范围,这是不正确的,确实很慢。

首先阅读完整的范围,然后遍历结果如下所示:

 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()); } } 

这将会快得多!

简短的回答:正确的,interop是慢的。 (有同样的问题,需要几秒钟才能读取300行…

为此使用一个库:

附加到@RvdK的答案 – 是COM互操作速度慢。

为什么它慢?

这是由于它是如何工作的。 每一个从.NET开始的调用都必须封送到本地COM代理,从那里它必须从一个进程(你的应用程序)封装到COM服务器(Excel)(通过Windows内核中的IPC),然后从服务器端转换(分派)本地代理转换为本地代码,其中参数从OLE自动化兼容types封送到本机types,检查其有效性并执行function。 function的结果在两个不同的过程之间通过几层以大致相同的方式返回。

所以每一个命令执行起来都相当昂贵,你做的越多,整个过程就越慢。 你可以在网上find大量的文档,因为COM是老的,很好的工作标准(不知怎么地用Visual Basic 6去死)。

这样的文章的一个例子是在这里: http : //www.codeproject.com/Articles/990/Understanding-Classic-COM-Interoperability-With-NE

有更快的方法来阅读吗?

  1. ClosedXML可以使用微软的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 )的情况下进行批处理。 这个答案显示了如何做到这一点

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

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

https://freenetexcel.codeplex.com/