Exército... Vou?! Não Vou??!

É o que vou descobrir semana que vem! :D



Desejo um excelente 2010 para todos e deixo um papel de parede de presente!


Download em 1024×768, 1280×1024, 1440x900, 1600x1200, 2560x1600

Boas festas para todos!!

Criando/Baixando/Listando/Apagando Arquivos no Delphi ASP.NET

Olá pessoal!

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é!