ASP .NET MVC 5 - Converter Lista de Objetos para CSV


 Hoje veremos como converter uma lista de objetos para 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.

Hoje veremos como converter uma lista de objetos para o formato CSV e vamos gerar os objetos a partir de uma tabela de um banco de dados SQL Server usando o Entity Framework 6.

Podemos usar qualquer banco de dados e como exemplo para este artigo vou usar o banco de dados Northwind para o SQL Server que pode ser baixado aqui.

Vamos usar a tabela Employees deste banco de dados que tem a seguinte estrutura:

recursos usados:

  • Visual Studio 2019 Community
  • Entity Framework 6.2

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_ListCSV;

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

Clique no botão Create.

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

Agora na pasta Models do projeto vamos criar a classe Employee :

    public class Employee
    {
        public int EmployeeId { get; set; }
        public string FirstName { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
    }

Criei uma classe POCO com 4 propriedades que vai mapear para a tabela Employees. Vamos mapear apenas essas propriedades.

A seguir vamos criar a classe de contexto AppDbContext na pasta Models com o seguinte código:

using System.Data.Entity;
namespace Mvc5_ListCSV.Models
{
    public class AppDbContext : DbContext
    {
        public AppDbContext() : base("AppDbContext")
        {}
        public DbSet<Employee> Employees { get; set; }
    }
}

Aqui definimos o mapeamento da entidade para tabela do banco de dados.

Agora precisamos definir a string de conexão com o banco de dados Northwind no web config:

...
<connectionStrings>
    <add name="AppDbContext" providerName="System.Data.SqlClient" 
connectionString="Data Source=(localdb)\v11.0;Initial Catalog=master;Integrated Security=True;Connect 
Timeout=30;Encrypt=False;TrustServerCertificate=False; ApplicationIntent=ReadWrite;
MultiSubnetFailover=False" />
</connectionStrings>

...

Ajustando o controlador HomeController para obter os objetos e gerar o CSV

Vamos agora alterar o código do controlador HomeController na pasta Controllers conforme a seguir:

using Mvc5_ListCSV.Models;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Mvc5_ListCSV.Controllers
{
    public class HomeController : Controller
    {
        // GET: Home
        public ActionResult Index()
        {
            AppDbContext db = new AppDbContext();

            var employees = db.Employees.ToList();

            return View(employees);
        }

        [HttpPost]
        public FileResult Exportar()

        {
            AppDbContext db = new AppDbContext();

            //obtem uma lista de objetos Employee
            List<object> employees = (from employee in db.Employees.ToList().Take(9)
                                                select new[] { employee.EmployeeId.ToString(),
                                                            employee.FirstName,
                                                            employee.City,
                                                            employee.Country
                                                 }).ToList<object>();

            //Insere o nome das colunas
            employees.Insert(0, new string[4] { "Employee ID", "Employee Name", "City", "Country" });

            StringBuilder sb = new StringBuilder();

            //percore os funcionarios e gera o CSV
            for (int i = 0; i < employees.Count; i++)
            {
                string[] employee = (string[])employees[i];
                for (int j = 0; j < employee.Length; j++)
                {
                    //anexa dados com separador
                    sb.Append(employee[j] + ',');
                }

                //Anexa uma nova linha
                sb.Append("\r\n");
            }
            return File(Encoding.UTF8.GetBytes(sb.ToString()), "text/csv", "GridFuncionarios.csv");
        }
    }
}

Neste código temos dois métodos Action :

  • Index (Get) - Gera os dados dos funcionários obtendo-os a partir da tabela Employees;
  • Exportar (Post) -  Obtém novamente os dados e gera o arquivo CSV retornando o download do arquivo - GridFuncionarios.csv;

Para concluir vamos alterar o código da view Index.cshtml:

@model IEnumerable<Mvc5_ListCSV.Models.Employee>
@{
    Layout = null;
    WebGrid webGrid = new WebGrid(source: Model, canSort: false, canPage: false);
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Funcionários</title>
    <style type="text/css">
        body {
            font-family: Arial;
            font-size: 10pt;
        }
    </style>
</head>
<body>
    <h4>Funcionários</h4>
    <hr />
    <div id="Grid">
        @webGrid.GetHtml(
        htmlAttributes: new { @id = "WebGrid" },
        columns: webGrid.Columns(
                 webGrid.Column("EmployeeID", "EmployeeId"),
                 webGrid.Column("FirstName", "FirstName"),
                 webGrid.Column("City", "City"),
                 webGrid.Column("Country", "Country")))
    </div>
    <br />
    <br />
    @using (Html.BeginForm("Exportar", "Home", FormMethod.Post))
    {
        <input type="submit" id="btnSubmit" value="Exportar" />
    }
</body>
</html>

Estamos implementando o WebGrid para exibir os dados dos funcionários e ao clicar no botão Exportar iremos acionar o método Action Exportar do controlador Home que vai gerar o arquivo:

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

"Bendito seja o Deus e Pai de nosso Senhor Jesus Cristo, o Pai das misericórdias e o Deus de toda a consolação;
Que nos consola em toda a nossa tribulação, para que também possamos consolar os que estiverem em alguma tribulação, com a consolação com que nós mesmos somos consolados por Deus."
2 Coríntios 1:3,4

 

Referências:


José Carlos Macoratti