Saltar al contenido

Cómo convertir HTML a PDF usando iTextSharp

Hola, hallamos la solución a tu pregunta, desplázate y la obtendrás a continuación.

Primero, HTML y PDF no están relacionados aunque se crearon aproximadamente al mismo tiempo. HTML está destinado a transmitir información de nivel superior, como párrafos y tablas. Aunque existen métodos para controlarlo, en última instancia, es el navegador quien debe dibujar estos conceptos de nivel superior. PDF está destinado a transmitir documentos y los documentos debe “lucen” iguales dondequiera que se representen.

En un documento HTML, es posible que tenga un párrafo que sea 100% de ancho y, dependiendo del ancho de su monitor, puede tomar 2 líneas o 10 líneas y cuando lo imprime puede ser 7 líneas y cuando lo mira en su teléfono puede tomar 20 líneas. Sin embargo, un archivo PDF debe ser independiente del dispositivo de renderizado, por lo que, independientemente del tamaño de la pantalla, debe siempre renderizar exactamente lo mismo.

Por el deberes arriba, PDF no admite elementos abstractos como “tablas” o “párrafos”. Hay tres cosas básicas que admite PDF: texto, líneas / formas e imágenes. (Hay otras cosas como anotaciones y películas, pero estoy tratando de hacerlo simple aquí). En un PDF no dice “aquí hay un párrafo, ¡el navegador hace lo tuyo!”. En su lugar, dices, “dibuja este texto en esta ubicación exacta X, Y usando esta fuente exacta y no te preocupes, he calculado previamente el ancho del texto, así que sé que todo encajará en esta línea”. Tampoco dice “aquí hay una tabla”, sino que dice “dibuje este texto en esta ubicación exacta y luego dibuje un rectángulo en esta otra ubicación exacta que he calculado previamente para saber que parecerá estar alrededor del texto “.

En segundo lugar, iText y iTextSharp analizan HTML y CSS. Eso es todo. ASP.Net, MVC, Razor, Struts, Spring, etc., son todos marcos HTML, pero iText / iTextSharp los desconoce al 100%. Lo mismo ocurre con DataGridViews, repetidores, plantillas, vistas, etc., que son abstracciones específicas del marco. Está tu responsabilidad de obtener el HTML de su elección de marco, iText no lo ayudará. Si recibe una excepción que dice The document has no pages o piensa que “iText no está analizando mi HTML” es casi definitivo que en realidad no tiene HTML, solo cree que lo tiene.

En tercer lugar, la clase incorporada que ha existido durante años es la HTMLWorker sin embargo, esto ha sido reemplazado por XMLWorker (Java / .Net). No se está realizando ningún trabajo en HTMLWorker que no admite archivos CSS y solo tiene soporte limitado para las propiedades CSS más básicas y, de hecho, se rompe en ciertas etiquetas. Si no ve el HTML attribute o propiedad CSS y valor en este archivo, entonces probablemente no sea compatible con HTMLWorker. XMLWorker a veces puede ser más complicado, pero esas complicaciones también lo hacen más extensible.

A continuación se muestra el código C # que muestra cómo analizar etiquetas HTML en abstracciones de iText que se agregan automáticamente al documento en el que está trabajando. C # y Java son muy similares, por lo que debería ser relativamente fácil convertir esto. El ejemplo n. ° 1 usa el HTMLWorker para analizar el HTML string. Dado que solo se admiten los estilos en línea, class="headline" se ignora, pero todo lo demás debería funcionar. El ejemplo # 2 es el mismo que el primero excepto que usa XMLWorker en lugar de. El ejemplo n. ° 3 también analiza el ejemplo de CSS simple.

//Create a byte array that will eventually hold our final PDF
Byte[] bytes;

//Boilerplate iTextSharp setup here
//Create a stream that we can write to, in this case a MemoryStream
using (var ms = new MemoryStream()) 

    //Create an iTextSharp Document which is an abstraction of a PDF but **NOT** a PDF
    using (var doc = new Document()) 

        //Create a writer that's bound to our PDF abstraction and our stream
        using (var writer = PdfWriter.GetInstance(doc, ms)) 

            //Open the document for writing
            doc.Open();

            //Our sample HTML and CSS
            var example_html = @"

This is some sample text!!!

