ASP .NET MVC 5 - Upload e leitura de arquivos CSV


 Hoje veremos como fazer o upload e a leitura de arquivos CSV em aplicações ASP .NET MVC 5.

Um arquivo CSV é um arquivo texto delimitado que utiliza a vírgulas para separar os valores existentes no arquivo, sendo que existem implementações onde outros separadores também podem ser usados.

Os arquivos CSV mais simples não permitem valores que contenham vírgula (Ex: Rua Teste, 100) ou outros caracteres especiais como o indicador de nova linha CR ou LF. (Carriage Return/ Line Feed) . Implementações mais sofisticadas permitem vírgulas, ponto e vírgula(;), asterístico(*) como delimitadores e outros caracteres especiais.

Por que eu estou escrevendo sobre arquivos CSV ?

Porque 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.

Assim, neste artigo eu mostro como fazer o upload e como importar arquivos CSV no formato padrão (delimitados por vírgula) em uma aplicação ASP .NET MVC,  e,  em seguida ler o conteúdo do arquivo CSV enviado exibindo o seu conteúdo na página web.

Não iremos usar o provedor Jet/ACE OLEDB, ao invés dele vamos usar o pacote nuget LumenWorksCsvReader.

recursos usados:

  • Visual Studio 2019 Community

Criando o projeto ASP .NET MVC 5

Abra o VS 2019 Community e crie uma solução em branco via menu File-> New Project;

Selecione o template ASP .NET Core Web Application, e, Informe o nome Mvc5_CSV1;

A seguir selecione o template Empty  e configurações conforme figura abaixo:

Clique no botão Create.

Após criar o projeto vamos incluir o pacote nuget : LumenWorksCsvReader

Se preferir pode usar a janela do gerenciador do Console e digitar: Install-Package LumenWorksCsvReader

Agora crie uma pasta chamada Controllers no projeto e nesta pasta crie o controlador HomeController usando a opção Add->Controller e selecionando a opção - MVC 5 Controller Empty.

Abaixo temos o código do controlador HomeController:

using System.Web.Mvc;
namespace Mvc5_CSV1.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult Upload()
        {
            return View();
        }
    }
}

Vamos criar a view Index.cshtml com o código abaixo:

@{
    ViewBag.Title = "Index";
}
<h2>Enviando e Lendo arquivos CSV</h2>
<hr />
<h3><a href="http://www.macoratti.net">Macoratti .net</a></h3>

 

A seguir crie a view Upload.cshtml usando o código a seguir:

@model System.Data.DataTable
@using System.Data;
<h2>Enviar Arquivo</h2>
@using (Html.BeginForm(
  "Upload", "Home", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()
    <div class="form-group">
        <input type="file" id="dataFile" name="upload" />
    </div>
    <div class="form-group">
        <input type="submit" value="Upload" class="btn btn-default" />
    </div>
    if (Model != null)
    {
        <table>
            <thead>
                <tr>
                    @foreach (DataColumn col in Model.Columns)
                    {
                        <th>@col.ColumnName</th>
                    }
                </tr>
            </thead>
            <tbody>
                @foreach (DataRow row in Model.Rows)
                {
                    <tr>
                        @foreach (DataColumn col in Model.Columns)
                        {
                            <td>@row[col.ColumnName]</td>
                        }
                    </tr>
                }
            </tbody>
        </table>
    }
}
 

Na view Upload temo o formulário que permite ler o arquivo CSV usando o método POST Upload que iremos definir a seguir:

using LumenWorks.Framework.IO.Csv;
using System.Data;
using System.IO;
using System.Web;
using System.Web.Mvc;
namespace Mvc5_CSV1.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            return View();
        }
        public ActionResult Upload()
        {
            return View();
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Upload(HttpPostedFileBase upload)
        {
            if (ModelState.IsValid)
            {
                if (upload != null && upload.ContentLength > 0)
                {
                    if (upload.FileName.EndsWith(".csv"))
                    {
                        Stream stream = upload.InputStream;
                        DataTable csvTable = new DataTable();
                        using (CsvReader csvReader =
                            new CsvReader(new StreamReader(stream), true))
                        {
                            csvTable.Load(csvReader);
                        }
                        return View(csvTable);
                    }
                    else
                    {
                        ModelState.AddModelError("Arquivo", "Formato do arquivo não é suportado");
                        return View();
                    }
                }
                else
                {
                    ModelState.AddModelError("Arquivo", "Faça o Upload do arquivo");
                }
            }
            return View();
        }
    }
}

Implementamos o método Upload POST no controlador HomeController para ler o arquivo CSV usando a biblioteca LumenWorksCsvReader.

Vamos incluir no arquivo _Layout.cshtml o código para criar a opção de menu Upload:

...

    @Html.ActionLink("Enviar/Ler CSV", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
   </div>

   <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                   
<li>@Html.ActionLink("Upload","Upload","Home")</li>
              </ul>
    </div>

...

Executando o projeto teremos o resultado abaixo:

Pegue o projeto (sem as referências) aqui :  Mvc5_CSV1.zip

"E (Jesus) disse-lhes: Acautelai-vos e guardai-vos da avareza; porque a vida de qualquer não consiste na abundância do que possui.""
Lucas 12:15

 

Referências:


José Carlos Macoratti