Pergunta

Este foi working..and Mudei o código de descarte para o último bloco, e agora ele falhar cada vez.

Eu tenho uma planilha de teste com 4 registros, 6 colunas longas. Aqui está o código que estou usando para trazê-lo. Este é ASP .Net 3.5 no IIS 5 (meu pc) e no IIS 6 (servidor web).

Funde-se na linha logo antes da captura: "= valores (objeto [,]) range.Value2;" com o seguinte erro:

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

Todas as idéias? Sugestões? Eu tenho a maior parte deste código off codeproject, então eu não tenho idéia se essa é a maneira correta de trabalhar com Excel. Obrigado por qualquer ajuda que você pode proporcionar.

Aqui está o meu 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;
Foi útil?

Solução

Eu não tenho certeza se este é o seu problema ou não, mas pode muito bem ser. Você não está limpando o seu excel objetos corretamente. Eles são código não gerenciado e pode ser difícil de limpar. Finalmente deve ser algo como isto: E como os comentários notaram trabalhar com o Excel a partir asp.net não é uma boa idéia. Este código de limpeza é de um aplicativo 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

Uma alternativa seria usar ado.net para abrir a pasta de trabalho.

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

Outras dicas

Criação / destruição de excel em cada solicitação terá desempenho absolutamente terrível para importa o que você faz. Em geral a execução de qualquer aplicativo do Office usando a automação é um negócio desagradável para uma série de razões (ver aqui ). A única maneira que eu tenho que trabalhar é ter uma única instância do aplicativo (no meu caso Word) que é inicializado uma vez, e, em seguida, os pedidos são colocados em fila a essa instância para o processamento

Se você pode ficar longe dos aplicativos e analisar o arquivo de si mesmo (usando MS bibliotecas, de apenas XML)

Você vai correr em um monte de problemas usando interoperabilidade do ASP.NET. A menos que isso se entende por algum minúsculo na aplicação casa que seria aconselhável não ir para a frente com ele.

Office Interop não é uma API de programação no sentido tradicional - é o sistema de macro Escritório levado ao seu máximo, com a capacidade de entre processos de trabalho -. Por exemplo, um macro Excel poderiam interagir com o Outlook

Algumas consequências da utilização de interoperabilidade são:

  • Você está realmente abrir uma cópia completa do aplicativo do Office.
  • As suas ações estão sendo executadas pela aplicação como se um usuário iniciou-los -. Que significa que em vez de mensagens de erro que estão sendo devolvidos no código, eles são exibidos na GUI
  • A sua cópia da aplicação só fecha se você comandar explicitamente - e, mesmo assim, os erros podem impedir que isso realmente acontecendo (o aplicativo pode apresentar um "faça você deseja salvar" de diálogo se você não programável dizer Excel que as mudanças não precisa ser salvo). Isso geralmente resulta em muitas cópias ocultas de estar Excel deixado em execução no sistema -. Gerenciador de tarefas aberto e ver quantos processos Excel.exe está executando

Tudo isso interoperabilidade marcas algo para evitar a aplicação de desktop regular, e algo que deve ser utilizado apenas como último recurso para aplicativos de servidor, uma vez que um pop-up GUI exigindo ação ou script que processo de vazamentos é assassinato em um ambiente de servidor.

Algumas alternativas incluem:

  • Usando o Microsoft Office 2007 formatos baseados em XML, de modo que você pode escrever os arquivos XML si mesmo.
  • SpreadsheetGear.Net , que é uma .NET binário Excel leitor de arquivos / escritor (você don' t precisa Excel instalado, como é completamente stand alone). modelos SpreadsheetGear-se após as interfaces Intertop para fazer conversão de código antigo mais fácil.

O erro é provavelmente exatamente o que diz, você está recebendo um erro de falta de memória. Tente dividir a carga da matriz valores em vários pedaços menores em vez de ficar toda a Faixa de uma vez. Eu tentei o seu código em C # e não tinha problemas, mas minha planilha eu estava carregamento estava quase vazio.

Eu observei que o intervalo foi toda a planilha embora (de A2 para IV65536 ou algo assim). Eu não estou certo se isso se destina.

Uma coisa que você pode tentar usar é sheet.UsedRange, que irá reduzir o número de células que está a carregar.

Um par de pequenas coisas adicionais que eu aprendi que você pode achar útil:

  • Use aplicativo em vez de ApplicationClass
  • Use Marshal.FinalReleaseComObject (intervalo) (e também para a folha, livro, app) caso contrário, você vai ter o seu processo de EXCEL.EXE aderindo ao redor.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top