Lendo uma Planilha do Excel com C#

Hoje em dia é muito comum recebermos dados em planilhas do Excel e ter que importar ou analisar estes dados em nossas aplicações.

Com a ajuda do .Net Framework esta tarefa fica muito fácil e vou demonstrar como você pode abrir um arquivo do Excel e executar um comando Select em uma planilha simplesmente usando Ado.Net.

Para começar, vamos mostrar como está a nossa planilha no Excel e quais as informações importantes para o nosso programa em .Net.

Nossa planilha tem estes dados:

image

Vejam que a planilha tem os títulos das colunas na primeira linha. Estes serão os nomes dos campos para o nosso comando Select, e também o nome da planilha, que é Sheet1, será o nome da nossa tabela.

Agora vamos criar um projeto do tipo Console no Visual Studio:

image

Obs: no meu exemplo estou usando o Visual Studio 2010, mas vocês podem usar o Visual Studio 2008 com .Net Framework 2.0 sem problemas.

Criada nossa solução, vamos agora escrever o código. Para acessar os dados na planilha, vamos usar o Ado.Net e DataSet, para ser mais fácil de entender, e sendo assim precisamos incluir os namespaces apropriados:


using
System.Data;
using

System.Data.OleDb;

 

Após isto, precisamos criar a conexão com a planilha, usando OleDB:


OleDbConnection
conexao = new OleDbConnection(@”Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:tempplanilha.xlsx;Extended Properties=’Excel 12.0 Xml;HDR=YES’;”);


Nesta conexão, usamos o provider Microsoft.ACE.OLEDB e indicamos o noem da planilha, bem como a versão do Excel.

Criaremos agora um Adapter para executar o comando Select, e também um DataSet para armazenar os dados da consulta:


OleDbDataAdapter
adapter = new OleDbDataAdapter(“select * from [Sheet1$]”, conexao);
DataSet ds = new DataSet();


Observem que o nome da planilha tem um símbolo ‘$’ ao final e está entre colchetes ‘[]’.

Agora vamos abrir a conexão, preencher o DataSet e exibir os dados da planilha:


try
{
   conexao.Open();

   adapter.Fill(ds);

   foreach (DataRow linha in ds.Tables[0].Rows)
   {
     Console.WriteLine(“Nome: {0} – Cargo: {1} – Salario: {2}”, linha[“nome”].ToString(),
                        linha[“cargo”].ToString(), linha[“salario”].ToString());
   }
}
catch (Exception ex)
{
   Console.WriteLine(“Erro ao acessar os dados: “ + ex.Message);
}
finally
{
   conexao.Close();

}

 

Entendendo o código, abrimos a conexão, preenchemos o DataSet com o método Fill() do Adapter e depois executamos um ForEach para exibir os dados. Fazemos também o tratamento de exceção caso ocorra algum erro.

Vocês devem ter percebido que é um código bastante simples, mas de grande ajuda.

[]s,
Carlos.

