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 |
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:
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 |
Imports System.Data.OleDb Imports System.Data Imports System.IO
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
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