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

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

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

tia.

【问题讨论】:

    标签: .net itextsharp html-to-pdf


    【解决方案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 取代。请参阅stackoverflow.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你能帮帮我吗:stackoverflow.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!
        } 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-09-30
          • 2013-07-11
          • 1970-01-01
          • 1970-01-01
          • 2011-11-28
          • 2011-06-29
          • 2011-08-29
          • 1970-01-01
          相关资源
          最近更新 更多