ASP.NET - Importando um arquivo CSV para um DataTable


Em aplicações web muitas vezes temos que importar arquivos a partir de uma fonte externa de dados como um arquivo Excel, arquivo CSV, arquivo texto, etc.

Nestes casos como proceder ?

O ASP .NET Framework fornece uma solução simples para importar dados a partir de uma fonte de dados usando o provedor Microsoft.Jet.OLEDB. Apesar disso podem ocorrer muitos problemas quando o arquivo de dados externo possuir muitas colunas com diferentes tipos de dados.

Nestes casos o provedor basicamente não consegue diferenciar os tipos de dados entre as colunas e linhas e para resolver este problema geralmente usamos um arquivo schema.ini para definir os tipos de dados para o arquivo CSV ou arquivo texto e permitir dessa forma que o provedor leia e reconheça o tipo de dados exato para cada coluna.

Neste artigo vou mostrar como importar um arquivo CSV contendo diferentes tipos de dados para um banco de dados usando o Microsoft Jet DataBase Engine e também o arquivo Schema.ini. Será mais uma opção às diversas formas de tratar este problema.

Comma-separated values (ou CSV) é um formato de arquivo que armazena dados tabelados, cujo grande uso data da época dos mainframes. Por serem bastante simples, arquivos .csv são comuns em todas as plataformas de computador.

O CSV é um implementação particular de arquivo texto separados por um delimitador, que usa a vírgula e a quebra de linha para separar os valores. O formato também usa as aspas em campos no qual são usados os caracteres reservados (vírgula e quebra de linha). Essa robustez no formato torna o CSV mais amplo que outros formatos digitais do mesmo segmento.(http://pt.wikipedia.org/wiki/Comma-separated_values)

Exemplo de um arquivo CSV:

Arquivo Agenda de contatos
1979, Macoratti, São Paulo, SP. 125500
1980, Jose Carlos, Rio De Janeiro, RJ, 210125
1992, Ana Maria, Marilia, SP , 134525
2000, Janice , Parana, PR, 789452

Afinal , o que é um arquivo Schema.ini ?

O arquivo schema.ini é um arquivo de informação usado para definir a estrutura de dados e o formato de cada coluna que contém dados no arquivo CSV. Se este arquivo existir no diretório o provedor Microsoft.Jet.OLEDB automaticamente lê e reconhece a informação sobre os tipos de dados que cada coluna contém no arquivo CSV.

Dessa forma a criação de arquivo schema.ini faz com que a informação correta seja lida e que erros que poderiam ocorrer na interpretação dos dados seja evitados

Antes de criar um arquivo schema.ini você tem que saber que existem as seguintes regras que devem ser seguidas:

Para ilustrar, considere um arquivo CSV com 5 colunas : Nome, Endereco, Idade, Salario e Data contendo a seguinte estrutura de dados:

Nome da Coluna    Tipos de Dados       Largura      Formato  
Nome Text 100  
Endereco Text 100  
Idade Long    
Salario Double    
Data DateTime   dd/MMM/yyyy

Vamos considerar que precisamos fazer um upload deste arquivo CSV em usando dois cenários diferentes:

Vamos usar como exemplo o arquivo funcionarios.csv cujo conteúdo é exibido a seguir:

Relação de funcionários - 2009
Jose Carlos Macoratti, Rua Projetada 100, São Paulo, 35, 1200, 12/05/2009
Ana Maria Aoki, Av. Presidente LIma 900, Parana, 28 , 2500 , 12/07/2005
Carolina Bueno, Pça XV Novembro 230, Rio de Janeiro, 45 , 5600 , 15/11/2000


1-) Importando um arquivo CSV com o mesmo nome do arquivo

Para efetuar esta tarefa vamos seguir o seguinte roteiro:

  1. Abra o aplicativo Bloco de Notas ou um editor de texto de sua escolha;
  2. Cole e copie o seguinte conteúdo no Bloco de Notas (substitua 'arq_CSV_NomeArquivo.csv' pelo no do seu arquivo CSV);
arq_CSV_NomeArquivo.csv
ColNameHeder=True
Format=CVSDelimited
DateTimeFormat=dd-MMMM-yyyy
Col1=A Text width 100
Col2=B Text width 100
Col3=C Long
Col4=D Double
Col5=E DateTime
  1. Salve o arquivo com o nome 'schema.ini' no mesmo local do arquivo CSV;
  2. Crie um novo web site com o nome ImportaCSV e inclua na página Default.aspx um controle FileUpload, um controle Button e um controle GridView conforme o leiaute abaixo: (Vamos adotar o nome padrão para cada controle)
  1. Defina os seguintes namespaces que serão usados :
