Clique para saber mais...
  Home     Download     Produtos / Cursos     Revista     Vídeo Aulas     Fórum     Contato   Clique aqui para logar | 05 de Outubro de 2026
  Login

Codinome
Senha
Salvar informações

 Esqueci minha senha
 Novo Cadastro

  Usuários
56 Usuários Online

  Revista ActiveDelphi
 Assine Já!
 Edições
 Sobre a Revista

  Conteúdo
 Apostilas
 Artigos
 Componentes
 Dicas
 News
 Programas / Exemplos
 Vídeo Aulas

  Serviços
 Active News
 Fórum
 Produtos / Cursos

  Outros
 Colunistas
 Contato
 Top 10

  Publicidade

  [Artigos]  Exportando dados de um DataSet para o Excel
Publicado por ActiveDelphi : Quinta, Março 30, 2006 - 12:32 GMT-3 (17363 leituras)
Comentários 6 Comentários   Enviar esta notícia a um amigo Enviar para um amigo   Versão para Impressão Versão para impressão
Administrador Olá amigos leitores da Active Delphi. É um prazer escrever pra vocês. Prazer e tensão, porque essa é a primeira vez que publico algo.
O assunto do artigo é uma dúvida comum no mundo da programação. Muitas vezes o cliente precisa de um relatório, de uma amostra comparativa, muito extensa, mas fazer em ferramentas como Quick Report ou Rave pode nos limitar, ou dar um trabalho excessivo.

Isso quando o próprio cliente não pergunta se é possível mandar a informação diretamente para o Excel. Pois bem, veremos como fazer isso nesse artigo, usando os componentes OLE da paleta “Servers” no Delphi.

Obs: para este artigo, estou usando Delphi 7 e Office 97. Mas acredito que o que for apresentado aqui também sirva para o Office 2000.
(Atualização do código para funcionar no Office 2003 no final do artigo)

Mãos à obra !!

Inicie uma aplicação VCL no Delphi. Adicione um Button, um Edit, um Label (da paleta Standard), um DataSource, um ClientDataSet (ambos da paleta Data Access), um DBGrid (da paleta Data Controls) e um ExcelApplication (da paleta Servers). Configure os componentes da seguinte forma:

Button:
Name: btnExportar
Caption: Enviar para o Excel
Width: 115

Edit:
Name: edtNome

Label:
Caption: Digite um nome para o arquivo

ClientDataSet
Name: cdsExpExcel
FileName: C:\Arquivos de programas\Arquivos comuns\Borland Shared\Data\employee.cds
Active: True

DataSource:
DataSet: cdsExpExcel

DBGrid:
Align: alBottom
DataSource: DatSource1

ExcelApplication:
Name: Excel

Agora, dê um clique duplo no cdsExpExcel e adicione todos os campos (“Add all fields”) contidos no arquivo. Organize os componentes na tela de maneira que se pareça com a figura 1.

  

 

 

Figura1. Interface da aplicação.

Pensem agora comigo: pra exportar corretamente para o Excel, é necessário que o programa saiba em qual coluna escrever, se na A1, B1 e assim por diante. Por isso é necessário a criação de uma função que faça exclusivamente isso, ou seja, que mostre em qual coluna no Excel a informação será escrita. Ela pode ser vista a seguir:

function TForm1.PegaLetraColuna(IntNumber : Integer) : String;
begin
  if IntNumber < 1 then
    Result:='A'
  else
  begin
    if IntNumber > 256 then
      Result:='IV'
    else
    begin
      if IntNumber > 26 then
      begin
        Result:=Chr(64 + (IntNumber div 26));
        Result:=Result+Chr(64 + (IntNumber mod 26));
      end
      else
        Result:=Chr(64 + IntNumber);
    end;
  end;
end;

Repare que a função recebe um número inteiro como parâmetro e retorna uma string. Essa função será usada dentro de um laço, e receberá o contador do laço como parâmetro. À medida que o contador for incrementado, a função retornará a letra da coluna, sempre em seqüência.
Passemos agora, finalmente, para o procedimento que exportará os dados. Veja-o na Listagem 1.

