You are on page 1of 8

Generar archivos PDF con C#

En este articulo vamos a ver como generar documentos PDF con C# directamente desde cdigo. Antes de nada, dar la gracias a Raul - compaero de trabajo - por ensearme que existia iTextSharp - la librera que vamos a utilizar para este ejemplo. Normalmente, cuando queremos generar un documento PDF recurrimos a una impresara virtual PDF - como explicamos en este artculo: http://www.devjoker.com/contenidos/Articulos/311/DoPDF-Crea-archivos-PDF-facilmente.aspx, pero en muchas ocasiones necesitamos hacerlo directamente desde cdigo. Ya hemos dicho que vamos a utilizar iTextSharp - una librera que proviene del mundo Java (iText), pero que ha sido portada a C# y que podemos descargar desde el siguiente enlace:
http://sourceforge.net/projects/itextsharp/

En este ejemplo hemos utilizado C# 3.0 ( Visual Studio 2008 ) - es decir .Net Framework 3.5 - , pero la librera funciona correctamente con cualquier versin de .Net, incluido el Framework 1.0. Vamos a obviar temas de permisos de escritura en los directorios y esas cosas, asuminos que tenemos los permisos necesarios para escribir en disco y esas cosas (aunque como veremos ms adelante tambin podramos usar un MemoryStream).

Mi primer documento PDF.


Lo primero que tenemos que hacer es decargar la librera desde el enlace que hemos indicado y aadir la referencia a nuestro proyecto: itextsharp.dll. En mi caso he creado un proyecto de tipo Windows Forms, y he diseado un formulario con un nico botn que servira para crear el documento pdf. Tenemos que incluir las siguientes directivas using a nuestro formulario:

using iTextSharp.text; using iTextSharp.text.pdf; using System.IO; Crear documentos PDF es realmente simple, vemos como y lo explicamos un poco ms adelante.

private void button1_Click(object sender, EventArgs e) {

Document document = new Document(); PdfWriter.GetInstance(document, new FileStream("devjoker.pdf", FileMode.OpenOrCreate)); document.Open(); document.Add(new Paragraph("Este es mi primer PDF al vuelo")); document.Close(); } Con esto ya tenemos nuestro primer PSF. Vamos a ver que hemos hecho ... Creamos un objeto de tipo Document. Es nuestro PDF. Invocamos al mtodo estatico GetInstance de la clase PdfWriter - como argumentos recibe el documento que acabamos de crear y un Stream. En este caso utilizamos un FileStream pero podramos haber usado cualquier Stream que admita escritura como por ejemplo MemoryStream. Abrimos el documento con el mtodo Open. Le aadimos un parrafo con Add. Debemos darnos cuenta que el mtodo Add recibe como parametro una interface -IElement. Esto nos va a simplificar enormemente el trabajo. Cerramos el documento con Close. Que dificil! Con esto ya tenemos creado el archivo en la ruta indicada al FileStream (en mi caso la misma ruta que el ejecutable). La librera es bastante amplia y permite controlar casi todo. Por ejemplo, para modificar la fuente y el tamao del parrafo solo tendremos que utilizar el siguiente cdigo:

Chunk chunk = new Chunk("Texto subrayado", FontFactory.GetFont("ARIAL", 12, iTextSharp.text.Font.UNDERLINE ));

document.Add(new Paragraph(chunk ));

Como hemos comentado antes, el mtodo Add recibe como parmetro una interface - IElement . Todos los objetos que podemos aadir al documento implementan esta interface por lo que la manera de aadir elementos al documento es siempre la misma. Por ejemplo, insertar una imagen en el documento es igual de simple que un parrafo, solo cambiamos el objeto Paragraph pr un objeto Image (no confundir con System.Drawing.Image!):

iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(@"C:\...\ghostsandgoblins.jpg"); jpg.Alignment = iTextSharp.text.Image.MIDDLE_ALIGN; document.Add(jpg); Solo hemos visto una mnima para de la funcionalidad que ofrece la librera, pero espero que sea suficiente como para que os pique la curiosidad. Podemos encontrar un completo tutorial de como usar la librera en esta direccin:http://itextsharp.sourceforge.net/tutorial/index.html

ASP.NETGenerar PDF al vuelo con imagenes, enlaces y tablas

Hace varios aos, cuando necesit generar un archivo pdf formateado se me hizo muy difcil hallar informacin para construir un catlogo de productos en PDF que incluya imgenes tablas y enlaces. Es por este motivo que surge este post: para facilitarle la vida a los

