2012-11-27 26 views
5

Convertire un HTML a PDF utilizzando iTextSharpiTextSharp HTML a PDF immagine 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; 
     } 
    } 

il codice HTML contiene diverse immagini incorporate in questo modo. Questo metodo è stato preferito in quanto lo stesso codice HTML viene inviato tramite e-mail utilizzando LinkedResources in un AlternateView.

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

Tuttavia, quando il pdf viene generato, non c'è modo di collegare l'id immagine con la src parte del tag html img. In definitiva, il pdf contiene tutte le immagini in alto e quindi l'HTML con lo <img src... ignorato.

Ho letto diverse soluzioni possibili utilizzando sia i paragrafi o ImageAbsolutePosition ma non sembrano adattarsi.

risposta

1

ho trovato prima che ci sia un problema quando si utilizza percorso relativo a iTextSharp generazione html pdf come lei ha citato è possibile utilizzare l'ImageAbsolutePosition che richiederebbe l'uso paragrafo per posizionare la vostra immagine in modo corretto o se si vuole ancora utilizzare html che avrebbe dovuto dare via qualcosa di diretto come

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

o è possibile convertire percorso virtuale al percorso fisico con Server.MapPath come questo:

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

provare in questo modo:

  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

Guardate this site, sembra che questo può funzionare.

EDIT:

Ecco il codice e il testo dai riferimenti a sito

Le persone che hanno lavorato con iTextSharp e la sua classe HTMLWorker per il rendering di una pagina HTML a PDF sa di cosa sto a proposito di: se l'HTML contiene immagini con percorso relativo probabilmente otterrai lo schermo giallo "amichevole"!

enter image description here

Significa che iTextShap cercato di ottenere un'immagine con il percorso relativo "images/screenshot.3.jpg" come il file locale "C: \ Immagini \ screenshot.3.jpg", così, quell'immagine non esiste. Dopo aver fatto molte ricerche su come fornire a iTextSharp l'immagine corretta, ho scoperto che un tizio ha menzionato l'interfaccia "IImageProvider" che dà a iTextSharp la possibilità di trovare l'immagine usando metodi personalizzati. Bene, ho fatto un esempio usando iTextSharp 5.0.2.0. Potete scaricarlo qui.

Prima a tutto quello che dovete creare una classe che implementa l'IImageProvider interfaccia:

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 
} 

Dopo di esso, è necessario assegnare questo fornitore di immagine come la proprietà di interfaccia "img_provider" della classe HTMLWorker prima del rendering della contenuto HTML:

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

Ora, quando si esegue il rendering il codice HTML dovrebbe funzionare con le immagini relative.

Anche se questo è un esempio fatto per ASP.Net, l'idea principale è come creare un fornitore di immagini personalizzato per iTextSharp quando si esegue il rendering di HTML e potrebbe essere utilizzato su qualsiasi applicazione, inoltre, questo potrebbe aiutare non solo ad ottenere immagini da una posizione relativa, l'ho usato (con più codice, ovviamente) per ottenere immagini da SharePoint o siti che richiedono l'autenticazione.

+0

@kleopatra Ho aggiunto il codice e il testo dal sito web di riferimento. – Pierre

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

L'OP indica chiaramente che le immagini fanno parte di un codice HTML che alla fine viene eseguito tramite XmlWorker. Pertanto, la tua riga di codice non corrisponde. – mkl

Problemi correlati