C# - Convertendo Excel para XML


 Neste artigo vou mostrar como converter arquivos Excel para o formato XML usando a linguagem C#.

Neste artigo vamos criar uma aplicação Windows Forms usando a linguagem C# e a partir de um arquivo Excel informado vamos gerar o respectivo arquivo XML.

Para fazer o processo inverso veja o meu artigo : VB .NET - Convertendo XML para Excel - Macoratti.net

Iremos converter arquivos Excel  no formato .xls referente ao Excel 97 até 2003 e formato .xlsx referente ao Excel 2007 e superior.

Para realizar esta tarefa não vamos usar nenhuma referência à biblioteca Excel -  Microsoft.Office.Interop.Excel - que é  um componente COM. Assim não precisaremos usar o Excel em background e nossa aplicação ficará mais leve e rápida.

Para fazer a conversão vamos usar os seguintes recursos:

Vamos localizar um arquivo Excel informado e obter os dados deste arquivo, e , usando o OLEDB vamos gerar um DataTable com os dados obtidos e exportar estes dados no formato XML.

Vamos usar a classe XmlTextWriter que fornece uma maneira rápida de gerar streams ou arquivos contendo dados XML em conformidade com a W3C Extensible Markup Language (XML) 1.0. Ela contém diversos métodos e propriedades que vão fazer todo o trabalho pesado para você na prática.

Para usar esta classe basta você usar os namespace System.Xml e criar um novo objeto XmlTextWriter; em seguida basta ir incluindo os elementos Xml que você deseja criar. A classe comporta métodos para incluir cada tipo de elemento em um arquivo XML. A seguir temos alguns destes métodos:

Método Descrição
WriterStartDocument Escreve a declaração XML indicativa da versão XML  (version  "1.0")
WriteEndDocument Fecha qualquer elemento ou atributo aberto.
Close Fecha o stream.
WriteDocType Escreve a declaração DOCTYPE com o nome especificado e atributos opcionais.
WriterStartElement Escreve tag de inicio definida.
WriteEndElement Fecha um elemento.
WriteFullEndElement Fecha um elemento.
WriteElementString Escreve um elemento contendo um valor string.
WriteStartAttribute Escreve o início de um atributo.
WriteEndAttribute Fecha a chamada anterior de WriteStarttAttribute.
WriterString Escreve uma string.
WriteAttributes Escreve um atributo com um valor específico..
WriteCData Escreve um bloco <![CDATA[...]]> contendo o texto especificado..
WriteComment Escreve um comentário <!--...--> contendo o texto especificado.
WriteWhitespace Escreve um espaço.
WriteProcessingInstruction Escreve uma instrução de processamento com um espaço entre o nome e o texto seguido de <?name text?>.

De forma geral, para gerar XML usando a classe XmlTexWriter , você vamos efetuar os seguintes passos:

Nota: Para saber mais sobre conceitos XML leia o artigo: XML - eXtensible Markup Language - Introdução

Recursos usados :

Lendo Excel e convertendo para XML

Abra o VS Community 2017  e clique em New Project;

A seguir selecione Visual C# -> Windows Classic Desktop -> Windows Forms App;

Informe o nome CSharp_ExcelXML e clique no botão OK;

No formulário padrão form1.cs inclua os seguintes controles:

Disponha os controles conforme o leiaute da figura :

Defina os seguintes namespaces no formulário:

Imports System
Imports System.Windows.Forms
Imports System.Xml


Observe que não estamos usando nenhuma referência ao Excel no formulário.

Implementando o código do formulário

1 - No evento Click do botão para localizar o arquivo Excel inclua o código a seguir:

        private void btnLocalizar_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd1 = new OpenFileDialog();
            ofd1.Multiselect = false;
            ofd1.Title = "Selecione o arquivo Excel";
            ofd1.InitialDirectory = @"C:\Dados\xls";
            ofd1.CheckFileExists = true;
            ofd1.CheckPathExists = true;
            ofd1.FilterIndex = 1;
            DialogResult drResultado = ofd1.ShowDialog();

            if (drResultado == DialogResult.OK)
                txtNomeExcel.Text = ofd1.FileName;
        }

No código acima eu já defini um diretório inicial para localizar os arquivos no formato Excel.

