为什么我在使用ASP .NET Excel Interop时遇到内存不足错误?

这是工作..我把处理代码移动到finally块,现在每次都失败。

我有一个测试电子表格,包含4条记录,6列长。 这里是我使用的代码。这是IIS 5(我的电脑)和IIS 6(Web服务器)上的ASP .Net 3.5。

它就在catch之前的那条线上:“values =(object [,])range.Value2;” 出现以下错误:

11/2/2009 8:47:43 AM :: Not enough storage is available to complete this operation. (Exception from HRESULT: 0x8007000E (E_OUTOFMEMORY))

有任何想法吗? 建议? 我从codeproject中获得了大部分代码,所以我不知道这是否是使用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对象。 它们是非托管代码,清理起来可能非常棘手。 最后应该看起来像这样:并且正如注释已经注意到从asp.net使用excel并不是一个好主意。 这个清理代码来自一个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将会有非常糟糕的表现,无论你做什么。 一般来说运行任何使用自动化的Office应用程序是一件令人讨厌的事情,原因很多(请看这里)。 我得到它的唯一方法是让应用程序的单个实例(在我的情况下是Word)初始化一次,然后请求排队等待这个实例进行处理

如果您可以远离应用程序并自行解析文件(使用MS库,仅使用XML)


使用ASP.NET的interop会遇到很多麻烦。 除非这是为了一些微小的内部应用,否则建议不要继续使用它。

Office Interop不是传统意义上的编程API--它是Office最大的系统,具有处理进程的能力 - 例如,Excel宏可以与Outlook进行交互。

使用interop的一些后果是:

  • 您实际上正在打开办公应用程序的完整副本。
  • 您的操作正在由应用程序执行,就像用户启动它们一样 - 这意味着代码中将返回错误消息,它们将显示在GUI中。
  • 您的应用程序副本只有在您明确命令时才会关闭 - 即使这样错误也会阻止实际发生的情况(如果您没有可编程地告诉Excel这些更改不需要,应用程序可能会显示“是否要保存”对话框被保存)。 这通常会导致许多隐藏的Excel副本在系统上运行 - 打开任务管理器并查看有多少个excel.exe进程正在运行。
  • 所有这些都使互操作成为常规桌面应用程序避免的一些问题,并且只能作为服务器应用程序的最后手段,因为需要操作或脚本泄露进程的GUI弹出窗口在服务器环境中是谋杀的。

    一些替代品包括:

  • 使用基于Microsoft Office 2007 XML的格式,以便您可以自己编写XML文件。
  • 使用SpreadsheetGear.Net,这是一个.NET二进制Excel文件读取器/写入器(您不需要安装Excel,因为它完全独立)。 SpreadsheetGear在Intertop接口之后自我模型,使旧代码的转换更容易。
  • 链接地址: http://www.djcxy.com/p/35687.html

    上一篇: Why am I getting an Out of Memory Error doing ASP .NET Excel Interop?

    下一篇: replace cell values within excel using excel.interop