Hoje vou mostrar como criar arquivos .txt ou .sql com Delphi ASP.NET em tempo de execução a partir de uma string qualquer, gravar estes arquivos no servidor e descer para o usuário, também vou mostrar como listar os arquivos gerados, apagar e ler os dados de cada arquivo, recomendo a leitura do artigo Trabalhando com Diretórios e Arquivos do Blog Geeks .NET, lá o meu colega Mateus Chies já demonstrou algumas dessas funções da classe System.IO.
Bom, neste exemplo temos uma página que executa SQL diretamente no banco e exibe os resultados em uma gridView, após isso temos uma função que pega estes dados e gera um arquivo SQL com comandos para inserir (INSERT INTO ...) e disponibiliza o arquivo .SQL pra download, vamos primeiramente fazer a procedure que gera a SQL a partir de um dataset e grava o arquivo no servidor.
procedure TExemplo.GerarSQLInsert(ds:dataset); var C,R: Integer; sql: StringBuilder; caminho, arquivo:string; arq: System.IO.FileInfo; dir: System.IO.Directory; stream: System.IO.StreamWriter; begin {$REGION 'Cria SQL Insert'} sql := StringBuilder.Create; // Inicia transação na banco sql.appendLine('BEGIN TRANSACTION'); sql.appendLine('GO'); sql.AppendLine(''); // Registros Encontrados for R := 0 to ds.Tables[0].Rows.Count - 1 do begin // Inicia comando Insert com Nome da Tabela sql.AppendLine('INSERT INTO '+txbNomeTabela.Text+' ('); // Recupera Campos/Atributos for C := 0 to ds.Tables[0].Columns.Count - 1 do begin // Se não for última coluna precisa vírgula if C <> ds.Tables[0].Columns.Count -1 then sql.AppendLine(ds.Tables[0].Columns.Item[C].ColumnName+', ') else sql.AppendLine(ds.Tables[0].Columns.Item[C].ColumnName); end; // Fecha Atributos sql.AppendLine(') '); // Dado de cada Atributo sql.AppendLine('VALUES ('); for C := 0 to ds.Tables[0].Columns.Count - 1 do begin // Se não for última coluna precisa vírgula if C <> ds.Tables[0].Columns.Count -1 then begin if ds.Tables[0].Rows.Item[r].Item[c].ToString().TRIM <> '' then begin // Verifica se o tipo é double if NumeroValido(ds.Tables[0].Rows.Item[r].Item[c].ToString().TRIM) then sql.AppendLine(ds.Tables[0].Rows.Item[r].Item[c].ToString().TRIM+', ') else // Se não deve ser string e precisa aspas sql.AppendLine(' '''+ds.Tables[0].Rows.Item[r].Item[c].ToString().TRIM+''', '); end else sql.AppendLine('NULL, '); end else begin // Verifica se tem valor if ds.Tables[0].Rows.Item[r].Item[c].ToString().TRIM <> '' then begin // Verifica se o tipo é double if NumeroValido(ds.Tables[0].Rows.Item[r].Item[c].ToString().TRIM) then sql.AppendLine(ds.Tables[0].Rows.Item[r].Item[c].ToString().TRIM) else // Se não deve ser string e precisa aspas sql.AppendLine(' '''+ds.Tables[0].Rows.Item[r].Item[c].ToString().TRIM+''' '); end else sql.AppendLine('NULL'); end; end; // Fecha Dados sql.AppendLine(')'); sql.AppendLine('GO'); sql.AppendLine(''); end; sql.AppendLine(''); // Encerra transação e grava registros sql.appendLine('COMMIT'); sql.appendLine('GO'); {$ENDREGION} // Exibe // lblScript.Text := sql.ToString; {$REGION 'Cria Arquivo SQL Insert e Desce para o Usuário'} try caminho := Server.MapPath('.')+'\SQL\'; arquivo := 'SQL_INSERT_'+txbNomeTabela.Text+'.sql'; // verifica / cria diretório se não existe if dir.Exists(caminho) = False then dir.CreateDirectory(caminho); // cria arquivo arq := System.IO.FileInfo.Create(caminho+arquivo); // Insere SQL no arquivo stream := System.IO.StreamWriter.Create(caminho+arquivo); stream.WriteLine(sql.ToString); stream.Close(); // download do arquivo ScriptManager.RegisterStartupScript(Page, Page.GetType(), Guid.NewGuid().ToString(),'window.open("/SQL/'+arquivo+'","downsql","menubar=no,scrollbars=no,WIDTH=15,HEIGHT=15");', true); except on ex:exception do response.write('Erro durante criação do arquivo. Detalhes: '+ex.message); end; {$ENDREGION} end; // Função que verifica se o número é válido (é um número ou não) function TExemplo.NumeroValido(Numero: String): Boolean; Var N: Double; begin Result := False; try N := Convert.ToDouble(Numero); Result := True; Except Result := False; end; end;
Bom, no código acima ficou bem comentado o que cada parte faz, então vamos para o próximo passo, exibir os arquivos gerados em uma grid e também ter a opção de exibir o conteúdo dos arquivos em um textBox, excluir os arquivos ou fazer o download novamente.
Exibir os arquivos de um diretório é fácil como você já viu no post od Geeks .NET, mas aquele exemplo temos um problema, ele exibe o caminho completo do arquivo no servidor mas nós queremos ver apenas os nomes dos arquivos, então veja como ficou a procedure abaixo:
procedure TExemplo.ListarArquivos; var caminho, na:string; lista: ArrayList; i: integer; begin caminho := Server.MapPath('.'); lista := ArrayList.Create; gvSQL.DataSource := System.IO.Directory.Getfiles(caminho+'\sql'); gvSQL.databind(); for I := 0 to gvSQL.rows.Count - 1 do begin na := gvSQL.Rows.item[i].cells[3].Text; // Substitui o caminho até o diretório dos arquivos por '' -> nada na := na.replace(caminho+'\sql\',''); lista.add(na); end; gvSQL.DataSource := lista; gvSQL.databind(); end;
Ok, você pode notar que jogamos os nomes dos arquivos dos diretórios na coluna (Cells) 3 da grid, isto porque já temos as funções de ler, excluir e baixar nas três primeiras colunas da grid, veja o código da grid, tire os espaços nas tags.
< asp:gridview backcolor="White" bordercolor="#999999" borderstyle="Solid" borderwidth="1px" cellpadding="3" font-size="Small" forecolor="Black" gridlines="Vertical" id="gvSQL" runat="server"> < columns> < asp:buttonfield commandname="LER" text="Carregar">< /asp:buttonfield> < asp:buttonfield commandname="DOWNLOAD" text="Download">< /asp:buttonfield> < asp:buttonfield commandname="EXCLUIR" imageurl="~/imagens/exc.gif" text="Excluir">< /asp:buttonfield> < /columns> < footerstyle backcolor="#CCCCCC">< /footerstyle> < pagerstyle backcolor="#999999" forecolor="Black" horizontalalign="Center">< /pagerstyle> < selectedrowstyle backcolor="#000099" font-bold="True" forecolor="White">< /selectedrowstyle> < headerstyle backcolor="Black" font-bold="True" forecolor="White">< /headerstyle> < alternatingrowstyle backcolor="#CCCCCC">< /alternatingrowstyle> < /asp:gridview>
Agora já sabemos criar os arquivos, exibir eles em uma grid, vamos a parte de ler e e excluir os arquvos existentes, para isso vamos implementar as funções para cada botão da grid, fazemos isto no evento RowCommand, veja código abaixo:
procedure TExemplo.gvSQL_RowCommand(sender: TObject; e: System.Web.UI.WebControls.GridViewCommandEventArgs); var caminho,arquivo:string; arq: System.IO.FileInfo; reader: System.IO.StreamReader; begin // Se o comando é EXCLUIR if e.commandname = 'EXCLUIR' then begin // Pega o caminho até o diretório caminho := Server.MapPath('.')+'\SQL\'; // o Nome do arquivo SQL arquivo := GVSQL.Rows.Item[convert.ToInt32(e.commandargument)].Cells[3].Text; // Cria arquivo arq := System.IO.FileInfo.Create(caminho+arquivo); // Se arquivo existe -> com certeza existe if arq.Exists then arq.Delete; // Deleta // Atualiza Lista dos Arquivos ListarArquivos; end; // Se o comando é para baixar o arquivo -> DOWNLOAD if e.commandname = 'DOWNLOAD' then begin // Pega nome arquivo arquivo := GVSQL.Rows.Item[convert.ToInt32(e.commandargument)].Cells[3].Text; // Redireciona usuário para endereço do arquivo, vai pedir pra baixar... Response.redirect('/SQL/'+arquivo); end; // Se for pra ler -> exibir na textbox conteúdo do arquivo if e.commandname = 'LER' then begin caminho := Server.MapPath('.')+'\SQL\'; arquivo := GVSQL.Rows.Item[convert.ToInt32(e.commandargument)].Cells[3].Text; reader := StreamReader.Create(caminho+arquivo); // Lê arquivo até o fim e joga string para textbox txbSQL.text := reader.ReadToEnd; reader.Close(); end; end;
Bom pessoal, basicamente é isto ai, não mostrei como faz .txt né, é só trocar o final do nome do arquivo (Extensão) de .sql para .txt e pronto. Espero que seja útil, hoje também fiz um post no Geeks mostrando como exportar dados de uma grid para o Excel, pode ser muito útil em alguns casos, normalmente o usuário pede também...
Agradecimentos ao Tiago Pasieka que começou a página que me motivou fazer estas funções, valeuu!!
Até!