2012-03-08 190 views
10

我想從使用庫ITextSharp的HTML生成.pdf。我能夠創建PDF與HTML文本轉換爲PDF文本/段落ITextSharp解析HTML中的圖像:它解析正確,但不會顯示圖像

我的問題: PDF格式不顯示我的圖片(我IMG從HTML元素)。我所有的HTML代碼在我的html中都不會顯示在pdf中,我的所有img? ITextSharp可以解析HTML &顯示圖像。我真的希望如此,否則我塞進:(

我鏈接到其中的圖像(使用IMG_BASURL)正確的目錄,但他們只是沒有顯示

我的代碼:

// 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(); 

回答

11

每我遇到過這個問題的時候,圖片對於畫布來說太大了,更具體地說,即使是一個全裸的IMG標籤也會被包裝在一個Chunk中,並且會被包裝在Paragraph中,我認爲圖片是溢出段落,但我不是100%肯定。

這兩個簡單的修復方法是放大畫布或指定HTML IMG標記上的圖像尺寸。第三種更復雜的路線是使用額外的供應商IMG_PROVIDER。要做到這一點,你需要實現IImageProvider接口。下面是一個

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<string, string> 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; 
     } 
    } 

一個非常簡單的版本要使用此供應商只需將其添加到供應商收集像你HTMLWorker.IMG_BASEURL做:

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

應當注意的是,如果你使用HTMLWorker.IMG_PROVIDER你負責搞清楚形象的一切。上面的代碼假定所有圖像路徑都需要用一個常量字符串前綴,您可能需要更新它並在開始時檢查HTTP。另外,因爲我們說我們想完全處理圖像處理流水線,所以不再需要供應商HTMLWorker.IMG_BASEURL

的主要代碼迴路現在看起來是這樣的:

 string html = @"<img src=""Untitled-1.png"" />"; 
     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<string, object> providers = new System.Collections.Generic.Dictionary<string, object>(); 
         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(); 
       } 
      } 
     } 

最後一兩件事,一定要指定張貼在這裏,當你靶向其中iTextSharp的版本。上面的代碼針對iTextSharp 5.1.2.0,但我認爲你可能會使用4.X系列。

+0

我試圖創建和使用基於這種代碼實現IImageProvider一類,但它不工作,我相信它與這條線有關: providers.Add(HTMLWorker。IMG_PROVIDER,新ImageThing(doc)); 我在C#中編碼,當我添加到我的散列表時,我無法使用HTMLWorker.IMG_PROVIDER枚舉。如果這個值只是一個字符串,這有什麼關係嗎?也許我需要從循環內部做更多的事情來實際執行ImageProvider類中的GetImage代碼。我使用的是itextsharp 4.1.6,以防萬一。 – Neitherman 2014-02-06 14:36:33

+0

@Neitherman,請發表一個新的問題與你的嘗試和什麼不工作,引用這篇文章,如果它是有道理的。 – 2014-02-07 14:35:31

+0

發佈新問題: http://stackoverflow.com/questions/21684040/imageprovider-not-working-in-html-to-pdf-conversion – Neitherman 2014-02-10 17:32:30

-1
string siteUrl = HttpContext.Current.Server.MapPath("/images/image/ticket/Ticket.jpg"); 
string HTML = "<table><tr><td><u>asdasdsadasdsa <img src='" + siteUrl + "' al='tt' /> </u></td></tr></table>"; 
+0

如果知道該如何或爲什麼會起作用,那將是非常好的,如果它確實如此......我相信這不適用於當前版本的iTextSharp,因爲

標記不受支持。 – azarc32014-08-22 13:26:41

+0

剛剛得到這個工作,儘管@ GuruRaja的初始評論在當前版本的iTextSharp中不起作用。但是,如果您刪除容器標籤並使用URL作爲圖像源(不是物理服務器路徑),將刪除

,和​​容器標籤。 – azarc32014-08-22 15:55:35

2

我面臨同樣的問題,嘗試了以下建議解決方案: 字符串替代標籤,編碼以base64和圖像嵌入到.NET類庫但沒有工作! 所以我來老式的解決方案:doc.Add()
手動添加徽標這裏是你的代碼更新:

string html = @"<img src=""Untitled-1.png"" />"; 
     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<string, object> providers = new System.Collections.Generic.Dictionary<string, object>(); 
         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(); 
       } 
      } 
     } 
+0

爲了節省時間,你不需要server.map路徑。如果您未使用Web應用程序,則可以使用文件路徑。 – 2017-04-27 15:28:18