procedure TForm1.ExpExcel(Dataset : TDataSet; ArqNome : String);
var
  NumLinha, NumColuna, LCID  : Integer;
  StrCell                    : String;
  FileName                   : OleVariant;
begin
  LCID := GetUserDefaultLCID;
  with Excel do
  begin
    Connect;
    try
      Visible[LCID] := True;
      Workbooks.Add(EmptyParam, LCID);
      NumLinha := 1;

      with Dataset do
      begin
        for NumColuna := 1 to Fields.Count do
        begin
          StrCell := PegaLetraColuna(NumColuna) + IntToStr(NumLinha);

          if Fields[NumColuna - 1].DisplayLabel <> '' then
            Range[StrCell,StrCell].Value := Fields[NumColuna - 1].DisplayLabel
          else
            Range[StrCell,StrCell].Value := Fields[NumColuna - 1].FieldName;

        end;
      end;

      NumLinha := 2;

      with Dataset do
      begin
        First;
        while not Eof do
        begin
          for NumColuna := 1 to Fields.Count do
          begin
            StrCell := PegaLetraColuna(NumColuna) + IntToStr(NumLinha);
            Range[StrCell, StrCell].Value := Fields.Fields[NumColuna - 1].Value;
          end;
          Next;
          Inc(NumLinha);
        end;
      end;
      Range['A1', StrCell].EntireColumn.Autofit;
      FileName := ArqNome;
      ActiveWorkbook.SaveAs(FileName, xlNormal, '', '', False, False, xlNoChange,
                            xlUserResolution, False, EmptyParam, EmptyParam, LCID);
      Quit;
    finally
      Disconnect;
    end;
  end;
end;

Listagem 1.

Procedure para exportação para o Excel

Vamos analisar o código mais de perto:

  procedure TForm1.ExpExcel(Dataset : TDataSet; ArqNome : OLEVariant);

Para poder extrair os dados, você passa como primeiro parâmetro, o DataSet e depois o nome do arquivo externo.

Repare o seguinte: LCID, e depois LCID := GetUserDefaultLCID;
É aqui que será instanciado, chamado, o aplicativo do Excel. E logo em seguida, em Visible[LCID] := True; ele será mostrado ao cliente. Se você optar por não mostrar ao seu cliente o Excel, para dar uma idéia de que sua aplicação está processando os dados, é só não incluir essa linha no programa. Não mudará em nada.

  with Excel do
  begin
    Connect;

Aqui o nosso programa se conectara ao servidor OLE, nesse caso o do Excel.

  Workbooks.Add(EmptyParam, LCID);

Aqui será criada uma nova Pasta no Excel. (Lembrando que o Excel trata como Pasta o arquivo que conterá as planilhas)

  NumLinha := 1;

Como o Excel trabalha com coordenadas (A1, Z1500), eu inicio a minha variável responsável por controlar o numero da linha com “1”.

  for NumColuna := 1 to Fields.Count do
  begin
    StrCell := PegaLetraColuna(NumColuna) + IntToStr(NumLinha);

Aqui será pego as coordenadas de onde será escrito o dado. Lembrando que começará na célula “A1”.

  if Fields[NumColuna - 1]. DisplayLabel <> '' then
    Range[StrCell,StrCell].Value := Fields[NumColuna - 1].DisplayLabel
  else
    Range[StrCell,StrCell].Value := Fields[NumColuna - 1].FieldName;

Nessa parte do código, o procedimento irá escrever o nome dos campos do DataSet nas células (Range) da planilha do Excel. Você pode melhorar como sairá o nome do campo, bastando para isso, quando adicionar os campos ao DataSet, alterar a propriedade “DisplayLabel”. Note que é passado para a célula (Range) as coordenadas de onde será escrita a informação ([StrCell,StrCell]). Eu passo a mesma string para inicio e fim, porque quero somente que seja escrita em uma célula. Se quiser escrever a mesma informação em um intervalo de células, basta colocar na seguinte notação:
  Range[StrCellInicio, StrCellFinal].Value := VarArrayOf([valor1, valor2,... valorN]);

  NumLinha := 2;

