iTextSharp Html到Pdf图像src

时间:2012-11-27 21:49:33

标签: c# itextsharp

使用iTextSharp将html转换为pdf

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

html以这种方式包含几个嵌入式图像。此方法是首选,因为使用LinkedResources中的AlternateView通过电子邮件发送相同的HTML。

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

但是,当生成pdf时,无法将图像ID与src html标记的img部分相关联。 最终,pdf包含顶部的所有图像,然后忽略<img src...的HTML。

我已经使用Paragraphs或ImageAbsolutePosition阅读了几种可能的解决方案,但它们似乎不适合。

5 个答案:

答案 0 :(得分:2)

尝试这种方式:

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

答案 1 :(得分:2)

看看this site,看起来这样可行。

修改

以下是Referenced Site

中的代码和文字

使用iTextSharp及其HTMLWorker类将一个HTML页面呈现为PDF的人知道我在说什么:如果HTML包含具有相对路径的图像,您可能会得到“友好”的黄色屏幕!

enter image description here

这意味着iTextShap尝试使用相对路径“images / screenshot.3.jpg”获取一个图像作为本地文件“C:\ images \ screenshot.3.jpg”,因此,该图像不存在。 在做了大量关于如何向iTextSharp提供正确图像的研究后,我发现一个人提到了“IImageProvider”界面,它给iTextSharp提供了使用自定义方法查找图像的能力。好吧,我使用iTextSharp 5.0.2.0做了一个例子。你可以在这里下载。

首先,您必须创建一个实现IImageProvider接口的类:

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
}

之后,您必须在呈现HTML内容之前将此图像提供程序指定为HTMLWorker类的“img_provider”接口属性:

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

现在,当您渲染HTML时,它应该适用于相对图像。

虽然这是ASP.Net的一个例子,但主要的想法是如何在呈现HTML时为iTextSharp创建一个自定义图像提供程序,它可以在任何应用程序上使用,这也可以帮助您获取图像从相对位置,我已经使用它(显然有更多代码)从SharePoint或需要身份验证的站点获取图像。

答案 2 :(得分:1)

我之前发现,当您在Itextsharp html pdf生成中使用相对路径时会出现问题,因为您提到可以使用ImageAbsolutePosition,这需要您使用段落来正确定位图像,或者如果您仍想使用html 你必须给出类似

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

答案 3 :(得分:1)

或者您可以使用Server.MapPath将虚拟路径转换为物理路径,如下所示:

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

答案 4 :(得分:-1)

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