desarrolladores que necesitan crear un documento con imgenes y enlaces en un archivo PDF. Para la generacin del PDF vamos a usar la ya reconocida librera iTextSharp. Algo ms, el archivo se generar al vuelo, osea en el momento que el usuario solicite el archivo esto tiene la ventaja de que el pdf siempre estar actualizado dado que suponemos que el pdf se generar con informacin guardada en la base de datos, pero nosotros en este post obviaremos ese paso para simplificar el post. Para solicitar el archivo pdf, tendremos un hyperlink en cual tiene un parmetro querystring con el id del documento a solicitar y este hyperlink, har el llamado a un manejador genrico o handler, quien finalmente ser quien genere el pdf. Algo como esto: <asp:HyperLink ID="hplDownload" NavigateUrl="~/PdfGenerator.ashx?did=5" runat="server">Descargar...</asp:HyperLink> Como pueden observar, el enlace del hyperlink llama a un manejador de peticiones, el cual recibe el id del documento. Bueno, ya hemos dicho a grandes rasgos en que consiste este post, ahora vamos al cdigo:
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Generar documento pdf al vuelo con imagenes y enlaces</title> </head> <body> <form id="form1" runat="server"> <p> Haga click en el enlace para descargar el archivo pdf <br /> <asp:HyperLink ID="hplDownload" NavigateUrl="~/PdfGenerator.ashx?did=5" runat="server">Descargar...</asp:HyperLink> </p> </form> </body> </html>

Este es un extracto del cdigo que va en el manejador de peticiones web:


Imports Imports Imports Imports System.Web System.IO iTextSharp.text iTextSharp.text.pdf

Public Class PdfGenerator Implements IHttpHandler Sub ProcessRequest(ByVal ctx As HttpContext) Implements IHttpHandler.ProcessRequest Dim did As String = ctx.Request.QueryString("did") If IsNumeric(did) Then CreatePDFDocument(did)

