2012-03-08 194 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