segunda-feira, 20 de agosto de 2012

Download de Arquivos - Web

Bom dia pessoal, este post é bem simples, iremos ver como podemos possibilitar a opção de "Salvar como" arquivos gerados por nossa aplicação para o usuário final.
Utilizando este método podemos controlar o tipo de documento que será salvo e o nome padrão que irá aparecer para o usuário. Dessa forma podemos gerar Logs Diários das alterações do Banco de Dados em .txt passando a Data como Nome Padrão.
Em alguns casos necessitamos gerar documentos, por exemplo .txt, em nossa aplicação web para que o usuário possa exportar este arquivo gerado. Porém se utilizarmos uma variável do tipo blob, nossas ações estarão limitadas aos métodos default do Genexus.
Assim, ao realizar a soliticação a opção de Salvar irá aparecer:
Genexus Blog

Neste exemplo adicionei um botão à minha WebPanel, com o Evento "Salvar", logo quando este botão for clicado o seguinte evento irá ocorrer:

Event 'Salvar'
 //=====Extensao do Arquivo=====
 &Extensao = 'txt'
 do case
  case &Extensao = 'txt'
   &contenttype = 'text/plain'
 endcase
 
 //=====Nome a ser gerado=====
 &Date = ServerDate()
 &Nome = &Date.Year().ToString().Trim()+PadL(&Date.Month().ToString().Trim(),2,'0')+
 PadL(&Date.Day().ToString().Trim(),2,'0')+'.txt'
 
 //=====Source do Arquivo=====
 &Arquivo = 'Destino\Teste.txt'
 
 RealizaDownload.Call(&contenttype,&Arquivo,&Nome)
EndEvent

No código acima, uma Procedure (RealizaDownload) é chamada passando 3 parâmetros:
  1. contentType (tipo do documento) - aqui você encontra os tipos existentes (xls/doc/etc);
  2. Arquivo (Caminho onde o arquivo se encontra);
  3. Nome(Nome padrão do Documento a ser Salvo).
Já  procedure terá o seguinte código:

Rules:
parm(in:&contenttype,in:&filepath,in:&DocumentoNome); 

Events:
&HttpResponse.AddHeader('Content-Type', &contenttype)
&HttpResponse.AddHeader('Content-Disposition',"attachment;filename="+&DocumentoNome)
&HttpResponse.AddFile(&filepath)

Properties:
Main program: true
Call protocol: Http

