Utilizando razor para generar un csv

En muchos de nuestros desarrollos nos solicitan la funcionalidad de exportar nuestros datos a diferentes formatos y hoy me ha tocado exportar a csv.

Lo lógico, es que lo hubiese hecho de la forma tradicional simple y sencillo defino un StringWriter y un foreach hasta que acabe,pero los años me están haciendo despertar la imaginación,con lo cual he pensado en hacerlo de otra formaSonrisa.

¿Cómo?.Voy a utilizar una vista que se encargue de generar el csv.

Manos a la obra.

Partimos para el ejemplo de un modelo sencillo una factura con las siguientes propiedades Número,Fecha e Importe.

using System;
using System.Collections.Generic;
using System.Linq;


namespace MvcApplication15.Models
{
    public class Factura
    {
        public int Id { get; set; }
        public DateTime FechaFactura { get; set; }
        public Decimal Importe { get; set; }
    }
}

Lógicamente el segundo paso es crear un controlador y un método dentro de él que nos permita solicitar el csv.

Que tengo que hacer, pues retornar un FileContentResult con MimeType “text/csv”.

public ActionResult GetCsv()
{
    //Generamos RazorViewEngine
    var razorView = new RazorViewEngine();
    var viewEngineResult = razorView
             .FindPartialView(ControllerContext, "_GetCsv", false);

    //Creamos la vista y pasamos el modelo
    var modelo = new List<Factura>()
    {
        new Factura(){Id=1,
                      FechaFactura = DateTime.Now.Date,
                      Importe = 1000},

        new Factura(){Id=1,
                      FechaFactura = DateTime.Now.AddDays(1).Date,
                      Importe = 2000}
    };
    var vista = View(viewEngineResult.View, modelo);

    //Renderizamos la vista
    using (StringWriter sw = new StringWriter())
    {
        var viewContext = new ViewContext(
            ControllerContext, 
            vista.View, 
            vista.ViewData, 
            vista.TempData, sw);
        
        vista.View.Render(viewContext, sw);
        
        var result = Encoding.UTF8.GetBytes(sw.ToString());
        
        viewEngineResult.ViewEngine
            .ReleaseView(ControllerContext, vista.View);
        
        return File(result, "text/csv", "facturas.csv");
    }
            

}

y por último tenemos que definir nuestra vista y solicitar nuestro archivo desde el explorador.

@model IEnumerable<MvcApplication15.Models.Factura>
@{
<text>Numero;Fecha;Importe</text>
}
@foreach (var item in Model)
{
<text>@item.Id;@string.Format("{0:dd/MM/yyyy}", item.FechaFactura);
      @string.Format("{0:###,###,##0.00}", item.Importe)</text>    
}
Nota: todo el texto que que se escribe dentro de las etiquetas <text> 
debe de estar en una sola línea.

Conclusiones.

Pues sencillo que MVC nos deja hacer escapar nuestra imaginación hasta límites insospechables, gracias a ser un framework abierto crece y crece o lo podemos hacer crecer Sonrisa.

Espero que os guste y sea de utilidad.

3 comentarios en “Utilizando razor para generar un csv”

  1. Muy bueno el aporte Pedro!

    Ahora te pregunto yo, ¿En este caso no sería mas aconsejable crearte un ActionResult personalizado para csv? Así podrás usarlo en cualquiera de tus controladores.

    Un saludo

  2. Hola Luis,

    Gracias por contestar

    Te cuento aparte de un experimento:). El problema es que necesito a partir del mismo modelo devolver diferentes resultados en función de los roles de cada usuario con lo cual como puedes imaginar cada uno tiene un formato diferente de salida.

    Y de esta forma simplemente cambiando la vista puedo personalizar la salida.

    Lo otro se podría hacer tal y como comentas pero me obligaba a crear diferentes objetos y no está claro en la especificación.

    Saludos,

  3. Muy buen post.

    Soy más de la opinión de Luis: para mi, para este caso *concreto* es mejor usar un custom view result.

    Lo bueno del post es que se ven las capacidades de Razor para permitir realizar de forma rápida y sencilla pequeñas herramientas de “templating”. Probablemente un CSV es tan sencillo en su formato que no se justifica, pero para formatos más complejos puede ser interesante.

    Un saludo!!!!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *