ITextSharp Análisis HTML con imágenes en él: analiza correctamente pero no muestra imágenes

Estoy tratando de generar un .pdf desde html usando la biblioteca ITextSharp. Soy capaz de crear el pdf con el texto html convertido a pdf texto / párrafos

Mi problema: el pdf no muestra mis imágenes (mis elementos img del html). ¿Todos mis elementos img html en mi html no se muestran en el pdf? ¿Es posible que ITextSharp analice HTML y muestre imágenes? Realmente espero que de lo contrario estoy lleno 🙁

Estoy enlazando con el directorio correcto donde están las imágenes (usando IMG_BASURL) pero simplemente no se muestran

Mi código:

// mainContents variable is a string containing my HTML var document = new Document(PageSize.A4, 50, 50, 80, 100); var output = new MemoryStream(); var writer = PdfWriter.GetInstance(document, output); document.open(); Hashtable providers = new Hashtable(); providers.Add("img_baseurl","C:/users/xx/VisualStudio/Projects/myproject/"); var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(mainContents), null, providers); foreach (var htmlElement in parsedHtmlElements) document.Add(htmlElement as IElement); document.Close(); 

Cada vez que encontré esto, el problema era que la imagen era demasiado grande para el canvas. Más específicamente, incluso una etiqueta IMG desnuda se envolverá internamente en un Chunk que se envolverá en un Paragraph , y creo que la imagen está desbordando el párrafo, pero no estoy 100% seguro.

Las dos soluciones fáciles son ampliar el canvas o especificar las dimensiones de la imagen en la etiqueta IMG HTML. La tercera ruta más compleja sería utilizar un proveedor adicional IMG_PROVIDER . Para hacer esto necesitas implementar la interfaz IImageProvider . A continuación se muestra una versión muy simple de uno.

  public class ImageThing : IImageProvider { //Store a reference to the main document so that we can access the page size and margins private Document MainDoc; //Constructor public ImageThing(Document doc) { this.MainDoc = doc; } Image IImageProvider.GetImage(string src, IDictionary attrs, ChainedProperties chain, IDocListener doc) { //Prepend the src tag with our path. NOTE, when using HTMLWorker.IMG_PROVIDER, HTMLWorker.IMG_BASEURL gets ignored unless you choose to implement it on your own src = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\" + src; //Get the image. NOTE, this will attempt to download/copy the image, you'd really want to sanity check here Image img = Image.GetInstance(src); //Make sure we got something if (img == null) return null; //Determine the usable area of the canvas. NOTE, this doesn't take into account the current "cursor" position so this might create a new blank page just for the image float usableW = this.MainDoc.PageSize.Width - (this.MainDoc.LeftMargin + this.MainDoc.RightMargin); float usableH = this.MainDoc.PageSize.Height - (this.MainDoc.TopMargin + this.MainDoc.BottomMargin); //If the downloaded image is bigger than either width and/or height then shrink it if (img.Width > usableW || img.Height > usableH) { img.ScaleToFit(usableW, usableH); } //return our image return img; } } 

Para usar este proveedor, simplemente agréguelo a la colección de proveedores como lo hizo con HTMLWorker.IMG_BASEURL :

 providers.Add(HTMLWorker.IMG_PROVIDER, new ImageThing(doc)); 

Se debe tener en cuenta que si utiliza HTMLWorker.IMG_PROVIDER usted es responsable de averiguar todo acerca de la imagen. El código anterior asume que todas las rutas de imagen deben ir precedidas por una cadena constante, probablemente querrá actualizar esto y verificar si hay HTTP al comienzo. Además, porque estamos diciendo que queremos manejar completamente el proceso de procesamiento de imágenes, el proveedor HTMLWorker.IMG_BASEURL ya no es necesario.

El bucle de código principal ahora se vería así:

  string html = @""; string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "HtmlTest.pdf"); using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) { using (Document doc = new Document(PageSize.A4, 50, 50, 80, 100)) { using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) { doc.Open(); using (StringReader sr = new StringReader(html)) { System.Collections.Generic.Dictionary providers = new System.Collections.Generic.Dictionary(); providers.Add(HTMLWorker.IMG_PROVIDER, new ImageThing(doc)); var parsedHtmlElements = HTMLWorker.ParseToList(sr, null, providers); foreach (var htmlElement in parsedHtmlElements) { doc.Add(htmlElement as IElement); } } doc.Close(); } } } 

Una última cosa, asegúrese de especificar qué versión de iTextSharp está apuntando al publicar aquí. El código anterior apunta a iTextSharp 5.1.2.0 pero creo que podría estar usando la serie 4.X.

Enfrenté el mismo problema e intenté las siguientes soluciones propuestas: la cadena reemplazó una etiqueta, codificó en base64 e incrustó la imagen en una biblioteca de clases .NET, ¡pero ninguna funcionó! Así que he llegado a la solución antigua: agregar el logotipo manualmente con doc.Add()
Aquí está su código actualizado:

 string html = @""; string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "HtmlTest.pdf"); using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) { using (Document doc = new Document(PageSize.A4, 50, 50, 80, 100)) { using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) { doc.Open(); using (StringReader sr = new StringReader(html)) { System.Collections.Generic.Dictionary providers = new System.Collections.Generic.Dictionary(); providers.Add(HTMLWorker.IMG_PROVIDER, new ImageThing(doc)); var parsedHtmlElements = HTMLWorker.ParseToList(sr, null, providers); foreach (var htmlElement in parsedHtmlElements) { doc.Add(htmlElement as IElement); } // here's the magic var logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/HTMLTemplate/logo.png")); logo.SetAbsolutePosition(440, 800); document.Add(logo); // end } doc.Close(); } } } 
 string siteUrl = HttpContext.Current.Server.MapPath("/images/image/ticket/Ticket.jpg"); string HTML = "
asdasdsadasdsa
";