Imports System.Data.OleDb
Imports System.Data
Imports System.IO
  1. No evento Click do controle Button inclua o seguinte código:
 Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

        If FileUpload1.HasFile Then
            Dim fileinfo As New FileInfo(FileUpload1.PostedFile.FileName)
            Dim csvDiretorio As String = ""

            Dim strCaminhoArquivoCSV As String = (Server.MapPath(csvDiretorio) & "\") + fileinfo.Name

            'Salva o arquivo CSV no servidor na pasta csvDiretorio
            FileUpload1.SaveAs(strCaminhoArquivoCSV)

            'define a localização do arquivo CSV
            Dim strCaminhoArquivo As String = Server.MapPath(csvDiretorio) & "\"

            Dim strSql As String = "SELECT * FROM [" & fileinfo.Name & "]"

            Dim strCSVStringConexao As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _ 
strCaminhoArquivo & ";" & "Extended Properties='text;HDR=YES;'"

            ' carrega os dados do arquivo CSV para um DataTable 
            Dim da As New OleDbDataAdapter(strSql, strCSVStringConexao)
            Dim dtCSV As New DataTable()
            da.Fill(dtCSV)

            'Exibe os dados no gridview
            GridView1.DataSource = dtCSV
            GridView1.DataBind()
        End If
    End Sub
  1. Salve o projeto e pronto. Você já pode exportar os dados do arquivo CSV para o GridView em sua página ASP .NET.

2-) Importando um arquivo CSV com um nome diferente

Para enviar um arquivo CSV com um nome diferente a cada vez, teremos que criar o arquivo schema.ini em tempo de execução usando os objetos FileStream e StreamWriter antes de importar o arquivo CSV.

Neste caso o código do evento Click do botão de comando ficaria assim:

If FileUpload1.HasFile Then
            Dim fileinfo As New FileInfo(FileUpload1.PostedFile.FileName)
            Dim csvDiretorio As String = ""

            Dim strCaminhoArquivoCSV As String = (Server.MapPath(csvDiretorio) & "\") + fileinfo.Name

            'Salva o arquivo CSV no servidor na pastacsvDiretorio
            FileUpload1.SaveAs(strCaminhoArquivoCSV)

            'define a localização do arquivo CSV
            Dim strCaminhoArquivo As String = Server.MapPath(csvDiretorio) & "\"

            'cria em tempo de execução o arquivo schema.ini
            Using filestr As New FileStream(strCaminhoArquivo & "\schema.ini", FileMode.Create, FileAccess.Write)
                Using writer As New StreamWriter(filestr)
                    writer.WriteLine("[" & fileinfo.Name & "]")
                    writer.WriteLine("ColNameHeader=True")
                    writer.WriteLine("Format=CSVDelimited")
                    writer.WriteLine("DateTimeFormat=dd-MMM-yy")
                    writer.WriteLine("Col1=A Text Width 100")
                    writer.WriteLine("Col2=B Text Width 100")
                    writer.WriteLine("Col3=C Long")
                    writer.WriteLine("Col4=D Double")
                    writer.WriteLine("Col5=E DateTime")
                    writer.Close()
                    writer.Dispose()
                End Using
                filestr.Close()
                filestr.Dispose()
            End Using

            Dim strSql As String = "SELECT * FROM [" & fileinfo.Name & "]"
            Dim strCSVStringConexao As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strCaminhoArquivo & ";" _
 & "Extended Properties='text;HDR=YES;'"

            ' carrega os dados do arquivo CSV para um DataTable 
            Dim da As New OleDbDataAdapter(strSql, strCSVStringConexao)
            Dim dtCSV As New DataTable()
            da.Fill(dtCSV)

            'Exibe os dados no gridview
            GridView1.DataSource = dtCSV
            GridView1.DataBind()
        End If

No código acima usamos o objeto FileInfo para obter o nome do arquivo CSV para escrever no arquivo schema.ini.

Usando o componente FileUpload salvamos o arquivo CSV no diretório do servidor (csvDiretorio).

O arquivo schema.ini também tem que ser criado no mesmo diretório.

Usando a classes FileStream criamos o arquivo schema.ini , e então usando a classe StreamWriter criamos o conteúdo do arquivo schema.ini.

Depois disto basta ler o arquivo CSV usando o provedor Microsoft.Jet.OLEDB , carregar o seu conteúdo para um DataTable e exibir o resultado em um GridView. O resultado pode ser visto abaixo:

Eu sei é apenas ASP .NET, mas eu gosto...

Pegue o projeto completo aqui : ImportaCSV.zip

Referências:


José Carlos Macoratti