ITextSharp解析包含图像的HTML:它可以正确解析,但不会显示图像

本文关键字:图像 显示 显示图 包含 HTML ITextSharp | 更新日期: 2023-09-27 18:27:02

我正在尝试使用库ITextSharp从html生成.pdf。我能够创建将 html 文本转换为 pdf 文本/段落的 pdf

我的问题:pdf 不显示我的图像(我的 img 元素来自 html(。我的 html 中的所有 img html 元素都没有显示在 pdf 中?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();

ITextSharp解析包含图像的HTML:它可以正确解析,但不会显示图像

每次我遇到这种情况时,问题都是图像对于画布来说太大了。更具体地说,即使是内部裸露的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系列。

我遇到了同样的问题,并尝试了以下建议的解决方案:字符串替换了一个标签,在 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();
                }
            }
        }
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>";