none
Utilizando o Office Web Component RRS feed

  • Pergunta

  • Pessoal, estou querendo gerar relatórios na minha aplicação ASP.NET em excel, porém esses relatórios irão abrir arquivos modelos em .xls, preencher os valores e depois disponibilizar para download.

    Minha primeira tentativa foi utilizar o Microsoft.Office.Interop.Excel.Application, ele funcionou porém depois que acaba todo o processo (mesmo dando um nothing no final) o Excel.exe continua na memória e não consegui tirar ele de lá.

    Ví que existe o Office Web Component, parece que ele funciona da mesma forma porém não consegui abrir o arquivo .xls para poder atualizar os valores.

    Alguém sabe me dizer como eu faço isso?

    Obrigado.
    quarta-feira, 4 de novembro de 2009 19:11

Respostas

  • Wagner,

    Veja abaixo o código da applicação Web aqui da empresa que funciona exportando dados para o Excel.

       Public Function ExportaDados(ByVal pHostAddress As String, ByVal pIdeUni As Double, ByVal pIdePlaGes As Double, ByVal pBuscaAvancada As cFiltroGestaoRisco.stcBuscaAvancada) As String
          Try
             Dim strReturnPath As String = String.Empty
             Dim lExcel As New Excel.Application
             Dim lBooks As Excel.Workbooks
             Dim lBook As Excel.Workbook
             Dim lSheets As Excel.Sheets
             Dim lSheet As Excel.Worksheet
             Dim lCells As Excel.Range
             Try
                'String.Format("{0}\TmpExcel\TmpExcel.xls", pHostAddress)
                Dim lDir As New System.IO.DirectoryInfo(String.Format("{0}arquivos\GestaoRiscos", pHostAddress))
                If lDir.Exists Then
                   For Each lFile As System.IO.FileInfo In lDir.GetFiles
                      If lFile.CreationTime < DateTime.Today Then lFile.Delete()
                   Next
                Else : System.IO.Directory.CreateDirectory(String.Format("{0}arquivos\GestaoRiscos", pHostAddress))
                End If
    
                Dim lFileName As String = String.Empty
                Select Case Avaliacao
                   Case eRiscos.Ambiental
                      lFileName = Resources.Resource.Ambientais
                   Case eRiscos.Saude + eRiscos.SegurancaOcupacional
                      lFileName = Resources.Resource.Ocupacionais
                   Case eRiscos.Financeira
                      lFileName = Resources.Resource.Financeiros
                   Case eRiscos.Operacional
                      lFileName = Resources.Resource.Operacionais
                   Case eRiscos.ParteInteressada
                      lFileName = Resources.Resource.PartesInteressadas
                End Select
    
                Dim lTemplatePath As String = String.Format("{0}Templates\GestaoRiscos\{1} - {2}.xls", pHostAddress, Resources.Resource.GestaoDeRiscos, lFileName)  'Caminho do arquivo Template
    
                strReturnPath = String.Format("{0}arquivos\GestaoRiscos\Tmp{1}_{2}.xls", pHostAddress, lFileName, DateTime.Now.ToString().Replace("/", String.Empty).Replace(":", String.Empty).Replace(" ", String.Empty))
    
    
    
                lExcel.Visible = False
                lExcel.DisplayAlerts = False
    
                'Start a new workbook
                lBooks = lExcel.Workbooks
    
                'Carrega o arquivo de template
                lBooks.Open(lTemplatePath)
    
                'Pega o primeiro Workbook
                lBook = lBooks.Item(1)
    
                'Carrega as planilhas do arquivo
                lSheets = lBook.Worksheets
    
                'Pega a primeira planilha do arquivo
                lSheet = CType(lSheets.Item(1), Excel.Worksheet)
    
                'Seta o nome da planilha
                lSheet.Name = String.Format("{0} {1}", Resources.Resource.Riscos, lFileName)
    
                'Carreta as células da planilha
                lCells = lSheet.Cells
    
                'Setando as linhas da planilha
                Me.OpenDataReader(Me.RetornaRiscosPorAplicacao(pIdeUni, pIdePlaGes, pBuscaAvancada, True))
    
                Select Case Avaliacao
                   Case eRiscos.Ambiental
                      PreencheCelulasAmbiental(lCells)
                   Case eRiscos.Saude + eRiscos.SegurancaOcupacional
                      PreencheCelulasOcupacional(lCells)
                   Case eRiscos.Financeira
                      PreencheCelulasFinanceiro(lCells)
                   Case eRiscos.Operacional
                      PreencheCelulasOperacional(lCells)
                   Case eRiscos.ParteInteressada
                      PreencheCelulasPartesInteressadas(lCells)
                End Select
    
                lCells.Columns.AutoFit()
    
                'Salva arquivo
                lSheet.SaveAs(strReturnPath)
    
             Catch ex As Exception
                Throw ex
             Finally
                lBook.Close()
    
                'Finaliza o Excel e desaloca os objetos
                lExcel.Quit()
                ReleaseComObject(lCells) : ReleaseComObject(lSheet)
                ReleaseComObject(lSheets) : ReleaseComObject(lBook)
                ReleaseComObject(lBooks) : ReleaseComObject(lExcel)
                lExcel = Nothing : lBooks = Nothing : lBook = Nothing
                lSheet = Nothing : lCells = Nothing : lSheets = Nothing
    
                'Coletor de lixo
                System.GC.Collect()
    
             End Try
             Return strReturnPath
          Catch ex As Exception
             Throw ex
          End Try
       End Function
    


    Pode ser porque no seu código você não esta chamando o método Quit do objeto Excel.
    E também usamos o método ReleaseComObject da classe Marshal do .Net.
    E depois chamamos o GC por precaução.

    Espero ter ajudado.
    Douglas Aguiar
    MCAD, MCT
    • Sugerido como Resposta Douglas Aguiar quinta-feira, 5 de novembro de 2009 12:56
    • Marcado como Resposta Harley Araujo sexta-feira, 6 de novembro de 2009 13:03
    quinta-feira, 5 de novembro de 2009 12:56