Agora eu coloco a minha variável responsável pela linha com o valor “2”, porque na linha “1” foram escritos somente o nome dos campos.

  with Dataset do
  begin
    First;
    while not Eof do
    begin
      for NumColuna := 1 to Fields.Count do
      begin
        StrCell := PegaLetraColuna(NumColuna) + IntToStr(NumLinha);
        Range[StrCell, StrCell].Value := Fields.Fields[NumColuna - 1].Value;
      end;
      Next;
      Inc(NumLinha);
    end;
  end;

Repare que o raciocínio dessa parte do código é o mesmo que na parte anterior, com a diferença que, agora, eu precisarei mudar de linha, somando sempre mais um à minha variável “NumLinha”. Por isso o comando Inc(NumLinha);
Com o comando Range['A1', StrCell].EntireColumn.Autofit; eu coloco todas as colunas com o mesmo tamanho.

    ActiveWorkbook.SaveAs(ArqNome, xlNormal, '', '', False, False, xlNoChange,
                          xlUserResolution, False, EmptyParam, EmptyParam, LCID);
    Quit;
  finally
    Disconnect;

A procedure “SaveAs” recebe como parâmetros o nome do arquivo externo, o formato do arquivo (nesse caso será XLS, que é o padrão), alguns parâmetros para tratamento do arquivo como “Password” ou se o arquivo será de somente leitura, e por fim, a instancia aberta do Excel (LCID).
Depois de salvar, eu fecho o Excel e me desconecto do servidor OLE.

Agora é só colocar no evento “OnClick” do btnExportar o seguinte comando:

  ExpExcel(cdsExpExcel, ExtractFilePath(Application.ExeName) + edtNome.Text);

Nesse caso, o arquivo será gerado na mesma pasta do arquivo executável.

E pronto, aí está o procedimento que exportará bonitinho os dados do seu cliente para o Excel !!! Espero que tenham gostado dessa dica e sobre qualquer questão, podem me contatar. Será um prazer conversar com outros amigos Delphianos. Saúde e paz à todos nós.

 

Atualização do código para funcionar no Office 2003 no final do artigo e para tratar campos to tipo Date
Enviada pelo amigo Gustavo Frassini (usuário gustavocco)

procedure TForm1.ExpExcel(Dataset : TDataSet; ArqNome : OleVariant);
var
  NumLinha, NumColuna, LCID  : Integer;
  StrCell                    : String;
  // Criado Vaviaveis by Gustavo
  AdtoMru, CreateBck, ROREcommended : OleVariant;

