6

使用 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以这种方式包含几个嵌入的图像。首选此方法,因为相同的 HTML 是LinkedResources使用AlternateView.

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

但是,当生成 pdf 时,无法将图像 id 与html 标签的src一部分链接起来。img最终,pdf 包含顶部的所有图像,然后是<img src...被忽略的 HTML。

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

4

5 回答 5

3

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!

enter image description here

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.

于 2014-02-01T07:00:55.210 回答
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();
于 2013-02-05T12:22:38.157 回答
1

我之前发现,当您在 Itextsharp html pdf 生成中使用相对路径时存在问题,正如您提到的,您可以使用 ImageAbsolutePosition 这将要求您使用段落来正确定位您的图像,或者如果您仍想使用 html,您将不得不给直接路径类似

 html += string.Format("<img src=https://www.mysite.com/"+a.Id.ToString()+".imageext"></img>");
于 2012-11-27T22:08:13.230 回答
1

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

imgPhoto.ImageUrl = Server.MapPath(imgPhoto.ImageUrl);
于 2013-02-05T12:11:43.313 回答
-1
var logo = iTextSharp.text.Image.GetInstance(Server.MapPath("../Images/mevantage-logo.jpg"));
于 2016-09-09T05:03:03.907 回答