ITextSharp HTML到PDF?

Posted

技术标签:

【中文标题】ITextSharp HTML到PDF?【英文标题】:ITextSharp HTML to PDF? 【发布时间】:2011-02-18 20:28:27 【问题描述】:

我想知道 ITextSharp 是否具有将 html 转换为 PDF 的能力。我将转换的所有内容都只是纯文本,但不幸的是,ITextSharp 上几乎没有文档,所以我无法确定这对我来说是否是一个可行的解决方案。

如果做不到,有人可以指点我一些好的、免费的 .net 库,它们可以获取简单的纯文本 HTML 文档并将其转换为 pdf 文件吗?

tia.

【问题讨论】:

【参考方案1】:

几周前我遇到了同样的问题,这是我发现的结果。此方法将 HTML 快速转储为 PDF。该文档很可能需要进行一些格式调整。

private MemoryStream createPDF(string html)

    MemoryStream msOutput = new MemoryStream();
    TextReader reader = new StringReader(html);

    // step 1: creation of a document-object
    Document document = new Document(PageSize.A4, 30, 30, 30, 30);

    // step 2:
    // we create a writer that listens to the document
    // and directs a XML-stream to a file
    PdfWriter writer = PdfWriter.GetInstance(document, msOutput);

    // step 3: we create a worker parse the document
    HTMLWorker worker = new HTMLWorker(document);

    // step 4: we open document and start the worker on the document
    document.Open();
    worker.StartDocument();

    // step 5: parse the html into the document
    worker.Parse(reader);

    // step 6: close the document and the worker
    worker.EndDocument();
    worker.Close();
    document.Close();

    return msOutput;

【讨论】:

为了避免其他人不得不挖掘文档,请注意,从 5.1.1 开始,HTMLWorker 可以在 iTextSharp.text.html.simpleparser 中找到。 为什么人们从不在 c# 代码示例中使用“using”语句? @cbp 我通常在 using 语句声明中调用这样的方法。前任。 using(MemoryStream stream = createPDF(html)) 为了拯救更多的人,HTMLWorker 现在已经过时了。使用 XMLWorkerHelper.ParseXHtml(),但要注意,它只适用于 XHTML。您必须单独下载它,因为它被设计为附加组件。 HTMLWorker 类现已过时,已被 XMLWorker 取代。请参阅***.com/questions/25164257/…,深入了解如何使用它将 HTML 呈现为 PDF,包括 CSS 呈现【参考方案2】:

在进行了一些挖掘之后,我找到了一种使用 ITextSharp 完成我需要的好方法。

以下是一些示例代码,如果将来对其他人有所帮助:

protected void Page_Load(object sender, EventArgs e)

    Document document = new Document();
    try
    
        PdfWriter.GetInstance(document, new FileStream("c:\\my.pdf", FileMode.Create));
        document.Open();
        WebClient wc = new WebClient();
        string htmlText = wc.DownloadString("http://localhost:59500/my.html");
        Response.Write(htmlText);
        List<IElement> htmlarraylist = HTMLWorker.ParseToList(new StringReader(htmlText), null);
        for (int k = 0; k < htmlarraylist.Count; k++)
        
            document.Add((IElement)htmlarraylist[k]);
        

        document.Close();
    
    catch
    
    

【讨论】:

您可能不想像使用 Web 应用程序那样将输出写入固定路径。您将在负载下对单个文件进行资源争用。使用由操作系统生成的 MemoryStream 或临时文件(请务必在完成后删除临时文件)。如何创建临时文件:msdn.microsoft.com/en-us/library/… 对象引用未设置为对象的实例。在 List htmlarraylist = HTMLWorker.ParseToList(new StringReader(htmlText), null); 嗨@Kyle你能帮帮我吗:***.com/questions/20950236/… 嘿,当我提供本地主机链接时,我收到错误“远程服务器返回错误:(401)未经授权。”你遇到过这种情况吗? 您需要对尝试将新文件写入的文件夹启用权限。或者如果文件已经存在,它可能正在被另一个进程使用。【参考方案3】:

