iTextSharp Html to Pdf image src

倖福魔咒の 提交于 2019-12-04 13:18:44

问题


Convert a html to pdf using iTextSharp

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

The html contains several embedded images this way. This method was preferred as the same HTML is sent via email using LinkedResources in an AlternateView.

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

However, when the pdf gets generated, there is no way to link the image id with the src part of the img html tag. Ultimately, the pdf contains all the images up top and then the HTML with the <img src... ignored.

I've read several possible solutions using either Paragraphs or the ImageAbsolutePosition but they don't seem to fit in.


回答1:


Try this way:

           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:


Look at this site, looks like this can work.

EDIT:

Here is the code and text from the Referenced Site

The people which have been working with iTextSharp and its HTMLWorker class for rendering one HTML page to PDF knows what I'm talking about: if the HTML contains images with relative path you'll probably get the "friendly" yellow screen!

It means that iTextShap tried to get one image with the relative path "images/screenshot.3.jpg" as the local file "C:\images\screenshot.3.jpg", so, that image doesn't exist. After doing a lot of research about how to provide to iTextSharp the correct image I found that one guy mentioned the "IImageProvider" interface that gives to iTextSharp the ability of find the image using custom methods. Well, I have done one example using iTextSharp 5.0.2.0. you can download it here.

First at all you have to create one class that implements the IImageProvider Interface:

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
}

After it, you have to assign this image provider as the "img_provider" interface property of the HTMLWorker class before rendering the HTML Content:

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

Now, when you render your HTML it should work with relative images.

Althought this is one example made for ASP.Net, the main idea is how to create one custom Image Provider for iTextSharp when rendering HTML and it could be used on any application, also, this could help you not only for getting images from a relative location, I have used it (with more code, obviously) for getting images from SharePoint or Sites that require authentication.




回答3:


or you can convert virtual path to physical path with Server.MapPath like this:

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



回答4:


I found before that there is an issue when you use relative path in Itextsharp html pdf generation as you mentioned you can use the ImageAbsolutePosition which would require you to use paragraph to position your image correctly or if you still want to use html you would have to give direct path something like

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



回答5:


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


来源:https://stackoverflow.com/questions/13593758/itextsharp-html-to-pdf-image-src

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!