"; var example_css = @".headlinefont-size:200%"; /************************************************** * Example #1 * * * * Use the built-in HTMLWorker to parse the HTML. * * Only inline CSS is supported. * * ************************************************/ //Create a new HTMLWorker bound to our document using (var htmlWorker = new iTextSharp.text.html.simpleparser.HTMLWorker(doc)) //HTMLWorker doesn't read a string directly but instead needs a TextReader (which StringReader subclasses) using (var sr = new StringReader(example_html)) //Parse the HTML htmlWorker.Parse(sr); /************************************************** * Example #2 * * * * Use the XMLWorker to parse the HTML. * * Only inline CSS and absolutely linked * * CSS is supported * * ************************************************/ //XMLWorker also reads from a TextReader and not directly from a string using (var srHtml = new StringReader(example_html)) //Parse the HTML iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml); /************************************************** * Example #3 * * * * Use the XMLWorker to parse HTML and CSS * * ************************************************/ //In order to read CSS as a string we need to switch to a different constructor //that takes Streams instead of TextReaders. //Below we convert the strings into UTF8 byte array and wrap those in MemoryStreams using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css))) using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html))) //Parse the HTML iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss); doc.Close(); //After all of the PDF "stuff" above is done and closed but **before** we //close the MemoryStream, grab all of the active bytes from the stream bytes = ms.ToArray(); //Now we just need to do something with those bytes. //Here I'm writing them to disk but if you were in ASP.Net you might Response.BinaryWrite() them. //You could also write the bytes to a database in a varbinary() column (but please don't) or you //could pass them to another function for further PDF processing. var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf"); System.IO.File.WriteAllBytes(testFile, bytes);

Actualización de 2017

Hay buenas noticias para las demandas de HTML a PDF. Como mostró esta respuesta, el estándar css-break-3 del W3C resolverá el problema… Es una Recomendación Candidata con plan de convertirse en Recomendación definitiva este año, después de las pruebas.

Como no tan estándar, existen soluciones, con complementos para C #, como lo muestra print-css.rocks.

A partir de 2018, también hay iText7 (Una próxima iteración de la antigua biblioteca iTextSharp) y su paquete HTML a PDF disponible: itext7.pdfhtml

El uso es sencillo:

HtmlConverter.ConvertToPdf(
    new FileInfo(@"PathtoHtmlFile.html"),
    new FileInfo(@"PathtoPdfFile.pdf")
);

El método tiene muchas más sobrecargas.

Actualizar: La familia de productos iText * tiene un modelo de licencia dual: gratis para código abierto, pago para uso comercial.

@Chris Haas ha explicado muy bien cómo usar itextSharp para convertir HTML para PDF, muy útil

mi complemento es:
Mediante el uso HtmlTextWriter Puse etiquetas html dentro HTML tabla + CSS en línea obtuve mi PDF como quería sin usar XMLWorker .

Editar: agregando código de muestra:

Página ASPX:


 
 
blablabla.
blablabla.
blablabla
blablabla
blablabla Pending orders report
no records found

Código C #:

protected void PendingOrdersPDF_Click(object sender, EventArgs e)

    if (PendingOrdersGV.Rows.Count > 0)
    
        //to allow paging=false & change style.
        PendingOrdersGV.HeaderStyle.ForeColor = System.Drawing.Color.Black;
        PendingOrdersGV.BorderColor = Color.Gray;
        PendingOrdersGV.Font.Name = "Tahoma";
        PendingOrdersGV.DataSource = clsBP.get_PendingOrders(lbl_BP_Id.Text);
        PendingOrdersGV.AllowPaging = false;
        PendingOrdersGV.Columns[0].Visible = false; //export won't work if there's a link in the gridview
        PendingOrdersGV.DataBind();

        //to PDF code --Sam
        string attachment = "attachment; filename=report.pdf";
        Response.ClearContent();
        Response.AddHeader("content-disposition", attachment);
        Response.ContentType = "application/pdf";
        StringWriter stw = new StringWriter();
        HtmlTextWriter htextw = new HtmlTextWriter(stw);
        htextw.AddStyleAttribute("font-size", "8pt");
        htextw.AddStyleAttribute("color", "Grey");

        PendingOrdersPanel.RenderControl(htextw); //Name of the Panel
        Document document = new Document();
        document = new Document(PageSize.A4, 5, 5, 15, 5);
        FontFactory.GetFont("Tahoma", 50, iTextSharp.text.BaseColor.BLUE);
        PdfWriter.GetInstance(document, Response.OutputStream);
        document.Open();

        StringReader str = new StringReader(stw.ToString());
        HTMLWorker htmlworker = new HTMLWorker(document);
        htmlworker.Parse(str);

        document.Close();
        Response.Write(document);
    

por supuesto, incluya iTextSharp Refrences al archivo cs

using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;
using iTextSharp.tool.xml;

¡Espero que esto ayude!

Gracias

valoraciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

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