Microsoft.Office.Interop.Excel真的很慢

我正在使用标准的Microsoft.Office.Interop.Excel将1200 X 800matrix(indexMatrix)导出到excel文件。 该应用程序的作品,只是它真的真的很慢(即使是100×100matrix)。 我也通过TextWriter在文本文件中输出它几乎立即工作。 有没有办法更快地导出到Excel文件?

这是我的代码:

Excel.Application xlApp=new Excel.Application(); Excel.Workbook xlWorkBook; Excel.Worksheet xlWorkSheet; object misValue = System.Reflection.Missing.Value; //xlApp = new Excel.ApplicationClass(); xlWorkBook = xlApp.Workbooks.Add(misValue); xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); for (int i = 0; i < 800; i++) //h for (int j = 0; j < 1200; j++) xlWorkSheet.Cells[i+1,j+1] =indexMatrix[i][j]; xlWorkBook.SaveAs("C:\\a.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue); xlWorkBook.Close(true, misValue, misValue); xlApp.Quit(); releaseObject(xlWorkSheet); releaseObject(xlWorkBook); releaseObject(xlApp); MessageBox.Show("Excel file created , you can find the file c:\\csharp-Excel.xls"); 

您正在更新单个单元格。 这将是非常缓慢的。 如果你仔细想想,每次你更新一个单元格时,一个RPC调用将被整理到Excel进程中。

如果在单个语句(一个跨进程调用)中将您的二维数组值分配给相同维度的Excel范围,而不是当前的1200 x 800 = 960,000个跨进程调用,则会更快。

就像是:

 // Get dimensions of the 2-d array int rowCount = indexMatrix.GetLength(0); int columnCount = indexMatrix.GetLength(1); // Get an Excel Range of the same dimensions Excel.Range range = (Excel.Range) xlWorkSheet.Cells[1,1]; range = range.get_Resize(rowCount, columnCount); // Assign the 2-d array to the Excel Range range.set_Value(Excel.XlRangeValueDataType.xlRangeValueDefault, indexMatrix); 

其实,为了迂回,在上面的代码中有三个跨进程调用(.Cells,.get_Resize和.set_Value),并且在代码中每次迭代有两个调用(.Cells get和一个隐式.set_Value)总计1200 x 800 x 2 = 1,920,000。

注意 range.get_Resizerange.set_Value是我在第一次编写这篇文章时使用的旧版本的Excel互操作库所需要的。 现在,您可以使用range.Resizerange.Value如@ The1nk所示。

Excel互操作不会很快。 你基本上是远程控制Excel应用程序的一个实例。 通过创buildCSV文件,然后使用Excel interop将其转换为.xls或.xlsx文件

在阅读一个非常大的ex​​cel文件时,我遇到了类似的问题,它使用interop花了2个多小时。

我尝试使用ClosedXml,过程不到10秒。 ClosedXml

 // To loop Sheet.Row(y).Cell(x).Value 

另外请记住,除非您安装了excel,否则interop将无法在您的服务器上运行。 ClosedXml不需要安装excel。

使用Value2使其更快; 填充数据前显示excel

在写入任何数据之前closuresScreenUpdatingApplication.ScreenUpdating = FALSE然后在代码结束时打开= TRUE

ClosedXML是一个奇迹,这是一个更快,更容易使用。

 var workbook = new XLWorkbook();//create the new book var worksheet = workbook.Worksheets.Add("Computer Install");// Add a sheet worksheet.Cell(1,1).Value = "PC Name";// (Row, column) write to a cell workbook.SaveAs(@"LIC documents.xlsx");// Save the book 

你使用nu获取包安装。 https://www.nuget.org/packages/ClosedXML

有三种方法可以做到这一点,其中有两种方式是由别人提出不同的答案:

  1. 直接将excel中的范围值设置为2D数组。
  2. 将数据写入CSV文件,然后使用interop将CSV文件保存为xls或xlsx文件。
  3. 将数据写入CSV文件,然后使用数据连接function将CSV用作数据源并导入数据。

以上三种方法都很快。 我可以在大约6秒内写入90000行和100列大小的数据。

PS他们并没有解决我的问题,格式化数据的边框,字体样式,颜色,单元格合并等