1 - No evento Click do botão Converter inclua o código a seguir:

       private void btnConverter_Click(object sender, EventArgs e)
        {
            // usa o nome informado para o arquivo XML gerado
            if (chkbNomeArquivoExcel.Checked && chkbNomeArquivoExcel.Text != "" && txtNomeExcel.Text != "" && txtNomeNodePadrao.Text != "") 
            {
                if (File.Exists(txtNomeExcel.Text))
                {
                    // cria o caminho para o arquivo XML
                    string caminhoArquivoXML = Path.Combine(new FileInfo(txtNomeExcel.Text).DirectoryName, txtNomeArquivoXML.Text); 
                    ConverteXlsXml converteXML = new ConverteXlsXml();
                    // arquivo Xml File, arquivo Excel, nome da linha(Node)
                    converteXML.CriarXML(caminhoArquivoXML, txtNomeExcel.Text, txtNomeNodePadrao.Text); 
                    MessageBox.Show("A conversão para XML foi concluida com sucesso.","Conversão XML",MessageBoxButtons.OK,MessageBoxIcon.Information);
                }
            } // Usa o nome padrão para o arquivo XML gerado
            else if (txtNomeExcel.Text != "" && txtNomeNodePadrao.Text != "") 
            {
                if (File.Exists(txtNomeExcel.Text))
                {
                    ConverteXlsXml converteXML = new ConverteXlsXml();
                    converteXML.CriarXML(txtNomeExcel.Text, txtNomeNodePadrao.Text);
                    MessageBox.Show("A conversão para XML foi concluida com sucesso.","Conversão XML",MessageBoxButtons.OK,MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show("Informe os dados necessários para a conversão !!", "Conversão XML", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

Neste código após as validações da entrada do usuário usamos o método CriarXML() da classe ConvertXlsXml() passando os nomes do arquivo Excel , do arquivo XML e do Node do XML.

Criando a classe ConverteXlsXml e o método CriarXML

Vamos agora criar no projeto a classe ConverteXlsXml e o método CriarXML que são usados para fazer a conversão de XLS para XML.

O código da classe é

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Xml;
namespace CSharp_ExcelXML
{
    public class ConverteXlsXml
    {
        public bool CriarXML(string ArquivoXML, string ArquivoXLS, string NomeNode)
        {
            bool FoiCriado = false;
            try
            {
                DataTable dt = GetTabela(ArquivoXLS);
                XmlTextWriter writer = new XmlTextWriter(ArquivoXML, System.Text.Encoding.UTF8);
                writer.WriteStartDocument(true);
                writer.Formatting = Formatting.Indented;
                writer.Indentation = 2;
                writer.WriteStartElement("tbl_" + NomeNode);
                List<string> NomeColunas = dt.Columns.Cast<DataColumn>().ToList().Select(x => x.ColumnName).ToList(); 
                List<DataRow> RowList = dt.Rows.Cast<DataRow>().ToList();
                foreach (DataRow dr in RowList)
                {
                    writer.WriteStartElement(NomeNode);
                    // Obtem o nome dos Nós a partir dos nomes das colunas do DataTable
                    for (int i = 0; i < NomeColunas.Count; i++)
                    {
                        writer.WriteStartElement(NomeColunas[i]);
                        writer.WriteString(dr.ItemArray[i].ToString());
                        writer.WriteEndElement();
                    }
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Close();
                if (File.Exists(ArquivoXML))
                    FoiCriado = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return FoiCriado;
        }
        // Cria o arquivo XML com o nome padrão do arquivo
        public bool CriarXML(string ArquivoXLS, string NomeNode)
        {
            bool FoiCriado = false;
            try
            {
                // O nome do arquivo XML é o mesmo do arquivo Excel
                string ArquivoXML = ArquivoXLS.Replace(Path.GetExtension(ArquivoXLS), "") + ".xml";
                DataTable dt = GetTabela(ArquivoXLS);
                XmlTextWriter writer = new XmlTextWriter(ArquivoXML, System.Text.Encoding.UTF8);
                writer.WriteStartDocument(true);
                writer.Formatting = Formatting.Indented;
                writer.Indentation = 2;
                writer.WriteStartElement("tbl_" + NomeNode);
                //lista dos nomes das colunas
                List<string> NomeColunas = dt.Columns.Cast<DataColumn>().ToList().Select(x => x.ColumnName).ToList();
                List<DataRow> RowList = dt.Rows.Cast<DataRow>().ToList();
                foreach (DataRow dr in RowList)
                {
                    writer.WriteStartElement(NomeNode);
                    // Obtêm o nome dos Nós a partir dos nomes das colunas do DataTable
                    for (int i = 0; i < NomeColunas.Count; i++)  
                    {
                        writer.WriteStartElement(NomeColunas[i]);
                        writer.WriteString(dr.ItemArray[i].ToString());
                        writer.WriteEndElement();
                    }
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Close();
                if (File.Exists(ArquivoXML))
                    FoiCriado = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return FoiCriado;
        }
        private DataTable GetTabela(string ArquivoXLS)
        {
            DataTable dt = new DataTable();
            try
            {
                string Ext = Path.GetExtension(ArquivoXLS);
                string connectionString = "";
                if (Ext == ".xls")
                {   //Para Excel 97-03  
                    connectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source =" + ArquivoXLS + "; Extended Properties = 'Excel 8.0;HDR=YES'";
                }
                else if (Ext == ".xlsx")
                {    //Para Excel 07 e superior
                    connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source =" + ArquivoXLS + "; Extended Properties = 'Excel 8.0;HDR=YES'";
                }
                OleDbConnection conn = new OleDbConnection(connectionString);
                OleDbCommand cmd = new OleDbCommand();
                OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
                cmd.Connection = conn;
                //Nome da primeira Planilha
                conn.Open();
                DataTable dtSchema;
                dtSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
                string ExcelSheetName = dtSchema.Rows[0]["TABLE_NAME"].ToString();
                conn.Close();
                //Lê todos os dados da planiliha para o datatable
                conn.Open();
                cmd.CommandText = "SELECT * From [" + ExcelSheetName + "]";
                dataAdapter.SelectCommand = cmd;
                // Preenche o datatable a partir da planilha
                dataAdapter.Fill(dt); 
                conn.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return dt;
        }
    }
}

A classe ConverteXlsXml  possui 3 métodos :

Executando o projeto e selecionando um arquivo XML teremos o resultado:

1- Vamos converter o arquivo Excel NotasAlunos.xlsx que possui o seguinte conteúdo :

2- Iniciando o projeto e informando o arquivo acima e o nome do arquivo XML a ser gerado como NotaAlunos.xml com node Aluno:

3- Ao clicar no botão Converter teremos o seguinte resultado :

Verificando a pasta c:\dados\xls temos o arquivo NotasAlunos.xml gerado com o seguinte conteúdo:

Perfeito !!!!

Pegue o projeto completo aqui:  CSharp_ExcelXML.zip

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti