为什么我得到一个推存的错误做ASP。净Excel互操作?
-
12-09-2019 - |
题
此 是 工作..我处置移动代码的最后块,现在它失败。
我有一个测试的电子表格,记录4,6列长。这里是代码,我在使用带来它。这是ASP。净3.5IIS5(我的电脑)和IIS6(网络服务器)。
它打击了在线之前:"值=(object[,])的范围。值2;"与以下错误:
11/2/2009 8:47:43 AM :: Not enough storage is available to complete this operation. (Exception from HRESULT: 0x8007000E (E_OUTOFMEMORY))
任何想法?建议?我得到了大多数的这种代码断演示的,所以我不知道如果这是正确的工作方式与Excel。谢谢你任何帮助你可以提供。
这里是我的代码:
Excel.ApplicationClass app = null; Excel.Workbook book = null; Excel.Worksheet sheet = null; Excel.Range range = null; object[,] values = null; try { // Configure Excel app = new Excel.ApplicationClass(); app.Visible = false; app.ScreenUpdating = false; app.DisplayAlerts = false; // Open a new instance of excel with the uploaded file book = app.Workbooks.Open(path); // Get first worksheet in book sheet = (Excel.Worksheet)book.Worksheets[1]; // Start with first cell on second row range = sheet.get_Range("A2", Missing.Value); // Get all cells to the right range = range.get_End(Excel.XlDirection.xlToRight); // Get all cells downwards range = range.get_End(Excel.XlDirection.xlDown); // Get address of bottom rightmost cell string downAddress = range.get_Address(false, false, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing); // Get complete range of data range = sheet.get_Range("A2", downAddress); // get 2d array of all data values = (object[,])range.Value2; } catch (Exception e) { LoggingService.log(e.Message); } finally { // Clean up range = null; sheet = null; if (book != null) book.Close(false, Missing.Value, Missing.Value); book = null; if (app != null) app.Quit(); app = null; } return values;
解决方案
我不知道,如果这是你的问题或不是,但它很好可能。您没有正确清理你的Excel对象。他们都是非托管代码,并可能会非常棘手清理。最后,应该是这个样子:正如评论所指出与Excel从asp.net的工作是不是一个好主意。此清理代码是从winform应用程序:
GC.Collect();
GC.WaitForPendingFinalizers();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(range);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(sheet);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(book);
WB.Close(false, Type.Missing, Type.Missing);
Excel.Quit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(Excel);
修改强>
另一种方法是使用ado.net打开工作簿。
DataTable dt = new DataTable();
string connectionString;
System.Data.OleDb.OleDbConnection excelConnection;
System.Data.OleDb.OleDbDataAdapter da;
DataTable dbSchema;
string firstSheetName;
string strSQL;
connectionString = @"provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filename + @";Extended Properties=""Excel 12.0;HDR=YES;IMEX=1""";
excelConnection = new System.Data.OleDb.OleDbConnection(connectionString);
excelConnection.Open();
dbSchema = excelConnection.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
firstSheetName = dbSchema.Rows[0]["TABLE_NAME"].ToString();
strSQL = "SELECT * FROM [" + firstSheetName + "]";
da = new OleDbDataAdapter(strSQL, excelConnection);
da.Fill(dt);
da.Dispose();
excelConnection.Close();
excelConnection.Dispose();
其他提示
创建/在每次请求销毁Excel将有非常糟糕的表现,不管你做什么。在一般使用自动化运行的任何应用程序办公室是一个讨厌的业务有很多的原因(见这里)。我得到它的工作的唯一办法是让应用程序的单一实例(在我的情况的Word),这是一次初始化,然后请求排队到此实例进行处理
如果你可以留在应用远和解析自己(使用MS库只是XML的)文件
你要遇到很多麻烦,使用互操作从ASP.NET.除非这是一些微小的,在内部应用程序,它将是最好不要往前走。
办公室的互操作不是一种编程API在传统意义上的--这是办公室的宏观系统采取了其最大,有工作能力的进程,例如Excel宏可能互动的前景。
一些后果使用互操作程序:
- 你实际上是开放的完整副本的办公应用程序。
- 你的行动正在执行的应用程序,如果一个用户发起的他们-这意味着,而不是错误消息,正在返回代码,他们显示在图形界面。
- 你的复制的应用程序只能关闭,如果你明确指令和随后错误可以防止实际发生的情况(应用程序可能存在一个"你想要保存"对话如果你有没有不可编程地告诉Excel的改变不需要保存)。这通常导致在许多隐藏的副本Excel被留在系统上运行的开任务经理,看看多少excel.exe 进程正在运行。
所有这一切都使得互操作程序的东西,以避免的经常桌面应用程序,有什么东西,只应作为最后手段使用的服务器应用,因为GUI弹出需要采取行动或脚本泄漏过程是谋杀罪在服务器上的环境。
一些替代品包括:
- 使用微软办公室2007年基于XML格式,这样你可以写在XML文件的你自己。
- 使用 SpreadsheetGear.Net, ,这是一个。净二进制的Excel文件的读者/作家(你不需要安装Excel,因为它是完全独立的).SpreadsheetGear模型本身的后Intertop接口,以使转换的老年代更加容易。
错误可能是什么,它说,你得到一个推存储器的错误。尽量分装货的价值观阵分成几个较小的区块而不是得到整个范围在一段时间。我试过你的代码在C#没有问题,但是我的电子表格我是装大多是空的。
我注意到,范围是整个电子表格,虽然(自A2IV65536或某事)。我不知道如果这就是目的。
一件事你可以尝试使用是表。UsedRange,这将减少数细胞你是装载。
几个额外的小东西,我已经学到你可以找到有用的:
- 使用的应用程序而不是ApplicationClass
- 使用,元帅。FinalReleaseComObject(范围)(也为纸、书籍、应用程序),否则你会有你的EXCEL.EXE 过程中坚持的周围。