这是我在 5.4.2 版(来自 nuget 安装)上能够从 asp.net mvc 控制器返回 pdf 响应的内容。如果需要,可以将其修改为使用 FileStream 而不是 MemoryStream 作为输出。

我在这里发布它是因为它是当前 iTextSharp 用于 html -> pdf 转换的完整示例(忽略图像,我没有看过,因为我的使用不需要它)

它使用 iTextSharp 的 XmlWorkerHelper,因此传入的 hmtl 必须是有效的 XHTML,因此您可能需要根据您的输入进行一些修复。

using iTextSharp.text.pdf;
using iTextSharp.tool.xml;
using System.IO;
using System.Web.Mvc;

namespace Sample.Web.Controllers

    public class PdfConverterController : Controller
    
        [ValidateInput(false)]
        [HttpPost]
        public ActionResult HtmlToPdf(string html)
                   

            html = @"<?xml version=""1.0"" encoding=""UTF-8""?>
                 <!DOCTYPE html 
                     PUBLIC ""-//W3C//DTD XHTML 1.0 Strict//EN""
                    ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"">
                 <html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">
                    <head>
                        <title>Minimal XHTML 1.0 Document with W3C DTD</title>
                    </head>
                  <body>
                    " + html + "</body></html>";

            var bytes = System.Text.Encoding.UTF8.GetBytes(html);

            using (var input = new MemoryStream(bytes))
            
                var output = new MemoryStream(); // this MemoryStream is closed by FileStreamResult

                var document = new iTextSharp.text.Document(iTextSharp.text.PageSize.LETTER, 50, 50, 50, 50);
                var writer = PdfWriter.GetInstance(document, output);
                writer.CloseStream = false;
                document.Open();

                var xmlWorker = XMLWorkerHelper.GetInstance();
                xmlWorker.ParseXHtml(writer, document, input, null);
                document.Close();
                output.Position = 0;

                return new FileStreamResult(output, "application/pdf");
            
        
    

【讨论】:

感谢您,提供比 HtmlRenderer 和 PDFSharp 更清晰的 PDF。我检查了,您的代码支持图像。我这样做是为了测试 html = "google.com/images/srpr/logo11w.png' />"【参考方案4】:

如果我有声望的话,我会单打独斗的 mightymada 的答案——我刚刚使用 Pechkin 实现了一个 asp.net HTML 到 PDF 的解决方案。结果很棒。