18 comentários:

  1. Eduardo Ferroni Nithammer, valeu mesmo esse seu post foi muito útil, estava com esse problema e seu post foi muito claro. Obrigado.

    ResponderExcluir
  2. Pessoal estou com o problema!
    na hora de fazer o download do arquivo o nome do arquivo com tem espaço.

    Exemplo:
    "Nome do arquivo.txt" o mesmo quando é solicitado o seu download o mesmo é baixado com outro nome.
    "Nome+do+arquivo.txt"

    ResponderExcluir
    Respostas
    1. Bom dia, não é o ideal utilizar espaços e caracteres especiais em nomes de arquivos e pastas, retire os espaços alterando o nome do arquivo, para facilitar a leitura, troque os espaços por underline "_", ou então comece sempre uma nome palavra, preposição, etc... com letra maiúscula. Exemplos: Nome_do_Arquivo.txt ou NomeDoArquivo.txt... Abraços

      Excluir
  3. Olá!
    Gostaria de saber como faço para configurar a pasta na web.
    Normalmente configuro como /NomePasta/, porém não está funcionando.

    Abraços,

    Marlon

    ResponderExcluir
    Respostas
    1. A variável Arquivo deve conter o "source" (endereço fisico) onde esta localizado este arquivo. Por exemplo, se o arquivo esta localizado na pasta PublicTempStorage, você deve passar o caminho "C:\Models\TS_Homologacao\CSharpModel\web\PublicTempStorage\Arquivo.txt"
      Abraço

      Excluir
  4. fiz exatamente como está no seu exemplo e não acha o arquivo a fazer o download

    [FileNotFoundException: Não foi possível localizar o arquivo 'C:\Models\TS_Homologacao\CSharpModel\web\0.00'.]

    ResponderExcluir
    Respostas
    1. Luis, boa tarde. A variável Arquivo deve conter o "source" (endereço fisico) onde esta localizado este arquivo. Por exemplo, se o arquivo esta localizado na pasta PublicTempStorage, você deve passar o caminho "C:\Models\TS_Homologacao\CSharpModel\web\PublicTempStorage\Arquivo.txt"
      Abraço

      Excluir
  5. Olá boa tarde usei o seu exemplo aqui e deu certo, obrigado.

    ResponderExcluir
  6. Boa Tarde Usei seu metodo mas so funciona no Chrome no IE precisa colocar modo de compatibilidade , senão ele não funciona..
    Mas Obrigado. vai ser muito util

    ResponderExcluir
  7. Este comentário foi removido pelo autor.

    ResponderExcluir
  8. Olá Eduardo,

    Seu exemplo foi ótimo, o download funciona perfeitamente, quando crio o txt executando tudo na minha máquina de desenvolvimento está perfeito, só não consigo colocar em produção, dá erro ao criar o arquivo com este código:
    //****************************************************************
    // Diretório "txt" dentro do diretório da aplicação web
    &Directory.Source = 'valepostal_ro'

    // Se o diretório não existe, cria
    If not &Directory.Exists()
    &Directory.Create()
    EndIf

    // Identifica o arquivo e o endereço
    &Arquivo = &Directory.Source + '/' + &Arquivo.Trim()

    // Abrindo o arquivo
    &Error = DFWOpen(Trim(&Arquivo), '', '', 0, 'ISO-8859-1')
    //****************************************************************

    O download está ok nos dois ambientes.

    O que tenho que fazer para funcionar também em produção em um servidor remoto, como direciono para a pasta correta?

    Se tiver uma forma de gravar na máquina do usuário também resolve meu problema.

    Agradeço a ajuda.

    ResponderExcluir
    Respostas
    1. Tânia, o diretório tem que ser o caminho completo. Por exemplo: "C:\Temp\".

      O endereço do arquivo tem que ser o físico, não o endereço da Web.
      "C:\inetpub\wwroot\Aplicacao\Web\Pasta\" - ESSE
      "http://localhost/aplicacao/pasta" - NAO ESTE
      Att, Eduardo

      Excluir
  9. Eduardo,

    Tentei fazer como me orientou, mas não funcionou, estou trabalhando com GX Ev2 U7, com Java Web.

    Você tem alguma ideia do que posso estar fazendo de errado?

    ResponderExcluir
    Respostas
    1. Tânia, se os caminhos estão corretos, provavelmente é permissão de acesso a esta pasta.
      Se a aplicação for web, é preciso dar permissão para o usuário do IIS realizar alterações nesta pasta. Clique com o botão direito na pasta e verifique na aba "Segurança". Verifique as permissões dos usuários.

      Para fazer um teste de permissão total, "Full Control' para o usuário "Todos" ou "Everyone". Se funcionar é isto. Mas não recomendo manter esta configuração por questão de segurança. Ai você precisa procurar na internet como habilitar a segurança para o usuário do IIS.

      Att, Eduardo

      Excluir
  10. Boa Tarde,
    Como seria no caso de fazer download de vários arquivos ao mesmo tempo.
    Por exemplo:
    Criei vários arquivos texto de uma só vez e salvei seus caminho e nomes em um SDT. Como seria?

    ResponderExcluir
  11. Boa tarde,
    Tenho um link de um PDF, como faria para gravá-lo localmente ?
    Obrigado

    ResponderExcluir
  12. Eduardo...
    Agradeço sua publicação, pois me ajudou muito.
    Sempre tive essa dúvida que me assustava, mas agora ficou mais claro esse recurso.
    Implementei e funcionou corretamente em vários ambientes.

    Muito obrigado

    ResponderExcluir
  13. Bom dia, apliquei este exemplo já algum tempo em uma aplicação e funcionou perfeitamente até o Genexus EV3.... Agora compilando com a versão 15 simplesmente parou de funcionar.

    ResponderExcluir