2012-11-27 6 views
5

Wandle html pdf iTextSharp mitiTextSharp HTML in PDF Bild src

public static MemoryStream CreatePdfFromHtml(
     string html, List<Attachment> attachments) 
    { 
     MemoryStream msOutput = new MemoryStream(); 

     using (TextReader reader = new StringReader(html)) 
     using (Document document = new Document()) 
     { 
      PdfWriter writer = PdfWriter.GetInstance(document, msOutput); 
      document.Open(); 

      foreach (var a in attachments) 
      { 
       var image = iTextSharp.text.Image.GetInstance(a.File); 
       document.Add(image); 
      } 

      XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader); 

      writer.CloseStream = false; 
      document.Close(); 
      msOutput.Position = 0; 
      return msOutput; 
     } 
    } 

Die html auf diese Weise mehrere eingebettete Bilder enthält. Diese Methode wurde bevorzugt, da der gleiche HTML-Code per E-Mail unter Verwendung von LinkedResources in einer AlternateView gesendet wird.

foreach (var a in attachments) 
{ 
    //not production code 
    html += string.Format("<img src=\"cid:{0}\"></img>", a.Id.ToString()); 
} 

Wenn jedoch die pdf generiert wird, gibt es keine Möglichkeit, die Bild-ID mit dem src Teil des img HTML-Tages zu verknüpfen. Letztendlich enthält das pdf alle Bilder oben und dann wird das HTML mit <img src... ignoriert.

ich mehrere mögliche Lösungen gelesen haben entweder Absätze oder die ImageAbsolutePosition aber sie scheinen nicht zu passen.

Antwort

1

fand ich vor, dass es ein Problem ist, wenn Sie relative Pfad in iTextSharp html pdf Generation verwenden als Sie erwähnten Sie die ImageAbsolutePosition verwenden können, die Sie Absatz verwenden würde erfordern, das Bild richtig oder wenn Sie noch html wollen positionieren verwenden Sie direkten Weg so etwas wie

html += string.Format("<img src=https://www.mysite.com/"+a.Id.ToString()+".imageext"></img>"); 
1

oder Sie können virtuelle Pfad geben würde, konvertieren zum physischen Pfad mit Server.MapPath wie folgt:

imgPhoto.ImageUrl = Server.MapPath(imgPhoto.ImageUrl); 
1

Versuchen Sie, diese Art und Weise:

  PdfWriter writer = PdfWriter.GetInstance(document, msOutput); 
      document.Open(); 
      HTMLWorker worker = new HTMLWorker(document); 

      Dictionary<string, object> providers = new Dictionary<string, object>(); 
      //Get url of the application 
      string url = "http://www.url.com/" //url from which images are loaded 
      //Bind image providers for the application 
      providers.Add(HTMLWorker.IMG_BASEURL, url); 
      //Bind the providers to the worker 
      worker.SetProviders(providers); 

      document.Open(); 
      worker.StartDocument(); 

      // Parse the html into the document 

      worker.Parse(reader); 
      worker.EndDocument(); 
      worker.Close(); 
      document.Close(); 
2

Blick auf this site, sieht wie folgt aus arbeiten können.

EDIT:

Hier ist der Code und Text aus der referenzierten Website

Die Menschen, die für das Rendern einer HTML-Seite in PDF mit iTextSharp und seine HTMLWorker Klasse gearbeitet haben weiß, was ich bin Im Gespräch: Wenn der HTML-Code Bilder mit relativem Pfad enthält, erhalten Sie wahrscheinlich den "freundlichen" gelben Bildschirm!

enter image description here

Es bedeutet, dass iTextShap ein Bild mit dem relativen Pfad "images/screenshot.3.jpg", wie die lokalen Datei zu erhalten versucht, "C: \ images \ screenshot.3.jpg", so, Dieses Bild existiert nicht. Nachdem ich viele Nachforschungen darüber angestellt habe, wie ich das richtige Bild an iTextSharp liefern kann, habe ich festgestellt, dass ein Typ die "IImageProvider" -Schnittstelle erwähnt, die iTextSharp die Fähigkeit gibt, das Bild mit benutzerdefinierten Methoden zu finden. Nun, ich habe ein Beispiel mit iTextSharp 5.0.2.0 gemacht. Sie können es hier herunterladen.

Zuerst überhaupt Sie eine Klasse erstellen, die die IImageProvider Interface implementiert:

public class CustomItextImageProvider : IImageProvider 
{ 
    #region IImageProvider Members 
    public iTextSharp.text.Image GetImage(string src, Dictionary<string,string> imageProperties, ChainedProperties cprops, IDocListener doc) 
    { 
     string imageLocation = imageProperties["src"].ToString(); 
     string siteUrl = HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.AbsolutePath, ""); 

     if (siteUrl.EndsWith("/")) 
      siteUrl = siteUrl.Substring(0, siteUrl.LastIndexOf("/")); 

     iTextSharp.text.Image image = null; 

     if (!imageLocation.StartsWith("http:") && !imageLocation.StartsWith("file:") && !imageLocation.StartsWith("https:") && !imageLocation.StartsWith("ftp:")) 
      imageLocation = siteUrl + (imageLocation.StartsWith("/") ? "" : "/") + imageLocation; 

     return iTextSharp.text.Image.GetInstance(imageLocation); 
    } 
    #endregion 
} 

Nachdem es, müssen Sie dieses Bild Provider als „img_provider“ Schnittstelle Eigenschaft der HTMLWorker Klasse zuweisen, bevor das Rendering HTML Inhalt:

HTMLWorker worker = new HTMLWorker(document); 
Dictionary<string, object> interfaceProps = new Dictionary<string, object>() { 
    {"img_provider", new CustomItextImageProvider()} 
}; 
worker.InterfaceProps = interfaceProps; 

Jetzt, wenn Sie Ihr HTML rendern, sollte es mit relativen Bildern arbeiten.

Obwohl dies ein Beispiel für ASP.Net gemacht wird, ist die Hauptidee, wie man einen benutzerdefinierten Image Provider für iTextSharp beim Rendern von HTML erstellt und es könnte für jede Anwendung verwendet werden, auch dies könnte Ihnen nicht nur helfen Bilder von einem relativen Ort, ich habe es (mit mehr Code, offensichtlich) verwendet, um Bilder von SharePoint oder Sites zu erhalten, die eine Authentifizierung erfordern.

+0

@kleopatra Ich habe den Code und den Text von der referenzierten Website hinzugefügt. – Pierre

-1
var logo = iTextSharp.text.Image.GetInstance(Server.MapPath("../Images/mevantage-logo.jpg")); 
+0

Das OP zeigte eindeutig an, dass die Bilder Teil eines HTML sind, das schließlich durch den XmlWorker läuft. Daher stimmt Ihre Codezeile nicht überein. – mkl

Verwandte Themen