none
Como abrir save file dialog box no browser do cliente transferindo arquivo gerado no serividor? RRS feed

  • Pergunta

  • Olá pessoal, estou com uma grande dificuldade em fazer com que o usuário possa salvar o arquivo gerado de um relatório usando o Save File Dialog box que abre no browser do cliente. Tenho um método que gera um arquivo .csv e do jeito que está ele salva direto na raíz do C:\ e não é isso que eu queria. Gostaria que quando o usuário clicasse no botão exportar, uma caixa de dialogo abriria e ele pudesse escolher em qual diretório de sua máquina ele gostaria de salvar.

    O código abaixo foi o código que criei  para gerar o arquivo csv. O método recebe um DatTable já preenchido com os dados e ele deveria dar a opção de abrir o save file dialog e o usuário escolhesse onde salvar. Eis o código:

    public void ExportarParaCsv(DataTable dt)
        {
           
            StreamWriter sw = new StreamWriter(@"C:\relatorio.csv");       
            System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
            
            try
            {
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    sw.Write(dt.Columns[i]);
                    if(i < dt.Columns.Count - 1)
                    {
                        sw.Write(";");
                    }
                }
                sw.Write(sw.NewLine);
                
                    foreach (DataRow dr in dt.Rows)
                    {
                        for (int i = 0; i < dt.Columns.Count; i++)
                        {
                            if (!Convert.IsDBNull(dr[i]))
                            {
                                sw.Write(dr[i].ToString());
                            }
                            if (i < dt.Columns.Count - 1)
                            {
                                sw.Write(";");
                            }
                        }
                        sw.Write(sw.NewLine);
                    }
                sw.Close();
                //response.ContentType = "text/csv";
                //response.AppendHeader("Content-Disposition", "attachment; filename=relatorio.csv");
                //response.TransmitFile();
                //response.End();
            }
                
                
            catch (Exception)
            {
                
                throw;
            }
        }

    Não entendi/sei como funciona o sistema de retorno http. Eu deveria usar um HttpStream ao invéz de um Streamwriter? Obrigado!
    quarta-feira, 26 de dezembro de 2012 20:14

Todas as Respostas

  • Olá, acho que faltou passar o binário pro response, assim:

    HttpResponse response = HttpContext.Current.Response;
    Response.Clear();
    Response.AppendHeader("content-disposition", "attachment; filename=" + relatorio.Nome.Replace(" ", ""));
    Response.ContentType = "application/octet-stream";
    response.BinaryWrite(relatorio.Arquivo);
    Response.Flush();
    Response.End();

    Usando o BinaryWrite que recebe um array de bytes.


    Rodrigo Reis Ferreira
    Microsoft Certified

    quinta-feira, 27 de dezembro de 2012 11:00
  • Rodrigo, testei com o código passado porém não funciona. O arquivo gerado é um arquivo .csv e ele está gravando dentro da pasta temp da minha aplicação. Usando o comando response.BinaryWriter() eu deveria converter meu csv para um array de bytes? Acho que fica meio complexa essa solução. Eu não poderia passar diretamente o arquivo no response?
    Obrigado pela ajuda!
    quinta-feira, 27 de dezembro de 2012 16:25
  • Bom, consegui resolver parcialmente o problema. Criei uma nova página aspx em branco e no método exportar dou um Response.Redirect("SaveFile.aspx");

    Na página criada coloquei os seguintes códigos no Page_Load:

     protected void Page_Load(object sender, EventArgs e)
        {
            string arquivo = "relatorio.csv";
            Response.ContentType = "text/csv";
            Response.AppendHeader("content-disposition", "attachment; filename=" + arquivo);
            //Response.Flush();
            Response.TransmitFile("~/temp/" + arquivo);
            Response.End();       
        }

    O problema agora é na página que tem o relatório. Ela fica travada. Como faço para que ela volte ao estado anterior, ou seja, ao estado de antes de clicar no meu botão exportar? 

    Obrigado!

    quinta-feira, 27 de dezembro de 2012 17:57
  • Deixa eu perguntar uma coisa, na verdade você já possui o arquivo na pasta temp, só quer que quando o usuário execute uma ação o arquivo seja carregado e a tela do browser de Salvar ou Abrir apareça?

    Rodrigo Reis Ferreira
    Microsoft Certified

    quinta-feira, 27 de dezembro de 2012 19:21
  • Deixa eu perguntar uma coisa, na verdade você já possui o arquivo na pasta temp, só quer que quando o usuário execute uma ação o arquivo seja carregado e a tela do browser de Salvar ou Abrir apareça?

    Rodrigo Reis Ferreira
    Microsoft Certified

    Exatamente, fiz conforme relatado acima e está funcionando o Salvar ou Abrir. Agora o problema é que toda vez que o usuário clica no botão "Exportar" a página que contém o grid fica "travada", ou seja, preciso dar um F5 pra voltar ao normal porém todo o conteúdo é perdido. Eu queria que depois que o usuário clicasse em Exportar ele fizesse o donwload (até aí está funcionando) e depois que fechasse a janela de Salvar ou Abrir voltasse tudo como estava antes, ou seja, ao estado anterior à ação de clicar em "Exportar". Será que fui claro? Muito obrigado pela atenção!
    quinta-feira, 27 de dezembro de 2012 20:26