Fazer uma PerguntaFazer uma Pergunta
 

RespondidoUtilizando o Office Web Component

  • quarta-feira, 4 de novembro de 2009 19:11Wagner Pansani Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    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.

Respostas

  • quinta-feira, 5 de novembro de 2009 12:56Douglas Aguiar Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     RespondidoContém Código
    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

Todas as Respostas

  • quinta-feira, 5 de novembro de 2009 0:49Douglas Aguiar Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Resposta Proposta
    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 RespostaDouglas Aguiar quinta-feira, 5 de novembro de 2009 0:49
    •  
  • quinta-feira, 5 de novembro de 2009 10:33Wagner Pansani Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    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 12:56Douglas Aguiar Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     RespondidoContém Código
    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
  • sexta-feira, 6 de novembro de 2009 23:08Wagner Pansani Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     
    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! ;)