Todas as Respostas

  • Wagner,

    O Office Web Components é um controle ActiveX que roda no browser do usuário, e funciona de uma forma completamente diferente que o VSTO.

    Na minha empresa utilizamos o VSTO em uma aplicação Web e tivemos o mesmo problema que você. Este problema ocorre por a aplicação Web roda no servidor com privilegios reduzidos ai ela não consegue fechar o Excel e as vezes nem abri-lo, mesmo que você use uma conta com mais privilegios fazendo um impersonate no momento de manipular o Excel.

    Dai partimos para uma outra alternativa, criamos um serviço windows que fica verificando uma pasta, assim que um arquivo Excel cai nesta pasta o serviço manipula o arquivo e joga para uma outra pasta onde minha aplicação Web recupera o arquivo já processado e o envia para o usuário.

    Espero ter ajudado.
    Douglas Aguiar
    MCAD, MCT
    • Sugerido como Resposta Douglas Aguiar quinta-feira, 5 de novembro de 2009 00:49
    quinta-feira, 5 de novembro de 2009 00:49
  • Olá Douglas, obrigado por responder.

    O problema do excel não sair da lista dos processos, a meu ver não tem a ver com permissão (pelo menos no meu caso) porque se eu criar uma aplicação windows forms o processo também fica preso na memória. Não sei se tem a ver por o componente ser COM e não ser gerenciado.

    Você tem algum exemplo de utilização do VSTO com excel?

    Obrigado.
    quinta-feira, 5 de novembro de 2009 10:33
  • Wagner,

    Veja abaixo o código da applicação Web aqui da empresa que funciona exportando dados para o Excel.

       Public Function ExportaDados(ByVal pHostAddress As String, ByVal pIdeUni As Double, ByVal pIdePlaGes As Double, ByVal pBuscaAvancada As cFiltroGestaoRisco.stcBuscaAvancada) As String
          Try
             Dim strReturnPath As String = String.Empty
             Dim lExcel As New Excel.Application
             Dim lBooks As Excel.Workbooks
             Dim lBook As Excel.Workbook
             Dim lSheets As Excel.Sheets
             Dim lSheet As Excel.Worksheet
             Dim lCells As Excel.Range
             Try
                'String.Format("{0}\TmpExcel\TmpExcel.xls", pHostAddress)
                Dim lDir As New System.IO.DirectoryInfo(String.Format("{0}arquivos\GestaoRiscos", pHostAddress))
                If lDir.Exists Then
                   For Each lFile As System.IO.FileInfo In lDir.GetFiles
                      If lFile.CreationTime < DateTime.Today Then lFile.Delete()
                   Next
                Else : System.IO.Directory.CreateDirectory(String.Format("{0}arquivos\GestaoRiscos", pHostAddress))
                End If
    
                Dim lFileName As String = String.Empty
                Select Case Avaliacao
                   Case eRiscos.Ambiental
                      lFileName = Resources.Resource.Ambientais
                   Case eRiscos.Saude + eRiscos.SegurancaOcupacional
                      lFileName = Resources.Resource.Ocupacionais
                   Case eRiscos.Financeira
                      lFileName = Resources.Resource.Financeiros
                   Case eRiscos.Operacional
                      lFileName = Resources.Resource.Operacionais
                   Case eRiscos.ParteInteressada
                      lFileName = Resources.Resource.PartesInteressadas
                End Select
    
                Dim lTemplatePath As String = String.Format("{0}Templates\GestaoRiscos\{1} - {2}.xls", pHostAddress, Resources.Resource.GestaoDeRiscos, lFileName)  'Caminho do arquivo Template
    
                strReturnPath = String.Format("{0}arquivos\GestaoRiscos\Tmp{1}_{2}.xls", pHostAddress, lFileName, DateTime.Now.ToString().Replace("/", String.Empty).Replace(":", String.Empty).Replace(" ", String.Empty))
    
    
    
                lExcel.Visible = False
                lExcel.DisplayAlerts = False
    
                'Start a new workbook
                lBooks = lExcel.Workbooks
    
                'Carrega o arquivo de template
                lBooks.Open(lTemplatePath)
    
                'Pega o primeiro Workbook
                lBook = lBooks.Item(1)
    
                'Carrega as planilhas do arquivo
                lSheets = lBook.Worksheets
    
                'Pega a primeira planilha do arquivo
                lSheet = CType(lSheets.Item(1), Excel.Worksheet)
    
                'Seta o nome da planilha
                lSheet.Name = String.Format("{0} {1}", Resources.Resource.Riscos, lFileName)
    
                'Carreta as células da planilha
                lCells = lSheet.Cells
    
                'Setando as linhas da planilha
                Me.OpenDataReader(Me.RetornaRiscosPorAplicacao(pIdeUni, pIdePlaGes, pBuscaAvancada, True))
    
                Select Case Avaliacao
                   Case eRiscos.Ambiental
                      PreencheCelulasAmbiental(lCells)
                   Case eRiscos.Saude + eRiscos.SegurancaOcupacional
                      PreencheCelulasOcupacional(lCells)
                   Case eRiscos.Financeira
                      PreencheCelulasFinanceiro(lCells)
                   Case eRiscos.Operacional
                      PreencheCelulasOperacional(lCells)
                   Case eRiscos.ParteInteressada
                      PreencheCelulasPartesInteressadas(lCells)
                End Select
    
                lCells.Columns.AutoFit()
    
                'Salva arquivo
                lSheet.SaveAs(strReturnPath)
    
             Catch ex As Exception
                Throw ex
             Finally
                lBook.Close()
    
                'Finaliza o Excel e desaloca os objetos
                lExcel.Quit()
                ReleaseComObject(lCells) : ReleaseComObject(lSheet)
                ReleaseComObject(lSheets) : ReleaseComObject(lBook)
                ReleaseComObject(lBooks) : ReleaseComObject(lExcel)
                lExcel = Nothing : lBooks = Nothing : lBook = Nothing
                lSheet = Nothing : lCells = Nothing : lSheets = Nothing
    
                'Coletor de lixo
                System.GC.Collect()
    
             End Try
             Return strReturnPath
          Catch ex As Exception
             Throw ex
          End Try
       End Function
    


    Pode ser porque no seu código você não esta chamando o método Quit do objeto Excel.
    E também usamos o método ReleaseComObject da classe Marshal do .Net.
    E depois chamamos o GC por precaução.

    Espero ter ajudado.
    Douglas Aguiar
    MCAD, MCT
    • Sugerido como Resposta Douglas Aguiar quinta-feira, 5 de novembro de 2009 12:56
    • Marcado como Resposta Harley Araujo sexta-feira, 6 de novembro de 2009 13:03
    quinta-feira, 5 de novembro de 2009 12:56
  • Olá Douglas, usei seu código com algumas adaptações e funcionou direitinho, inclusive a parte de remover o excel da memória!

    Muito obrigado! ;)
    sexta-feira, 6 de novembro de 2009 23:08