Pechkin 有一个 nuget 包,但正如上面的海报在他的博客中提到的(http://codeutil.wordpress.com/2013/09/16/convert-html-to-pdf/ - 我希望她不介意我重新发布它),这个分支中存在一个内存泄漏问题:

https://github.com/tuespetre/Pechkin

上面的博客有关于如何包含这个包的具体说明(它是一个 32 位 dll,需要 .net4)。这是我的代码。传入的 HTML 实际上是通过 HTML Agility 包组装的(我正在自动生成发票):

public static byte[] PechkinPdf(string html)

  //Transform the HTML into PDF
  var pechkin = Factory.Create(new GlobalConfig());
  var pdf = pechkin.Convert(new ObjectConfig()
                          .SetLoadImages(true).SetZoomFactor(1.5)
                          .SetPrintBackground(true)
                          .SetScreenMediaType(true)
                          .SetCreateExternalLinks(true), html);

  //Return the PDF file
  return pdf;

再次感谢您的威力马达 - 您的回答太棒了。

【讨论】:

注意:Pechkin(和 TuesPechkin)在几乎所有方面都优于 iTextSharp(恕我直言),除了它们不能在 Azure 网站中工作(可能是许多共享托管环境?) Pechkin 是 wkhtmltopdf 的包装器,它使用 QT Webkit 将网页渲染为 pdf。这与在 Safari(基于 Webkit 的浏览器)中说“打印到 PDF”基本相同。这与从代码创建 PDF 文件完全不同。这也是 OP 所要求的完全相反。所以我不赞成。【参考方案5】:

我更喜欢使用另一个名为 Pechkin 的库,因为它能够转换非平凡的 HTML(也有 CSS 类)。这是可能的,因为这个库使用了 Chrome 和 Safari 等浏览器也使用的 WebKit 布局引擎。

我在我的博客上详细介绍了我对 Pechkin 的体验:http://codeutil.wordpress.com/2013/09/16/convert-html-to-pdf/

【讨论】:

【参考方案6】:

上面的代码肯定会帮助将 HTML 转换为 PDF,但如果 HTML 代码具有带相对路径的 IMG 标签,则会失败。 iTextSharp 库不会自动将相对路径转换为绝对路径。

我尝试了上面的代码并添加了代码来处理 IMG 标签。

您可以在此处找到代码供您参考: http://www.am22tech.com/html-to-pdf/

【讨论】:

您发现了问题,但是当我尝试通过从 www.google.com 读取 HTML 来生成 PDF 时,您使用 IImageProvider 引用的解决方案会产生以下错误 Could not find a part of the path 'C:\intl\en_ALL\images\srpr\logo1w.png'.【参考方案7】:

它可以将 HTML 文件转换为 pdf。

转换所需的命名空间是:

using iTextSharp.text;
using iTextSharp.text.pdf;

以及用于转换和下载文件:

// Create a byte array that will eventually hold our final PDF
Byte[] bytes;

// Boilerplate iTextSharp setup here

// Create a stream that we can write to, in this case a MemoryStream
using (var ms = new MemoryStream())

    // Create an iTextSharp Document which is an abstraction of a PDF but **NOT** a PDF
    using (var doc = new Document())
    
        // Create a writer that's bound to our PDF abstraction and our stream
        using (var writer = PdfWriter.GetInstance(doc, ms))
        
            // Open the document for writing
            doc.Open();

            string finalHtml = string.Empty;

            // Read your html by database or file here and store it into finalHtml e.g. a string
            // XMLWorker also reads from a TextReader and not directly from a string
            using (var srHtml = new StringReader(finalHtml))
            
                // Parse the HTML
                iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
            

            doc.Close();
        
    

    // After all of the PDF "stuff" above is done and closed but **before** we
    // close the MemoryStream, grab all of the active bytes from the stream
    bytes = ms.ToArray();


// Clear the response
Response.Clear();
MemoryStream mstream = new MemoryStream(bytes);

// Define response content type
Response.ContentType = "application/pdf";

// Give the name of file of pdf and add in to header
Response.AddHeader("content-disposition", "attachment;filename=invoice.pdf");
Response.Buffer = true;
mstream.WriteTo(Response.OutputStream);
Response.End();

【讨论】:

.NET Core 怎么样?【参考方案8】:

2020 年更新:

现在将 HTML 转换为 PDF 非常简单。您所要做的就是使用 NuGet 安装 itext7itext7.pdfhtml。您可以通过转到“项目”>“管理 NuGet 包...”在 Visual Studio 中执行此操作

确保包含此依赖项:

using iText.Html2pdf;

现在只需粘贴这一衬里就完成了:

HtmlConverter.ConvertToPdf(new FileInfo(@"temp.html"), new FileInfo(@"report.pdf"));

如果您在 Visual Studio 中运行此示例,您的 html 文件应位于 /bin/Debug 目录中。

如果您有兴趣,这里有一个很好的resource。另请注意,itext7 已获得 AGPL 许可。

【讨论】:

【参考方案9】:

如果您在 html 服务器端将 html 转换为 pdf,您可以使用 Rotativa :

Install-Package Rotativa

这是基于 wkhtmltopdf,但它比 iTextSharp 具有更好的 css 支持,并且与 MVC(最常用)集成非常简单,因为您可以简单地将视图返回为 pdf:

public ActionResult GetPdf()

    //...
    return new ViewAsPdf(model);// and you are done!
 

【讨论】:

以上是关于ITextSharp HTML到PDF?的主要内容,如果未能解决你的问题,请参考以下文章

iTextSharp操作PDF

如何使用 iText 将带有图像和超链接的 HTML 转换为 PDF?

C#工具类:使用iTextSharp操作PDF文档

c# itextsharp PDF 创建每个页面上都有水印

ITextSharp HTML到PDF?

使用 itextsharp 将图像 html 旁边的文本放置到 pdf