End Sub Private Sub CreatePDFDocument(ByVal did As Integer) Dim MStream As New MemoryStream() Dim document As New Document(PageSize.A4, 80, 50, 30, 65) Dim writer As PdfWriter = PdfWriter.GetInstance(document, MStream) writer.CloseStream = False document.Open() 'header.................... Dim logo As Image = Image.GetInstance(GetApplicationPhysicalPath() & "images\header.jpg") Dim cell As New Cell(logo) cell.BorderWidth = 0 Dim TableHead As New Table(1, 1) TableHead.Width = 100 TableHead.Border = 0 TableHead.Cellpadding = 10 TableHead.BorderColor = iTextSharp.text.Color.WHITE TableHead.AddCell(cell) document.Add(TableHead) 'content................... Dim TableContent As New Table(2, 4) TableContent.Width = 100 TableContent.Cellpadding = 2 TableContent.Border = 0 TableContent.BorderColor = iTextSharp.text.Color.WHITE 'first row '----------------------------------------------Dim image0 As Image = Image.GetInstance(GetApplicationPhysicalPath() & "images\" & "image0.jpg") cell = New Cell() cell.BorderWidth = 0 cell.SetWidth("30%") cell.AddElement(image0) TableContent.AddCell(cell) Dim pMarca As New Phrase("Marca:", New Font(Font.BOLD)) Dim m As String = "Este es otro ttulo" & vbCr Dim pMarcaContent As New Phrase(m) Dim pLinea As New Phrase("Lnea:") Dim l As String = "Comics" & vbCr Dim pLineaContent As New Phrase(l) Dim pNombre As New Phrase("Nombre:") Dim n As String = "La historia del Comic" & vbCr Dim pNombreContent As New Phrase(n) Dim pCodigo As New Phrase("Cdigo:") Dim c As String = "1234567890"

Dim pCodigoContent As New Phrase(c) cell = New Cell() cell.BorderWidth = 0 cell.SetWidth("70%") cell.AddElement(pMarca) cell.AddElement(pMarcaContent) cell.AddElement(pLinea) cell.AddElement(pLineaContent) cell.AddElement(pNombre) cell.AddElement(pNombreContent) cell.AddElement(pCodigo) cell.AddElement(pCodigoContent) TableContent.AddCell(cell) 'second row '----------------------------------------------Dim pDescripcion As New Phrase(String.Format("Descripcin General:{0}", vbCr)) Dim desc As String = "Al hablar de los antecesores de la historieta, es inevitable " & _ "nombrar a los antiguos egipcios, que representaban muchos de sus mitos en dibujos y " & _ "jeroglficos que realizaban sobre hojas de papiro, y tambin hacan murales en forma de tira, " & _ "que incluan imagen y texto. Otros ejemplos son las cristaleras, el tapiz de Bayeux, las bandas que " & _ "rodean las columnas romanas conmemorativas (como la Trajana o la de Marco Aurelio), los retablos " & _ "medievales (con los que, mediante imgenes, se explicaban al pueblo historias, crmenes y sucesos " & _ "en general), los dibujos de las civilizaciones precolombinas (como los cdices, pintados por los mayas y " & _ "los aztecas) e incluso las primitivas pinturas rupestres. A estos ejemplos citados se pueden agregar algunas " & _ "obras pictricas de Hyeronnimus Bosh, Brueghel o Goya, las cuales adquieren un carcter narrativo." Dim pDescripcionContent As New Phrase(desc) cell = New Cell() cell.BorderWidth = 0 cell.Colspan = 2 cell.AddElement(pDescripcion) cell.AddElement(pDescripcionContent) TableContent.AddCell(cell) 'third row '----------------------------------------------Dim pInformacion As New Phrase(String.Format("Informacin:{0}", vbCr)) Dim inf As String = "Pero quizs los antecedentes ms cercanos a la historietas sean las Aucas y Aleluyas, " & _ "destinadas fundamentalmente a satisfacer las necesidades de instruccin de nios y adolescentes. " & _

"Estas publicaciones, que comenzaron a editarse en Francia a partir de 1820, se caracterizaban por narrar " & _ "pequeos cuentos y aventuras mediante ilustraciones, aunque, a diferencia de la historieta, los textos no " & _ "se integraban orgnicamente dentro de los dibujos, sino que se adicionaban a modo de explicacin " & _ "complementaria al pie de los grabados. Sin embargo, la historia del cmic se relaciona ms correctamente " & _ "con la de la imprenta y la caricatura. " Dim pInformacionContent As New Phrase(inf) cell = New Cell() cell.BorderWidth = 0 cell.Colspan = 2 cell.AddElement(pInformacion) cell.AddElement(pInformacionContent) TableContent.AddCell(cell) 'fourth row '----------------------------------------------Dim miniTable As New Table(2, 1) miniTable.Width = 50 miniTable.Alignment = Table.ALIGN_LEFT miniTable.Border = 0 miniTable.BorderColor = iTextSharp.text.Color.WHITE Dim miniCell As New Cell() Dim image2 As Image = Image.GetInstance(GetApplicationPhysicalPath() & "images\" & "image2.jpg") miniCell.BorderWidth = 0 miniCell.AddElement(image2) miniTable.AddCell(miniCell) Dim image3 As Image = Image.GetInstance(GetApplicationPhysicalPath() & "images\" & "image3.gif") miniCell = New Cell() miniCell.BorderWidth = 0 miniCell.AddElement(image3) miniTable.AddCell(miniCell) cell = New Cell() cell.Colspan = 2 cell.BorderWidth = 0 cell.Add(miniTable) TableContent.AddCell(cell) document.Add(TableContent) Dim TableLine As New Table(1, 1) TableLine.Width = 100 TableLine.Border = 0 TableLine.Cellpadding = 10 TableLine.BorderColor = iTextSharp.text.Color.WHITE Dim Line As Image = Image.GetInstance(GetApplicationPhysicalPath() & "images\Line.png")

cell = New Cell() cell.BorderWidth = 0 cell.AddElement(Line) TableLine.AddCell(cell) document.Add(TableLine) Dim ph As New Phrase("Contctenos en: ") Dim a As Anchor = New Anchor("Neuronasoft", FontFactory.GetFont(FontFactory.HELVETICA, 12, Font.UNDERLINE, New Color(0, 0, 255))) a.Reference = "http://www.neuronasoft.net" document.Add(ph) document.Add(a) document.Close() HttpContext.Current.Response.ContentType = "application/pdf" HttpContext.Current.Response.Buffer = True HttpContext.Current.Response.ClearContent() HttpContext.Current.Response.ClearHeaders() HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=Comics_virtual.pdf") HttpContext.Current.Response.BinaryWrite(MStream.GetBuffer()) HttpContext.Current.Response.End() End Sub Private Function GetApplicationPhysicalPath() As String Return System.Web.HttpContext.Current.Request.PhysicalApplicationPath End Function ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class

Estoy adjuntando el proyecto completo, para que hagan las pruebas con un ejemplo funcionando.

You might also like