begin
  LCID := GetUserDefaultLCID;
  with Excel do
  begin
    Connect;
    try
      Visible[LCID] := True;
      Workbooks.Add(EmptyParam, LCID);
      NumLinha := 1;

    (* Aqui pega o nome dos CAMPOS do Dataset *)
      with Dataset do
      begin
        for NumColuna := 1 to Fields.Count do
        begin
          StrCell := PegaLetraColuna(NumColuna) + IntToStr(NumLinha);

          (* Usa "DisplayLabel" das colunas para preencher as células ou "FieldName" *)
          // Alterado Parametro do Range .. by Gustavo
          if Fields[NumColuna - 1].DisplayLabel <> '' then
            Range[StrCell,StrCell].Value2 := Fields[NumColuna - 1].DisplayLabel
          else
            Range[StrCell,StrCell].Value2 := Fields[NumColuna - 1].FieldName;

        end;
      end;

      NumLinha := 2;

      with Dataset do
      begin
        First;
        while not Eof do
        begin
          for NumColuna := 1 to Fields.Count do
          begin
            StrCell := PegaLetraColuna(NumColuna) + IntToStr(NumLinha);
            // Alterado Parametro do Range .. by Gustavo
            if (Fields.Fields[NumColuna - 1].DataType = ftDate) or

               (Fields.Fields[NumColuna - 1].DataType = ftDateTime) then
               // Tratamento de Datas .. by Gustavo
               if (not Fields.Fields[NumColuna - 1].IsNull) then
                  Range[StrCell, StrCell].Value2 := DateToStr(Fields.Fields[NumColuna - 1].AsDateTime)
               else
                   Range[StrCell, StrCell].Value2 := ''
            else
                Range[StrCell, StrCell].Value2 := Fields.Fields[NumColuna - 1].Value;
          end;
          Next;
          Inc(NumLinha);
        end;
      end;
      Range['A1', StrCell].EntireColumn.Autofit;
      // Atribuido Valor as variaveis by Gustavo
      AdtoMru       := False;
      CreateBck     := False;
      ROREcommended := False;
      // Alterado Parametros .. by Gustavo
      ActiveWorkbook.SaveAs(ArqNome, xlnormal, EmptyParam, EmptyParam, ROREcommended, CreateBck,

xlNoChange, xlUserResolution, AdtoMru, Emptyparam, emptyparam,emptyparam, lcid);
      Quit;
    finally
      Disconnect;
    end;
  end;
end;

Clique aqui para fazer o download dos exemplos.

Mini-curriculo:

Welson de Avelar Soares Filho trabalha com Delphi desde 2004. É estudante de Ciência da Computação na Universidade Federal de Juiz de Fora. Pode ser contatado no e-mail welson_avelar@yahoo.com.br



Comentários Comentários
   Ordem:  
Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos.


por: jrsilveiro : Mai 02, 2006 - 09:55
(Informações sobre o membro | Enviar uma mensagem)
Como eu faço para importar esses dados para o banco de dados.
Eu tenho uma situação em que eu recebo uma planilha do excel e importo alguns dados dessa planilha, mas o empresa que me fornece essa planilha exlui ou acrescenta campos sem avisar e na minha aplicação eu uso colunas fixas para esses campos. Como eu posso controlar isso através de uma rotina?
ex.: campo X está na coluna B1, mas qdo recebi uma nova atualização verifiquei que passou a ser C1.


por: brainlock : Set 19, 2006 - 06:02
(Informações sobre o membro | Enviar uma mensagem)
Me perdoe a ignorancia sobre o assunto, mas tipo assim como faço para gerar um arquivo .CDS???

Se vc. puder me enviar essa resposta direto no meu e-mail fico no aguardo.

Obrigado!


por: alegneto : Jul 30, 2007 - 05:18
(Informações sobre o membro | Enviar uma mensagem)
Encontrei um pequeno bug na hora de selecionar a coluna AZ, BZ, etc... vai ai o código com a minha correção.

function PegaLetraColuna(nIntNumber : Integer) : String;
var
vStrCol : String;
vResto, vDivisor : Integer;
begin
vStrCol := '';
if nIntNumber < 1 then
vStrCol :='A'
else
begin
if nIntNumber > 256 then
vStrCol :='IV'
else
begin
if nIntNumber > 26 then
begin
vDivisor := nIntNumber div 26;
vResto := nIntNumber mod 26;
//para as colunas AZ, BZ, CZ, etc
if (vDivisor > 1) and (vResto = 0) then begin
vDivisor := vDivisor - 1;
vResto := 26 * vDivisor;
end;
vStrCol:=Chr(64 + (vDivisor)) + Chr(64+vResto);
end
else
vStrCol:=Chr(64 + nIntNumber);
end;
end;
Result := vStrCol;
end;
  Edição 112

Revista ActiveDelphi

  50 Programas Fontes


  Produtos

Conheça Nossos Produtos

Copyright© 2001-2016 – Active Delphi – Todos os direitos reservados