iTextSharp XMLWorkerHelper和HTML到PDF的图像

时间:2015-03-26 14:27:30

标签: c# html pdf itextsharp

底线是我使用iTextSharp将HTML写入PDF - 带图像。现在,我在最新版本的iTextSharp 5.5.5.0。我可以访问Bruno's本书,并且我使用demo.iTextSupport.com拼写的方法进行转换。很遗憾,the book似乎没有任何对 XMLWorkerHelper 的引用,这是我用来从HTML创建PDF的方法。

这是我最终通过格式良好的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中,而是可以做一些"添加"某种。

而且......在这里,我迷路了。

我认为我仍然需要使用XMLWorkerHelper,但我需要对IElementHandler做一些事情,而不是将整个事情推到pdfWriter中。

Additional research表明我可以通过Chris Haas wonderful post here对IElements做一些技巧。

所以,我像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,也许我可以用它做点什么,但我真的不是这里的专家而且我觉得我是&#39在没有爱丽丝指导我的情况下走下兔子洞。

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

所以,你可以看到我尝试过的东西。我很感激你能提供的任何其他帮助。

1 个答案:

答案 0 :(得分:1)

本书中没有提到XML Worker,因为这本书是在2009年编写的,而且XML Worker的开发是在2011年的某个地方开始的。你的问题很长,但却缺少一个重要元素:像HTML样本一样为sandbox examples提供了一个(你没有提到)。例如:当使用thoreau.html解析ParseHtmlImagesLinksOops示例时,我们会丢失所有图片:thoreau_oops.pdf;当我们使用ParseHtmlImagesLinks时,我们使用ImageProvider来确保我们获得图像的正确路径,结果看起来很不错:thoreau.pdf(顺便说一下链接也是如此)

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