ITextSharp HTML转PDF?

65

我想知道ITextSharp是否有将HTML转换为PDF的功能。 我需要转换的所有内容都只是纯文本,但不幸的是,关于ITextSharp几乎没有任何文档,所以我无法确定它是否对我来说是可行的解决方案。

如果不能实现,有人可以指向一些好的、免费的.NET库,可以将简单的纯文本HTML文档转换为PDF吗?

谢谢您。

9个回答

65

几周前我也遇到了同样的问题,这是我发现的结果。该方法可以快速将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;
}

10
请注意,截至 5.1.1 版本,HTMLWorker 可在 iTextSharp.text.html.simpleparser 中找到。为避免其他人不得不查阅文档,此处提供翻译。 - James Skemp
76
为什么在C#代码示例中人们从不使用“using”语句? - cbp
5
我通常会在using语句声明中调用一个方法,例如 using(MemoryStream stream = createPDF(html)) {} - Jonathan
6
为了拯救更多的人,HTMLWorker现在已经过时。请使用XMLWorkerHelper.ParseXHtml(),但要注意,它仅适用于XHTML。由于它被设计为附加组件,因此您必须单独下载它。 - Jake
6
HTMLWorker 类现已过时,被 XMLWorker 取代。请查看 https://dev59.com/0V8e5IYBdhLWcg3w-OYn 获取关于如何使用它将 HTML 渲染为 PDF(包括 CSS 渲染)的深入概述。 - mark.monteiro
显示剩余6条评论

28

经过一些探索,我发现使用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
    {
    }
}

4
你可能不想像Web应用程序那样将输出写入固定路径中。在负载下,这会导致对单个文件的资源争用。使用MemoryStream或由操作系统提供的临时文件(确保在完成后删除临时文件)。如何创建临时文件:http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename.aspx - ntcolonel
2
对象引用未设置到对象的实例。在List<IElement> htmlarraylist = HTMLWorker.ParseToList(new StringReader(htmlText), null); - navule
嗨@Kyle,你能帮我吗:http://stackoverflow.com/questions/20950236/how-to-insert-html-markup-using-itextsharp-for-creating-pdf-using-c - SHEKHAR SHETE
嘿,当我提供本地主机链接时,我收到错误消息“远程服务器返回错误:(401)未经授权。”你遇到过这个问题吗? - Ensar Turkoglu
您需要在尝试将新文件写入的文件夹上启用权限。或者,如果文件已经存在,则可能正在被其他进程使用。 - gunwin

11

以下是我在版本5.4.2上(从NuGet安装)能够实现的ASP.NET MVC控制器返回PDF响应的示例。如果需要,可以修改为使用FileStream而不是MemoryStream输出。 我在这里发布它,因为它是当前iTextSharp用于HTML-> PDF转换的完整示例(忽略图像,因为我的使用不需要)。它使用了iTextSharp的XmlWorkerHelper,所以传入的HTML必须是有效的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 =“<img src ='https://www.google.com/images/srpr/logo11w.png' />”。 - David Silva Smith

10

如果我有声望,我会比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 pack组装的(我正在自动化发票生成):

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;
}

再次感谢mightymada,你的回答非常出色。


5
警惕:在几乎所有方面(依我之见),Pechkin(和TuesPechkin)都比iTextSharp更优秀,唯一的例外是它们无法在Azure Web Sites(也许许多共享托管环境)中使用。 - Jay Querido
Pechkin是wkhtmltopdf的包装器,它使用QT Webkit将网页呈现为PDF。这本质上与在Safari(基于Webkit的浏览器)中说“打印到PDF”相同。这与从代码创建PDF文件完全不同。这也是OP所要求的完全相反的用例。因此我要点踩。 - Amedee Van Gasse

6
我更喜欢使用另一个名为 Pechkin 的库,因为它可以转换非平凡的 HTML(也具有 CSS 类)。这是可能的,因为该库使用了 WebKit 布局引擎,该引擎也被像 Chrome 和 Safari 这样的浏览器所使用。
我在我的博客上详细介绍了使用 Pechkin 的经验:http://codeutil.wordpress.com/2013/09/16/convert-html-to-pdf/

3

它有将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呢? - Matthew Layton

3

2020更新:

现在将HTML转换为PDF非常简单。您只需要使用NuGet安装itext7itext7.pdfhtml即可。在Visual Studio中,您可以通过转到“项目”>“管理NuGet包...”来完成此操作。

确保包含此依赖项:

using iText.Html2pdf;

现在只需复制此单行代码即可完成:
HtmlConverter.ConvertToPdf(new FileInfo(@"temp.html"), new FileInfo(@"report.pdf"));

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

如果您感兴趣,这里有一个不错的资源。另外,请注意itext7是根据AGPL许可证授权的。


3

上述代码可以帮助将HTML转换为PDF,但如果HTML代码中包含相对路径的IMG标签,则会失败。iTextSharp库不会自动将相对路径转换为绝对路径。

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

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


您已经找到了问题,但是您参考的IImageProvider解决方案在尝试从www.google.com读取HTML并生成PDF时出现以下错误:Could not find a part of the path 'C:\intl\en_ALL\images\srpr\logo1w.png'。 - cusman

1
如果您需要在html服务器端将html转换为pdf,您可以使用Rotativa:
Install-Package Rotativa

这是基于wkhtmltopdf的,比iTextSharp具有更好的CSS支持,并且非常容易与MVC集成(大多数情况下使用),因为你可以简单地返回视图作为PDF。
public ActionResult GetPdf()
{
    //...
    return new ViewAsPdf(model);// and you are done!
} 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接