36 Comments


  1. Muito bom o seu artigo, simples e facil de entender. Parabéns

    Reply

  2. Muito boa explicação, simples e eficiente!
    eu gostaria de saber se tem como importar todas as planilhas de uma vez, sem saber quantas e quais os nomes das mesmas!?!?!?!
    desde já agradeço a atenção!

    Márcio

    Reply

        1. Obrigado Juarez.
          []s,
          Carlos.

          Reply

  3. Bom dia carlos, estou fazendo um projeto com o MVC, e gostaria de subir este arquivo do Excel seja para uma pasta temporária do servidor ou para um banco de dados SQL Sever, e gostaria de consumir estes dados do Excel e popular eles numa Grid, e sendo que nessa Grid eu vou precisar fazer uma validação dos dados posso passar eles para uma List ou é melhor usar mesmo o dataSet?

    Desde já agradeço pelo belo post.

    Reply

    1. Bom dia,

      Se não for uma planilha muito grande, você pode trabahar no DataSet sem problemas.

      []s,

      Reply

      1. Carlos o que você chamaria de muito grande para essa situação? o que você acah do DataTable nesse caso? seria melhor para a manipulação dos dados?

        Reply

  4. Leandro,

    Não tem como medir isto exatamente, pois depende muito da sua aplicação. Lembre-se que se vários usuários realizarem o mesmo procedimento com uma planilha ao mesmo tempo, este dataset estará ocupando a memória do servidor.

    []s,

    Reply

    1. No meu caso não haverá isso de muitos usuários estarem usando ele ao mesmo tempo, mas estou em dúvida se o dataset será melhor para mim para trabalhar ou se eu uso um datatable já que vou popular o Grid com esses dados.

      Reply

  5. Leandro,

    Você pode usar o DataTable, pois é somente uma tabela. Caso precise trabalhar com mais de uma tabela, use o DataSet.

    []s,

    Reply

    1. Obrigado Carlos, usarei aqui o DataTable, e lhe informarei se ocorreu tudo certo.

      Reply

  6. Muito bom Carlos, código simples, facil de entender e de muita utilidade.
    Obrigado!!!

    Reply

  7. Deu um erro aqui: NÃO FOI POSSIVEL ENCONTRAR ISAM INSTALAVEL.

    o que poderia ser?

    Reply

  8. Bom artigo Carlos, se vc puder me ajudar com o código abaixo:

    cone.Open();
    DataSet ds = new DataSet();
    OleDbDataAdapter da = new OleDbDataAdapter(“Select * from [dados$]”, cone);
    da.Fill(ds);
    dataGridView1.DataSource = ds;
    cone.Close();

    o datagrid não está preenchendo :S

    Reply

  9. Oi, voce tem algum link, para que eu possa fazer a leitura mais arquitetural, a respeito dessa integração office e dotnet

    obrigado1

    Reply

  10. Guto,
    Não tem muita informação completa sobre isto, você pode encontrar vários fragmentos de acesso ao Excel em diversos sites. A integração Office x .Net é feita através de templates que existem dentro do Visual Studio. Veja este link: http://msdn.microsoft.com/en-us/library/23cw517s.aspx

    []s,
    Carlos.

    Reply

  11. Bom dia Carlos, pode me informar onde encontro alguma explicação para a seguinte dúvida?
    Gostaria de saber como faço para identificar o nome da tabela usando o visual studio, um comando que através do visual me traga a nome da tabela excel.
    Exemplo: Usarei o OpenFileDialog para localizar o arquivo excel, e após localizar gostaria de saber se tem algum comando que ao ler este arquivo pudesse me mostrar o nome da tabela dentro deste arquivo excel :
    Arquivo Nome: (Teste) e nome da tabela :Xyz

    Se pode me envia a resposta por email (runtime_inf@hotmail.com)

    Obrigado

    Reply

    1. Gil,

      Use o seguinte código:
      OleDbConnection conexao = new OleDbConnection(@”Provider = Microsoft.ACE.OLEDB.12.0; Data Source=c:\temp\planilha.xlsx; Extended Properties =’Excel 12.0 Xml; HDR = YES’;”);
      conexao.Open();
      var planilhas = conexao.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

      foreach(DataRow linha in planilhas.Rows)
      {
      Console.WriteLine(linha[“TABLE_NAME”].ToString());
      }

      conexao.Close();

      []s,
      Carlos.

      Reply

  12. Bom dia Carlos, estou importando dados(PRODUTO, DESCRIÇÃO E PREÇO) de uma tabela Excel más os produtos com “-” não são trazidos no select, o que pode ser? Quando coloco o produto com “-” na primeira linha apos o cabeçalho ele traz apenas o produtos com “-“. ??????????

    __________________________
    CODIGO

    ‘ abre uma conexao com a planilha excel
    Set oConn = New ADODB.Connection
    oConn.Open “Provider=Microsoft.Jet.OLEDB.4.0;” & _
    “Data Source=” & caminho & “;” & _
    “Extended Properties=””Excel 8.0;HDR=Yes;””;”

    Set RST = oConn.OpenSchema(adSchemaTables)
    strTbl = RST.Fields(“TABLE_NAME”).Value

    ‘ cria o objecto command e define a conexao ativa
    oCmd.ActiveConnection = oConn

    ‘ abre a planilha
    oCmd.CommandText = “SELECT * from [” & strTbl & “]”

    ‘ cria o recordset com os dados
    rsaux.Open oCmd, , adOpenKeyset, adLockOptimistic

    __________________________

    Reply

    1. Fábio,

      Montei um pequeno exemplo aqui onde na coluna continha um “-” no inicio do campo e leu sem problemas. Verifica no seu Excel se esta coluna está como Texto.

      []s,

      Reply

  13. O Script realmente roda perfeitamente. Mas por exemplo. Usei ele para uma rotina de importação de dados de uma planilha Excel para um Banco de Dados.

    Ocorre que em uma planinha com 5 linhas, o registro duplica várias e ainda não consegui entender o porque. Acredito que o problema esteja na linha:

    foreach (DataRow linha in ds.Tables[0].Rows)

    O que seria esse 0 “zero”? Seria o índide da linha? Se sim me parece estranho já que o for não segue o seu fluxo pelo índice.

    De qq forma, não consigo fazer esse script rodar para a minha necessidade.

    Alguma dica?

    Reply

    1. Robson,

      O indice [0] é referente a primeira tabela do dataset. A lilnha do foreach simplesmente percorre as linhas da planilha. Você pode fazer um debug e analisar.

      []s,

      Reply

  14. Olá!
    fiz conforme seu artigo e esta dando um erro, “O provedor ‘Microsoft.ACE.OLEDB.12.0’ não está registrado na máquina local.”
    e não acho nada para solucionar, alguma dica?
    Obgda

    Reply

  15. Olá Evelyn,

    Você precisa instalar o MDAC na maquina se ela não tiver o Office.

    []s,
    Carlos.

    Reply

    1. Mas eu tenho o office na maquina!

      Reply

  16. Confirme se é a mesma versão que você está colocando na conexão.

    Reply

    1. Consegui resolver, instalando “AccessDatabaseEngine”.
      Tem algum artigo para leitura de arquivo .csv ou consigo ler dessa maneira tbm?
      é que preciso fazer leitura dos dois tipos de arquivo (.xls e .csv)

      Obrigada

      Reply

  17. CSV você lê com StreamReader diretamente.

    Reply

  18. Carlos, Boa Tarde!

    Eu fiz um código parecido com este pra importar a planilha excel pra um DataGridView, porém eu estou trabalhando com window forms.
    E meu código funciona perfeitamente até a exibição da planilha excel no GridView, porém eu preciso salvar os dados que estão aparecendo neste GridView no meu Banco de dados Access, e não estou conseguindo, você poderia me ajudar com isso.?

    segue o código de iportação:

    ** o código abaixo está em uma classe ****
    class Importar
    {
    OleDbConnection conn;
    OleDbDataAdapter MyDataAdapter;
    DataTable dt;

    public void ImportaExcel(DataGridView dgv, String SheetName)
    {
    String ruta = “”;
    try
    {
    OpenFileDialog openfile1 = new OpenFileDialog();
    openfile1.Filter = “Excel Files |*.xlsx”;
    if (openfile1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
    if (openfile1.FileName.Equals(“”) == false)
    {
    ruta = openfile1.FileName;
    }
    }

    conn = new OleDbConnection(“Provider=Microsoft.ACE.OLEDB.12.0;data source=” + ruta + “;Extended Properties=’Excel 12.0 Xml;HDR=Yes'”);
    MyDataAdapter = new OleDbDataAdapter(“Select * from [” + SheetName + “$]”, conn);
    dt = new DataTable();
    MyDataAdapter.Fill(dt);
    dgv.DataSource = dt;

    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.ToString());
    }
    }
    }

    ** Codigo do botão Importar **

    new Importar().ImportaExcel(dataGridView1, “Vendas”);

    Para salvar eu estava tentando usar o botão que o próprio visual studio cria após a inserção do gridview, mas não está funcionando.

    Att.

    Reply

  19. Olá,

    Você pode salvar o dataset com o comando:

    dt.WriteXml(“seuarquivo.xml”);

    []s,

    Reply

    1. Boa Tarde, mas utilizando este comando eu irei salvar o conteúdo em um arquivo “.xml”, e pretendo salvar a informação que foi jogada no gridview no meu banco access! Tem alguma forma de fazer isto?

      Att

      Reply

  20. Você tem um dataset, precisa percorrer e salvar no seu banco access.

    Att.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Anti-spam: complete the taskWordPress CAPTCHA


This blog is kept spam free by WP-SpamFree.