c# - iTextSharp XMLWorkerHelper 和用于 HTML 到 PDF 的图像

标签 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 做一些技巧.

所以,我制作了自己的 IElementHandler,就像 Chris 展示的那样(除了我做的事情很长,请多多包涵):

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 中得到的结果完全相同。

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

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

因此,您可以看到我尝试过的内容。如果您能提供任何其他帮助,我将不胜感激。

最佳答案

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

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

关于c# - iTextSharp XMLWorkerHelper 和用于 HTML 到 PDF 的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29281040/

相关文章:

javascript - JQuery ScrollTop() 适用于窗口事件,但不适用于 div(在 chrome 中测试)

javascript - 显示一个 sessionStorage 项

php - 如何使用 PHP 下载生成的 pdf 文件?

c# - 无法更改实例化游戏对象的 transform.position

c# - 如何将 Count(*) 与 DAL2 一起使用?

C# MySQL 用循环添加多个相同的参数

jquery - 在嵌入标签中使用响应式显示 pdf

c# - 如何在不使用 "Contains"的情况下从列表框中删除项目?

javascript - 如何检查是否所有选择框都使用 jquery 选择了选项?

pdf - 维基百科如何生成PDF