[Tips] Exportar String a PDF en ASP.NET con iTextSharp

Una de las consultas recurrentes que recibo es sobre como crear pdf en ASP.NET, para esto hay varias respuestas, esta vez voy a mostrar una bastante sencilla de la mano de iTextSharp, que es una biblioteca gratis con muy buenas opciones para la generación pdf a partir de un string que almacena un HTML.

Lo primero que vamos a hacer es , mediante Nuget, obtener la biblioteca:

image

Una vez instalado, vamos a agregar (esto es opcional) una carpeta en donde estén nuestras plantillas para imprimir nuestro informe:

image

Este archivo test.html no es nada más que un archivo HTML en donde agregué el siguiente código:

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    <title></title>

</head>

<body>

    <p>Nombre:[nombre]</p>

    <p>Apellido:[apellido]</p>

    <p>Edad:[edad]</p>

</body>

</html>

Como puedes ver es bastante simple, y tambien verás que tengo [campos] que son los que vamos a remplazar con los datos que se van a agregar desde la siguiente Pagina aspx:

image

Ahora en el botón agregamos:

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

      Dim document = New Document(PageSize.A4, 50, 50, 25, 25)

      Dim output = New MemoryStream()

      Dim writer = PdfWriter.GetInstance(document, output)

      document.Open()

      Dim contents As String = File.ReadAllText(Server.MapPath("/HTMLTemplate/Test.html"))

      contents = contents.Replace("[nombre]", tx_nombre.Text)

      contents = contents.Replace("[apellido]", tx_apellido.Text)

      contents = contents.Replace("[edad]", tx_edad.Text)

 

 

      Dim parsedHtmlElements = HTMLWorker.ParseToList(New StringReader
                                                  (contents),
Nothing
)

      For Each var As IElement In parsedHtmlElements

            document.Add(TryCast(var, IElement))

      Next

   document.Close()

   Response.ContentType = "application/pdf"

   Response.AddHeader("Content-Disposition", "attachment;filename=test.pdf")

   Response.BinaryWrite(output.ToArray())

 

End Sub

Como puedes ver, estamos creando el documento con las dimensiones especificadas en el contructor, luego leemos el contenido del archivo html para finalmente reemplazar el contenido del los campos con [corchetes]. Finalmente escribimos el pdf.

image

Abrimos y listo!, PDF creado:

image

Obviamente esto es una simplificación al máximo de lo que se puede realizar , te recomiendo que visites la página del proyecto para muchas más opciones:

http://sourceforge.net/projects/itextsharp/

Saludos!.,
@chalalo

Comenzando con ASP.NET Web API y Odata , Parte 2

Hola, vamos a seguir revisando este tema de Web API junto con Odata, está vez voy a utilizar una clase para ver algunas potencialidades del sistema de consulta.

Voy a seguir utilizando el ejemplo del artículo anterior, el cual iremos completando poco  a poco.

Lo primero que vamos a hacer es agregar una nueva clase al proyecto en la carpeta models:

image

A esta clase le voy a llamar Asignatura, la cual va a tener la siguiente estructura:

  public class Asignatura

     {

        public int ID { get; set; }

        public string Nombre { get; set; }

        public int Creditos { set; get; }

        public int Semestre { set; get; }

 

    }

A continuación vamos a agregar un controlador específico para esta clase, la cual nos va a proveer del manejo de los HTTP request para esta entidad, vamos a elegir controlador de la API vacío, ya que crearemos a mano las acciones necesarias.

image

Puedes notar que al agregar el controlador, la clase deriva de APIController, debemos modificar esto a EntitySetController:

image

Ahora, puede ser que veas que no tienes el ensamblado System.Web.Http.OData , por lo que deberás incluir el ensamblado, yo lo hice mediante Nuget

image

Podemos crear el endpoint utilizando la clase ODataController directamente, sin embargo EntitySetController maneja los detalles de la creación correcta de las respuesta HTTP en conformidad con OData.  Esto nos permetirá centrarnos en el código específico de la aplicación. Lac lase EntitySetController toma dos parámetros de tipo de genérico: El primero es el tipo de la entidad (Asignatura) y el segundo es del tipo clave de la entidad, en nuestro caso , lo definimos con int. El esquema es el siguiente:

image

Ahora vamos a agregar una lista de asignaturas al controlador:

 

public class AsignaturaController : EntitySetController<Asignatura, int>

{

static List<Asignatura> asignaturas = new List<Asignatura>()

{

  new Asignatura() { ID=1, Nombre="Calculo I", Creditos=6, Semestre=1 },

  new Asignatura() { ID=2, Nombre="Algebra I", Creditos=6, Semestre=1 },

  new Asignatura() { ID=3, Nombre="Calculo II",Creditos=6, Semestre=2 },

  new Asignatura() { ID=4, Nombre="Algebra II",Creditos=6, Semestre=2 },

};

}

Luego veremos un ejemplo con acceso a bases de datos. Para soportar los request GET, que corresponden a lectura general de la colección y la lectura de un objeto en particular de la colección:

public override IQueryable<Asignatura> Get()

{

  return asignaturas.AsQueryable();

}

 

 

protected override Asignatura GetEntityByKey(int key)

{

    return asignaturas.FirstOrDefault(p => p.ID == key);

}

Ahora solo nos faltaría configurar los endpoint, para esto vamos a ir a la carpeta App_start y abrir el archivo WebApiConfig.cs, la cual tiene la configuración del la web api, vamos agregar en el método Register:

ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();

modelBuilder.EntitySet<Asignatura>("Asignaturas");

 

Microsoft.Data.Edm.IEdmModel model = modelBuilder.GetEdmModel();

config.Routes.MapODataRoute("ODataRoute", "odata", model);

 

Este código realiza dos cosas:

Crea un Entity Data Model para el Endpoint de Odata

Configura el EndPoint

 

 

El EDM es una modelo abstracto de datos, es usado para la creación de la metadata del documento (clase a devolver) para el servicio que creamos.

El método  EntitySet   agrega la entidad al set EDM:

modelBuilder.EntitySet<Asignatura>("Asignaturas");

El String “Asignaturas” define el nombre del entity Set, el nombre del controlador debe coincidir con el nombre del entity set.

Y ya estamos Listos!, vamos a probarlo con la URL http://localhost:1927/Odata/Asignaturas/

y tenemos:

{
  "odata.metadata":"
http://localhost:1927/odata/$metadata#Asignaturas","value":[
    {
      "ID":1,"Nombre":"Calculo I","Creditos":6,"Semestre":1
    },{
      "ID":2,"Nombre":"Algebra I","Creditos":6,"Semestre":1
    },{
      "ID":3,"Nombre":"Calculo II","Creditos":6,"Semestre":2
    },{
      "ID":4,"Nombre":"Algebra II","Creditos":6,"Semestre":2
    }
  ]
}

También podemos probar obteniendo solo un registro con la URL: http://localhost:1927/Odata/Asignaturas(2) y obtendremos:

  {
  "odata.metadata":"http://localhost:1927/odata/    $metadata#Asignaturas/@Element","ID":2,"Nombre":"Algebra I","Creditos":6,"Semestre":1
}

Como puedes ver consultamos el ID del registro que deseamos con el id entre paréntesis.

Bueno, seguiremos viendo OData con este objeto para que veamos más posibilidades de consulta, espero que te haya servido el artículo!

Saludos,
@chalalo