Pregunta

Este era funcionando... y moví el código de eliminación al bloque finalmente, y ahora falla siempre.

Tengo una hoja de cálculo de prueba con 4 registros y 6 columnas.Aquí está el código que estoy usando para incorporarlo.Este es ASP .Net 3.5 en IIS 5 (mi PC) y en IIS 6 (servidor web).

Explota en la línea justo antes de la captura:"valores = (objeto [,]) range.Value2;" Con el siguiente error:

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

¿Algunas ideas?¿Sugerencias?Obtuve la mayor parte de este código de Codeproject, por lo que no tengo idea de si esta es la forma correcta de trabajar con Excel.Gracias por cualquier ayuda que usted nos pueda proporcionar.

Aquí está mi código:

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;
¿Fue útil?

Solución

No estoy seguro si esto es su problema o no, pero que muy bien puede ser. No está limpiando sus objetos de Excel correctamente. Son código no administrado y puede ser difícil de limpiar. Por último debe ser algo como esto: Y a medida que los comentarios han señalado trabajar con Excel desde asp.net no es una buena idea. Este código de limpieza es de una aplicación 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);

Editar

Una alternativa sería utilizar ado.net para abrir el libro.

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

Otros consejos

La creación / destrucción de Excel en cada petición tendrá absolutamente terrible actuación para importar lo que hagas. En general, ejecutar cualquier aplicación de Office mediante la automatización es un asunto muy desagradable para un montón de razones (ver aquí ). La única manera que tengo para trabajar es tener una sola instancia de la aplicación (en mi caso Word) que se inicializa una vez, y luego se ponen en cola solicitudes a esta instancia para procesar

Si puede mantenerse alejado de las aplicaciones y analizar el archivo usted mismo (usando bibliotecas MS, de tan sólo XML)

Te encontrarás con muchos problemas al utilizar la interoperabilidad desde ASP.NET.A menos que esto esté destinado a alguna pequeña aplicación interna, sería aconsejable no seguir adelante.

Office Interop no es una API de programación en el sentido tradicional: es el sistema de macros de Office llevado al máximo, con la capacidad de trabajar entre procesos; por ejemplo, una macro de Excel podría interactuar con Outlook.

Algunas consecuencias del uso de la interoperabilidad son:

  • En realidad, está abriendo una copia completa de la solicitud de oficina.
  • La aplicación ejecuta sus acciones como si las iniciara un usuario; es decir, en lugar de que se devuelvan mensajes de error en el código, se muestran en la GUI.
  • Su copia de la aplicación solo se cierra si usted lo ordena explícitamente, e incluso entonces los errores pueden evitar que eso suceda (la aplicación puede presentar un cuadro de diálogo "¿quiere guardar?" si no le dijo a Excel de manera programable que no es necesario realizar los cambios). Ser salvado).Esto generalmente da como resultado que se dejen ejecutándose muchas copias ocultas de Excel en el sistema: abra el administrador de tareas y vea cuántos procesos excel.exe se están ejecutando.

Todo esto hace que la interoperabilidad sea algo que se debe evitar para las aplicaciones de escritorio normales, y algo que solo debe usarse como último recurso para las aplicaciones de servidor, ya que una ventana emergente de GUI que requiere una acción o un script que filtra el proceso es un asesinato en un entorno de servidor.

Algunas alternativas incluyen:

  • Utilizando formatos basados ​​en XML de Microsoft Office 2007, para que pueda escribir los archivos XML usted mismo.
  • Usando Hoja de cálculoGear.Net, que es un lector/grabador de archivos binarios de Excel .NET (no necesita tener Excel instalado, ya que es completamente independiente).SpreadsheetGear se modela a sí mismo a partir de las interfaces de Intertop para facilitar la conversión de código antiguo.

El error es probablemente exactamente lo que dice, que está recibiendo un error de falta de memoria. Trate de dividir la carga de la matriz de valores en varios trozos más pequeños en lugar de obtener toda la gama de una sola vez. Probé su código en C # y no tuvimos problemas, pero mi hoja de cálculo que era carga era prácticamente vacío.

Me di cuenta de que el rango fue de toda la hoja de cálculo, aunque (de A2 a IV65536 o algo así). No estoy seguro de si lo que se pretende.

Una cosa que podría tratar de usar es sheet.UsedRange, que va a reducir el número de células que va a cargar.

Un par pequeñas cosas adicionales que he aprendido, que pueden serle de utilidad:

  • Uso de aplicaciones en lugar de ApplicationClass
  • Uso Marshal.FinalReleaseComObject (rango) (y también para la hoja, libro, app) de lo contrario tendrá su proceso de Excel.exe pegarse alrededor.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top