iTextSharp XMLWorkerHelper 和图像 HTML 到 PDF

iTextSharp XMLWorkerHelper and Images for HTML to PDF

底线是我正在使用 iTextSharp 将 HTML 写成 PDF -- 带有图像。现在,我使用的是最新版本的 iTextSharp,即 5.5.5.0。我可以访问 Bruno's book, and I'm using the methodology spelled out by demo.iTextSupport.com for the conversion. Unfortunately, the book 似乎没有对 XMLWorkerHelper 的任何引用,这是我用来从 HTML 创建 PDF 的内容。 =18=]

这是我终于开始使用的方法,它成功地从格式正确的 HTML 字符串生成 PDF:

private string createPDFFromHtml(string htmlString, string outputFileName)
{
    string result = string.Empty;

    try
    {
        if (!string.IsNullOrEmpty(htmlString) && !string.IsNullOrEmpty(outputFileName) && !File.Exists(outputFileName))
        {
            using (FileStream fos = new FileStream(outputFileName, FileMode.Create))
            {
                using (MemoryStream inputMemoryStream = new MemoryStream(Encoding.ASCII.GetBytes(htmlString)))
                {
                    using (TextReader textReader = new StreamReader(inputMemoryStream, Encoding.ASCII))
                    {
                        using (Document pdfDoc = new Document())
                        {
                            using (PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDoc, fos))
                            {
                                XMLWorkerHelper helper = XMLWorkerHelper.GetInstance();
                                pdfDoc.Open();
                                helper.ParseXHtml(pdfWriter, pdfDoc, textReader);
                                result = "Successfully Created new HTML--> PDF Document!";
                                pdfWriter.CloseStream = false;
                            }
                        }
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        result = "Exception: " + ex.Message;
    }

    return result;
}

这行得通,我想做的是用图像作为信头创建一封信,图像只是我放在硬盘驱动器某处的一些 JPG。

这是我尝试过的方法,但虽然它成功地将图像准确地放置在我想要的位置和我想要的方式,但 PDF 的其余部分输出被严重截断。

 private string createPDFFromHtmlWithImage(string htmlString, string outputFileName, string headerImagePath)
        {
            string result = string.Empty;

            try
            {
                if (!string.IsNullOrEmpty(htmlString) && !string.IsNullOrEmpty(outputFileName) && !File.Exists(outputFileName))
                {
                    using (FileStream fos = new FileStream(outputFileName, FileMode.Create))
                    {
                        using (MemoryStream inputMemoryStream = new MemoryStream(Encoding.ASCII.GetBytes(htmlString)))
                        {
                            using (TextReader textReader = new StreamReader(inputMemoryStream, Encoding.ASCII))
                            {
                                using (Document pdfDoc = new Document())
                                {
                                    using (PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDoc, fos))
                                    {
                                        pdfDoc.Open();
                                        Image img = Image.GetInstance(headerImagePath);
                                        if (img != null)
                                        {
                                            img.ScaleToFit(540f, 300f);
                                            pdfDoc.Add(img);
                                        }

                                        XMLWorkerHelper helper = XMLWorkerHelper.GetInstance();
                                        helper.ParseXHtml(pdfWriter, pdfDoc, textReader);

                                        result = "Successfully Created new HTML--> PDF Document!";
                                        pdfWriter.CloseStream = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result = "Exception: " + ex.Message;
            }

            return result;
        }

结果是 PDF 有我想要的图像,然后基本上是我的第一个 HTML(但即使是 DIV 也没有完全显示),然后没有别的。

所以,我认为我可能不仅需要将 textReader 转换为 pdfDoc,还可能需要做一些 "adds" 之类的事情。

而且...这就是我迷路的地方。

我想我仍然需要使用 XMLWorkerHelper,但我需要用 IElementHandler 做一些事情,而不是仅仅将整个东西推到 pdfWriter 中。

Additional research shows that I can possibly do some tricks with IElements via Chris Haas wonderful post here

所以,我像 Chris 展示的那样制作了自己的 IElementHandler(除了我做的事情很长,请耐心等待):

public class HtmlElementHandler : IElementHandler
{
    public List<IElement> elementList = new List<IElement>();

    public void Add(IWritable e)
    {
        if (e != null && e is WritableElement)
        {
            WritableElement we = e as WritableElement;

            if (we != null)
            {
                IList<IElement> weList = we.Elements();
                if (weList.Any())
                {
                    elementList.AddRange(weList);
                }
            }
        }
    }
}

现在使用此代码:

 private string createPDFFromHtmlWithImageElemental(string htmlString, string outputFileName, string headerImagePath)
        {
            string result = string.Empty;

            try
            {
                if (!string.IsNullOrEmpty(htmlString) && !string.IsNullOrEmpty(outputFileName) && !File.Exists(outputFileName))
                {
                    using (FileStream fos = new FileStream(outputFileName, FileMode.Create))
                    {
                        using (MemoryStream inputMemoryStream = new MemoryStream(Encoding.ASCII.GetBytes(htmlString)))
                        {
                            using (TextReader textReader = new StreamReader(inputMemoryStream, Encoding.ASCII))
                            {
                                using (Document pdfDoc = new Document())
                                {
                                    using (PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDoc, fos))
                                    {
                                        pdfDoc.Open();
                                        Image img = Image.GetInstance(headerImagePath);
                                        if (img != null)
                                        {
                                            img.ScaleToFit(540f, 300f);
                                            pdfDoc.Add(img);
                                        }

                                        HtmlElementHandler htmlElementHandler = new HtmlElementHandler();

                                        XMLWorkerHelper helper = XMLWorkerHelper.GetInstance();
                                        helper.ParseXHtml(htmlElementHandler, inputMemoryStream, Encoding.ASCII);

                                        foreach (IElement ielement in htmlElementHandler.elementList)
                                        {
                                            pdfDoc.Add(ielement);
                                        }

                                        result = "Successfully Created new HTML--> PDF Document!";
                                        pdfWriter.CloseStream = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result = "Exception: " + ex.Message;
            }

            return result;
        }

我得到的结果与以前一样将整个内容放入 pdfDoc 中得到的结果完全相同。

我可以看到我的元素实际上是一个 iTextShartp.text.pdf.PdfDiv 内容,也许我可以用它做点什么,但我真的不是这里的专家,我觉得我要下去了没有爱丽丝引导我的兔子洞

额外的搜索表明有一种方法可以 get an image embedded,但我并不热衷于为我的图像生成二进制文本图像字符串并将其加载到 HTML就像这个解决方案一样。我希望能够根据需要选择和更改图像。我想我可以创建一种方法来拍摄图像、创建此二进制文本并将其插入我的 HTML,但我宁愿先看看是否有其他解决方案。

所以,你可以看到我尝试了什么。如果您能提供任何其他帮助,我将不胜感激。

XML Worker 没有在书中提到,因为这本书是2009年写的, XML Worker 的开发是在2011年的某个地方开始的。你的问题很长,但是缺少一个重要元素:一个 HTML 样本,就像为 sandbox examples (which you don't mention). For instance: when the parse the thoreau.html example using ParseHtmlImagesLinksOops, we lose all images: thoreau_oops.pdf; when we use ParseHtmlImagesLinks, we use an ImageProvider that makes sure we get the correct paths to the images and the result looks quite OK: thoreau.pdf 提供的样本一样(顺便说一句,链接也是如此)。

但是,当我查看实际需求时,我发现您想要创建一个带有信头图像的信件。在这种情况下,我会使用页面事件将公司文具添加到每个页面。书中解释了如何做到这一点。