【问题标题】:Convert HTML to PDF in .NET [closed]在.NET中将HTML转换为PDF [关闭]
【发布时间】:2010-10-08 13:22:03
【问题描述】:

我想通过将 HTML 内容传递给函数来生成 PDF。我已经为此使用了 iTextSharp,但是当它遇到表格并且布局变得混乱时,它表现不佳。

有没有更好的办法?

【问题讨论】:

  • 您可以为此使用GemBox.Document。另外here您可以找到将HTML文件转换为PDF文件的示例代码。
  • 您使用哪个版本的 iTextSharp,您可以分享您的 html 吗?
  • 仍然没有回答我要求提供更多信息的请求。如果您使用的是 HTMLWorker 或 XMLWorker,请同时添加。
  • .net 核心呢?
  • Anvil 提供了一套完整的 API 用于生成、填充和电子签名 PDF。他们刚刚推出了一个 HTML 到 PDF 端点 useanvil.com/pdf-generation-api

标签: c# html pdf itextsharp


【解决方案1】:

对于所有在.net 5 中寻找有效解决方案的人,请看这里。

这是我的工作解决方案。

使用wkhtmltopdf:

  1. here下载并安装wkhtmltopdf最新版本。
  2. 使用下面的代码。
public static string HtmlToPdf(string outputFilenamePrefix, string[] urls,
    string[] options = null,
    string pdfHtmlToPdfExePath = @"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe")
{
    string urlsSeparatedBySpaces = string.Empty;
    try
    {
        //Determine inputs
        if ((urls == null) || (urls.Length == 0))
            throw new Exception("No input URLs provided for HtmlToPdf");
        else
            urlsSeparatedBySpaces = String.Join(" ", urls); //Concatenate URLs

        string outputFilename = outputFilenamePrefix + "_" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss-fff") + ".PDF"; // assemble destination PDF file name

        var p = new System.Diagnostics.Process()
        {
            StartInfo =
            {
                FileName = pdfHtmlToPdfExePath,
                Arguments = ((options == null) ? "" : string.Join(" ", options)) + " " + urlsSeparatedBySpaces + " " + outputFilename,
                UseShellExecute = false, // needs to be false in order to redirect output
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                RedirectStandardInput = true, // redirect all 3, as it should be all 3 or none
                WorkingDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location))
            }
        };

        p.Start();

        // read the output here...
        var output = p.StandardOutput.ReadToEnd();
        var errorOutput = p.StandardError.ReadToEnd();

        // ...then wait n milliseconds for exit (as after exit, it can't read the output)
        p.WaitForExit(60000);

        // read the exit code, close process
        int returnCode = p.ExitCode;
        p.Close();

        // if 0 or 2, it worked so return path of pdf
        if ((returnCode == 0) || (returnCode == 2))
            return outputFilename;
        else
            throw new Exception(errorOutput);
    }
    catch (Exception exc)
    {
        throw new Exception("Problem generating PDF from HTML, URLs: " + urlsSeparatedBySpaces + ", outputFilename: " + outputFilenamePrefix, exc);
    }
}
  1. 并将上述方法调用为HtmlToPdf("test", new string[] { "https://www.google.com" }, new string[] { "-s A5" });
  2. 如果您需要将HTML字符串转换为PDF,调整上述方法并将Arguments替换为Process StartInfo$@"/C echo | set /p=""{htmlText}"" | ""{pdfHtmlToPdfExePath}"" {((options == null) ? "" : string.Join(" ", options))} - ""C:\Users\xxxx\Desktop\{outputFilename}""";

这种方法的缺点:

  1. 截至发布此答案的wkhtmltopdf 的最新版本不支持最新的HTML5CSS3。因此,如果您尝试将任何 html 导出为 CSS GRID,则输出将与预期不同。
  2. 您需要处理并发问题。

使用chrome headless:

  1. here下载并安装最新的chrome浏览器。
  2. 使用下面的代码。
var p = new System.Diagnostics.Process()
{
    StartInfo =
    {
        FileName = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
        Arguments = @"/C --headless --disable-gpu --run-all-compositor-stages-before-draw --print-to-pdf-no-header --print-to-pdf=""C:/Users/Abdul Rahman/Desktop/test.pdf"" ""C:/Users/Abdul Rahman/Desktop/grid.html""",
    }
};

p.Start();

// ...then wait n milliseconds for exit (as after exit, it can't read the output)
p.WaitForExit(60000);

// read the exit code, close process
int returnCode = p.ExitCode;
p.Close();
  1. 这会将html 文件转换为pdf 文件。
  2. 如果您需要将一些url 转换为pdf,请使用以下ArgumentProcess StartInfo

@"/C --headless --disable-gpu --run-all-compositor-stages-before-draw --print-to-pdf-no-header --print-to-pdf=""C:/Users/Abdul Rahman/Desktop/test.pdf"" ""https://www.google.com""",

这种方法的缺点:

  1. 这可以与最新的HTML5CSS3 功能一起正常工作。输出将与您在浏览器中查看的相同,但通过 IIS 运行时,您需要在 LocalSystem 身份下运行应用程序的 AppliactionPool,或者您需要提供 read/write 访问 IISUSRS

使用Selenium WebDriver:

  1. 安装 Nuget 包 Selenium.WebDriverSelenium.WebDriver.ChromeDriver
  2. 使用下面的代码。
public async Task<byte[]> ConvertHtmlToPdf(string html)
{
    var directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments), "ApplicationName");
    Directory.CreateDirectory(directory);
    var filePath = Path.Combine(directory, $"{Guid.NewGuid()}.html");
    await File.WriteAllTextAsync(filePath, html);

    var driverOptions = new ChromeOptions();
    // In headless mode, PDF writing is enabled by default (tested with driver major version 85)
    driverOptions.AddArgument("headless");
    using var driver = new ChromeDriver(driverOptions);
    driver.Navigate().GoToUrl(filePath);

    // Output a PDF of the first page in A4 size at 90% scale
    var printOptions = new Dictionary<string, object>
    {
        { "paperWidth", 210 / 25.4 },
        { "paperHeight", 297 / 25.4 },
        { "scale", 0.9 },
        { "pageRanges", "1" }
    };
    var printOutput = driver.ExecuteChromeCommandWithResult("Page.printToPDF", printOptions) as Dictionary<string, object>;
    var pdf = Convert.FromBase64String(printOutput["data"] as string);

    File.Delete(filePath);

    return pdf;
}

这种方法的优点:

  1. 这只需要安装 Nuget 并使用最新的 HTML5CSS3 功能按预期工作。输出将与您在浏览器中查看的相同。

这种方法的缺点:

  1. 这种方法需要在运行应用的服务器上安装最新的 chrome 浏览器。

使用这种方法,请务必在.csproj文件中添加&lt;PublishChromeDriver&gt;true&lt;/PublishChromeDriver&gt;,如下所示:

<PropertyGroup>
  <TargetFramework>net5.0</TargetFramework>
  <LangVersion>latest</LangVersion>
  <Nullable>enable</Nullable>
  <PublishChromeDriver>true</PublishChromeDriver>
</PropertyGroup>

这将在发布项目时发布chrome driver

这是我的工作项目 repo 的链接 - HtmlToPdf

在使用可用选项几乎花了 2 天后,我得到了上述答案,并最终实现了基于 Selenium 的解决方案及其工作。希望这可以帮助您并节省您的时间。

【讨论】:

  • 您是否偶然在 Azure 上运行过这些?我很快就会发现自己。
  • 不,我没试过。如果您在 Azure 上尝试过,请在此处更新
  • @ttugates 你有机会验证吗?请分享您的反馈。如果对您有帮助,请为答案投票。
  • 我会回过头来回答这个问题。
  • @dalemac 是的。 chrome 需要安装在服务器上。用此信息更新了答案。
【解决方案2】:

你也可以查看Spire,它可以让你用这段简单的代码创建HTML to PDF

 string htmlCode = "<p>This is a p tag</p>";
 
//use single thread to generate the pdf from above html code
Thread thread = new Thread(() =>
{ pdf.LoadFromHTML(htmlCode, false, setting, htmlLayoutFormat); });
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
 
// Save the file to PDF and preview it.
pdf.SaveToFile("output.pdf");
System.Diagnostics.Process.Start("output.pdf");

【讨论】:

  • Spire 生成一个只是图像的 PDF 文件。有些 css 甚至不正确,比如忽略粗体。
  • 查看我关于将 PDF 生成为图像的问题的回复:e-iceblue.com/forum/nuget-pdf-as-non-image-t6710.html
  • Spire 是我从这个页面尝试的第四个,我认为它是最好的,谢谢。
【解决方案3】:

很可能大多数项目将封装 C/C++ 引擎,而不是从头开始实施 C# 解决方案。尝试项目Gotenberg

测试一下

docker run --rm -p 3000:3000 thecodingmachine/gotenberg:6

卷曲示例

curl --request POST \
    --url http://localhost:3000/convert/url \
    --header 'Content-Type: multipart/form-data' \
    --form remoteURL=https://brave.com \
    --form marginTop=0 \
    --form marginBottom=0 \
    --form marginLeft=0 \
    --form marginRight=0 \
    -o result.pdf

C# 示例.cs

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;
using static System.Console;

namespace Gotenberg
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            try
            {
                var client = new HttpClient();            
                var formContent = new MultipartFormDataContent
                    {
                        {new StringContent("https://brave.com/"), "remoteURL"},
                        {new StringContent("0"), "marginTop" }
                    };
                var result = await client.PostAsync(new Uri("http://localhost:3000/convert/url"), formContent);
                await File.WriteAllBytesAsync("duckduck.com.pdf", await result.Content.ReadAsByteArrayAsync());
            }
            catch (Exception ex)
            {
                WriteLine(ex);
            }
        }
    }
}

编译

csc sample.cs -langversion:latest -reference:System.Net.Http.dll && mono ./sample.exe

【讨论】:

    【解决方案4】:

    最后更新时间:2020 年 10 月

    这是我整理的 .NET 中 HTML 到 PDF 转换的选项列表(有些是免费的,有些是付费的)

    如果以上选项都不能帮助您,您可以随时搜索 NuGet 包:
    https://www.nuget.org/packages?q=html+pdf

    【讨论】:

    • 你测试过任何性能吗?我们正在寻求改善当前的转换时间,并正在探索其他库以获得这些性能优势
    • 我没有进行任何性能比较,尤其是因为列表如此之长 - 也许有人已经完成了“PDF 生成 .net 库性能评估”或类似的工作
    • 另一个基于 wkhtmtopdf 甚至可以在 Azure Web 服务上运行的解决方案是 DinkToPdf fork:github.com/hakanl/DinkToPdf 和 nuget:nuget.org/packages/Haukcode.DinkToPdf
    • DinkToPdf 是免费的,可以在 .net 内核中运行。 nuget.org/packages/DinkToPdf
    • @FritsJ 列表中有很多选项 ;-)
    【解决方案5】:

    您可以在无头模式下使用 Google Chrome 打印到 PDF 功能。我发现这是最简单但最可靠的方法。

    var url = "https://stackoverflow.com/questions/564650/convert-html-to-pdf-in-net";
    var chromePath = @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe";
    var output = Path.Combine(Environment.CurrentDirectory, "printout.pdf");
    using (var p = new Process())
        {
            p.StartInfo.FileName = chromePath;
            p.StartInfo.Arguments = $"--headless --disable-gpu --print-to-pdf={output} {url}";
            p.Start();
            p.WaitForExit();
        }
    
    

    【讨论】:

    • 嘿,这对于自有服务器和 vps 来说真的很酷。感谢分享。
    • 为了让IIS中的ASP.NET能够运行具有写访问权限的外部程序,应用程序池>高级设置>身份>设置为“LocalSystem”
    • 我喜欢这种方式,但是如果对url的请求需要更具体的,比如header、cookie甚至post方式,怎么处理呢?
    • 它能处理html字符串吗?而不是网址。
    • 我有问题。 pdf转换未完全加载页面。
    【解决方案6】:

    目前看来,最好的免费 .NET 解决方案是TuesPechkin 库,它是wkhtmltopdf 本机库的包装器。

    我现在使用单线程版本将几千个 HTML 字符串转换为 PDF 文件,它似乎工作得很好。它应该也可以在多线程环境(例如 IIS)中工作,但我还没有测试过。

    另外由于我想使用最新版本的wkhtmltopdf(撰写本文时为0.12.5),我从官网下载了DLL,将其复制到我的项目根目录,设置复制输出为真,并像这样初始化库:

    var dllDir = AppDomain.CurrentDomain.BaseDirectory;
    Converter = new StandardConverter(new PdfToolset(new StaticDeployment(dllDir)));
    

    上面的代码看起来完全是“wkhtmltox.dll”,所以不要重命名文件。我使用的是 64 位版本的 DLL。

    确保您阅读了多线程环境的说明,因为您只需在每个应用生命周期中初始化一次,因此您需要将其放入单例或其他东西中。

    【讨论】:

    • wkhtmltopdf 很棒,但它基于 2012 年左右的 WebKit,因此不支持更现代的 HTML/CSS。
    【解决方案7】:

    你可以使用 WebBrowser 控件的另一个技巧,下面是我的完整工作代码

    在我的例子中将 Url 分配给文本框控件

      protected void Page_Load(object sender, EventArgs e)
    {
    
       txtweburl.Text = "https://www.google.com/";
    
     }
    

    下面是使用线程生成屏幕的代码

      protected void btnscreenshot_click(object sender, EventArgs e)
      {
        //  btnscreenshot.Visible = false;
        allpanels.Visible = true;
        Thread thread = new Thread(GenerateThumbnail);
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
    
    }
    
    private void GenerateThumbnail()
    {
        //  btnscreenshot.Visible = false;
        WebBrowser webrowse = new WebBrowser();
        webrowse.ScrollBarsEnabled = false;
        webrowse.AllowNavigation = true;
        string url = txtweburl.Text.Trim();
        webrowse.Navigate(url);
        webrowse.Width = 1400;
        webrowse.Height = 50000;
    
        webrowse.DocumentCompleted += webbrowse_DocumentCompleted;
        while (webrowse.ReadyState != WebBrowserReadyState.Complete)
        {
            System.Windows.Forms.Application.DoEvents();
        }
    }
    

    在下面的代码中,我在下载后保存 pdf 文件

            private void webbrowse_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        // btnscreenshot.Visible = false;
        string folderPath = Server.MapPath("~/ImageFiles/");
    
        WebBrowser webrowse = sender as WebBrowser;
        //Bitmap bitmap = new Bitmap(webrowse.Width, webrowse.Height);
    
        Bitmap bitmap = new Bitmap(webrowse.Width, webrowse.Height, PixelFormat.Format16bppRgb565);
    
        webrowse.DrawToBitmap(bitmap, webrowse.Bounds);
    
    
        string Systemimagedownloadpath = System.Configuration.ConfigurationManager.AppSettings["Systemimagedownloadpath"].ToString();
        string fullOutputPath = Systemimagedownloadpath + Request.QueryString["VisitedId"].ToString() + ".png";
        MemoryStream stream = new MemoryStream();
        bitmap.Save(fullOutputPath, System.Drawing.Imaging.ImageFormat.Jpeg);
    
    
    
        //generating pdf code 
         Document pdfDoc = new Document(new iTextSharp.text.Rectangle(1100f, 20000.25f));
         PdfWriter writer = PdfWriter.GetInstance(pdfDoc, Response.OutputStream);
         pdfDoc.Open();
         iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(fullOutputPath);   
         img.ScaleAbsoluteHeight(20000);
         img.ScaleAbsoluteWidth(1024);     
         pdfDoc.Add(img);
         pdfDoc.Close();
         //Download the PDF file.
         Response.ContentType = "application/pdf";
         Response.AddHeader("content-disposition", "attachment;filename=ImageExport.pdf");
         Response.Cache.SetCacheability(HttpCacheability.NoCache);
         Response.Write(pdfDoc);
         Response.End();
    
    
    }
    

    您也可以参考我最早的帖子了解更多信息:Navigation to the webpage was canceled getting message in asp.net web form

    【讨论】:

      【解决方案8】:

      2018 年的更新,让我们使用标准的 HTML+CSS=PDF 公式!

      对于 HTML 到 PDF 的需求有好消息。正如this answer showedW3C 标准css-break-3 将解决这个问题...这是一个候选推荐,计划在 2017 年或 2018 年经过测试成为最终推荐。

      正如print-css.rocks 所展示的那样,有一些带有 C# 插件的解决方案。

      【讨论】:

      • 通过 print-css.rocks 链接的解决方案的 PDFreactor 价格为 2,950.00 美元,Prince 价格为 3800 美元,Antenna House Formatter V7 价格为 5,000.00 美元。 Weasyprint 似乎适用于 Python。
      【解决方案9】:

      编辑:新建议 HTML Renderer for PDF using PdfSharp

      (在尝试 wkhtmltopdf 并建议避免之后)

      HtmlRenderer.PdfSharp 是 100% 完全 C# 托管代码易于使用,线程安全,最重要的是 免费 ( New BSD License) 解决方案。

      用法

      1. 下载 HtmlRenderer.PdfSharp nuget 包。
      2. 使用示例方法。

        public static Byte[] PdfSharpConvert(String html)
        {
            Byte[] res = null;
            using (MemoryStream ms = new MemoryStream())
            {
                var pdf = TheArtOfDev.HtmlRenderer.PdfSharp.PdfGenerator.GeneratePdf(html, PdfSharp.PageSize.A4);
                pdf.Save(ms);
                res = ms.ToArray();
            }
            return res;
        }
        

      一个非常好的替代品Free VersioniTextSharp

      直到 4.1.6 版 iTextSharp 在 LGPL 许可下获得许可,并且直到 4.16 版(或者可能还有分叉)都可以作为包提供并且可以免费使用。当然有人可以用续5+paid version

      我尝试在我的项目中集成 wkhtmltopdf 解决方案,但遇到了很多障碍。

      出于以下原因,我个人会避免在托管企业应用程序上使用 wkhtmltopdf - based 解决方案。

      1. 首先,wkhtmltopdf 是 C++ 而非 C# 实现的,您将 将其嵌入到 C# 代码中时遇到各种问题, 尤其是在您的 32 位和 64 位版本之间切换时 项目。不得不尝试几种解决方法,包括有条件的 项目建设等只是为了避免“无效格式异常” 在不同的机器上。
      2. 如果您管理自己的虚拟机,则可以。但是如果你的项目 在受限环境中运行,例如 (Azure (实际上用天蓝色是不可能的,如 TuesPenchin 作者), Elastic Beanstalk 等)配置该环境仅让 wkhtmltopdf 工作是一场噩梦。
      3. wkhtmltopdf 正在您的服务器中创建文件,因此您必须 管理用户权限并授予对 where 的“写入”访问权限 wkhtmltopdf 正在运行。
      4. Wkhtmltopdf 作为一个独立的应用程序运行,所以它的 不是 由您的 IIS 应用程序池管理。所以你必须要么托管它 作为另一台机器上的服务,否则您将在生产中遇到处理峰值和内存消耗 服务器。
      5. 它使用临时文件来生成 pdf,在某些情况下像 AWS EC2 的磁盘 i/o 非常慢,这是一个很大的性能 问题。
      6. 最讨厌的“无法加载DLL 'wkhtmltox.dll'”报错 许多用户。

      --- 预编辑部分 ---

      对于任何想在更简单的应用程序/环境中从 html 生成 pdf 的人,我将我的旧帖子留作建议。

      TuesPechkin

      https://www.nuget.org/packages/TuesPechkin/

      或特别适用于 MVC Web 应用程序 (但我认为您可以在任何 .net 应用程序中使用它)

      Rotativa

      https://www.nuget.org/packages/Rotativa/

      他们都利用 wkhtmtopdf 用于将 html 转换为 pdf 的二进制文件。它使用 webkit 引擎来渲染页面,因此它也可以解析 css 样式表

      它们提供易于使用的与 C# 的无缝集成。

      Rotativa 还可以从任何 Razor 视图直接生成 PDF。

      此外,对于现实世界的 Web 应用程序,它们还管理线程安全等...

      【讨论】:

      • 感谢您更新您的帖子。我要试试 PdfSharp。你为我节省了很多时间。
      • PdfSharp 在性能方面不错,但它并没有为我正确渲染浮动。幸运的是,我可以更改标记以使用良好的旧表格,PdfSharp 可以很好地处理它们。
      • 我们尝试了 HtmlRenderer。不加载任何 CSS 时非常快。但是当我们尝试应用 CSS(Bootstrap 加上一些定制)时,CSS 解析需要一段时间(我们可能会缓解),并且呈现与网页完全不同。
      • BS。这将创建 HTML 图像并将图像添加到 pdf 文件中。这根本不是真正的 PDF。此外,PDF 是一种矢量图形格式——您可以几乎无限滚动——当然,除非 PDF 包含光栅图形,这是该库生成的。
      • @Anestis Kivranoglou 我在我的项目中使用了 pdf sharp。但是对于使用 css 的 html 设计,它无法呈现 html。相反,它只是创建一个空白页
      【解决方案10】:

      这是一个免费库,非常容易使用:OpenHtmlToPdf

      string timeStampForPdfName = DateTime.Now.ToString("yyMMddHHmmssff");
      
      string serverPath = System.Web.Hosting.HostingEnvironment.MapPath("~/FolderName");
      string pdfSavePath = Path.Combine(@serverPath, "FileName" + timeStampForPdfName + ".FileExtension");
      
      
      //OpenHtmlToPdf Library used for Performing PDF Conversion
      var pdf = Pdf.From(HTML_String).Content();
      
      //FOr writing to file from a ByteArray
       File.WriteAllBytes(pdfSavePath, pdf.ToArray()); // Requires System.Linq
      

      【讨论】:

        【解决方案11】:

        另一个建议是尝试https://grabz.it 的解决方案。

        他们提供了一个很好的 .NET API 来捕捉屏幕截图并以一种简单灵活的方式进行操作。

        要在您的应用程序中使用它,您首先需要获得key + secretdownload .NET SDK(它是免费的)。

        现在是一个使用它的简短示例。

        要使用 API,您首先需要创建 GrabzItClient 类的实例,将应用程序密钥和应用程序机密从 GrabzIt 帐户传递给构造函数,如下例所示:

        //Create the GrabzItClient class
        //Replace "APPLICATION KEY", "APPLICATION SECRET" with the values from your account!
        private GrabzItClient grabzIt = GrabzItClient.Create("Sign in to view your Application Key", "Sign in to view your Application Secret");
        

        现在,只需将 HTML 转换为 PDF:

        grabzIt.HTMLToPDF("<html><body><h1>Hello World!</h1></body></html>");
        

        你也可以转换成图片:

        grabzIt.HTMLToImage("<html><body><h1>Hello World!</h1></body></html>");     
        

        接下来您需要保存图像。您可以使用两种可用的保存方法之一,Save 如果可公开访问的回调句柄可用,SaveTo 如果不可用。 Check the documentation了解详情。

        【讨论】:

          【解决方案12】:

          作为 HiQPdf Software 的代表,我认为最好的解决方案是HiQPdf HTML to PDF converter for .NET。它包含市场上最先进的 HTML5、CSS3、SVG 和 JavaScript 渲染引擎。还有一个free version of the HTML to PDF library,您可以使用它免费制作多达 3 个 PDF 页面。从 HTML 页面生成 PDF 作为 byte[] 的最小 C# 代码是:

          HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
          
          // set PDF page size, orientation and margins
          htmlToPdfConverter.Document.PageSize = PdfPageSize.A4;
          htmlToPdfConverter.Document.PageOrientation = PdfPageOrientation.Portrait;
          htmlToPdfConverter.Document.Margins = new PdfMargins(0);
          
          // convert HTML to PDF 
          byte[] pdfBuffer = htmlToPdfConverter.ConvertUrlToMemory(url);
          

          您可以在HiQPdf HTML to PDF Converter examples repository 中找到更详细的 ASP.NET 和 MVC 示例。

          【讨论】:

          • 产生不错的结果,但与 SelectPdf 一样,它会对您的构建时间和部署包大小产生重大影响。我的 Visual Studio 构建时间几乎翻了一番。我也很难让它填满我的页面 - 中间的 html 太小 - 在这方面 SelectPdf 做得更好。
          • 页面填充 HTML 内容取决于 HtmlToPdf.BrowserWidth 属性。默认为 1200 像素,但您可以将其设置为 800 像素,HTML 应该可以很好地填充整个 PDF 页面。您可以在 hiqpdf.com/demo/HtmlFittingAndScalingOptions.aspx 找到现场演示和示例代码
          • 也不支持 .NET Core。
          【解决方案13】:

          下面是使用iTextSharp(iTextSharp + itextsharp.xmlworker)将html + css转换为PDF的示例

          using iTextSharp.text;
          using iTextSharp.text.pdf;
          using iTextSharp.tool.xml;
          
          
          byte[] pdf; // result will be here
          
          var cssText = File.ReadAllText(MapPath("~/css/test.css"));
          var html = File.ReadAllText(MapPath("~/css/test.html"));
          
          using (var memoryStream = new MemoryStream())
          {
                  var document = new Document(PageSize.A4, 50, 50, 60, 60);
                  var writer = PdfWriter.GetInstance(document, memoryStream);
                  document.Open();
          
                  using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssText)))
                  {
                      using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html)))
                      {
                          XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, htmlMemoryStream, cssMemoryStream);
                      }
                  }
          
                  document.Close();
          
                  pdf = memoryStream.ToArray();
          }
          

          【讨论】:

          • 请注意,iTextSharp 与 XHtml 一起使用,并且对 html 的质量非常敏感。它会中断,而 SelectPdf 和 HiqPdf 不会。
          【解决方案14】:

          如果您已经在使用 itextsharp dll,则无需添加第三方 dll(插件),我认为您使用的是 htmlworker 而不是使用 xmlworker,您可以轻松地将 html 转换为 pdf。

          有些 css 不起作用,它们是 Supported CSS
          Full Explain with example Reference Click here


                  MemoryStream memStream = new MemoryStream();
                  TextReader xmlString = new StringReader(outXml);
                  using (Document document = new Document())
                  {
                      PdfWriter writer = PdfWriter.GetInstance(document, memStream);
                      //document.SetPageSize(iTextSharp.text.PageSize.A4);
                      document.Open();
                      byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(outXml);
                      MemoryStream ms = new MemoryStream(byteArray);
                      XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, ms, System.Text.Encoding.UTF8);
                      document.Close();
                  }
          
                  Response.ContentType = "application/pdf";
                  Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".pdf");
                  Response.Cache.SetCacheability(HttpCacheability.NoCache);
                  Response.BinaryWrite(memStream.ToArray());
                  Response.End();
                  Response.Flush();
          

          【讨论】:

          • 值得注意的是,iTextSharp 使用 Affero 通用公共许可证,限制它只能与其他开源应用程序一起使用。这对于考虑此选项的某些人来说可能很重要。
          【解决方案15】:

          PDFmyURL 最近还发布了一个用于网页/HTML 到 PDF 转换的 .NET 组件。这有一个非常用户友好的界面,例如:

          PDFmyURL pdf = new PDFmyURL("yourlicensekey");
          pdf.ConvertURL("http://www.example.com", Application.StartupPath + @"\example.pdf");
          

          文档:PDFmyURL .NET component documentation

          免责声明:我为拥有 PDFmyURL 的公司工作

          【讨论】:

            【解决方案16】:

            我强烈推荐NReco,认真的。它有免费版和付费版,真的很值得。它在后台使用 wkhtmtopdf,但您只需要一个程序集。太棒了。

            使用示例:

            通过NuGet安装。

            var htmlContent = String.Format("<body>Hello world: {0}</body>", DateTime.Now);
            var pdfBytes = (new NReco.PdfGenerator.HtmlToPdfConverter()).GeneratePdf(htmlContent);
            

            免责声明:我不是开发者,只是该项目的粉丝 :)

            【讨论】:

            • 看起来确实很有用。值得注意的是,截至今天(2015 年 5 月 10 日),它是 wkhtmtopdf(作为 Nuget 包)下载次数最多的 .Net 包装器。
            • 试过了,不幸的是我无法让它在 azure 的网页上运行。
            • 当我在我的机器上本地运行这个库时,它运行良好,但在托管服务器上,我随机看到以下错误。有时会生成 Pdf,但有时会引发以下错误。 “错误。处理您的请求时出错。无法生成 PDF:(退出代码:1)”
            • wkhtmtopdf 依赖于 GDI+,如果你在 Mono/Linux 上运行,则依赖于 x-server。所以这对服务器环境没有用...
            • 它很好并且按预期工作,但是我在我的 pdf 中看到了位质量问题,我们可以改进吗?
            【解决方案17】:

            我发现并用于生成 javascript 和样式呈现视图或 html 页面的 PDF 的最佳工具是 phantomJS

            使用示例文件夹的 exe 根目录中的 rasterize.js 函数下载 .exe 文件并放入解决方案中。

            它甚至允许您在不打开该文件的情况下以任何代码下载文件,它还允许在应用样式和特别是 jquery 时下载文件。

            以下代码生成 PDF 文件:

            public ActionResult DownloadHighChartHtml()
            {
                string serverPath = Server.MapPath("~/phantomjs/");
                string filename = DateTime.Now.ToString("ddMMyyyy_hhmmss") + ".pdf";
                string Url = "http://wwwabc.com";
            
                new Thread(new ParameterizedThreadStart(x =>
                {
                    ExecuteCommand(string.Format("cd {0} & E: & phantomjs rasterize.js {1} {2} \"A4\"", serverPath, Url, filename));
                                       //E: is the drive for server.mappath
                })).Start();
            
                var filePath = Path.Combine(Server.MapPath("~/phantomjs/"), filename);
            
                var stream = new MemoryStream();
                byte[] bytes = DoWhile(filePath);
            
                Response.ContentType = "application/pdf";
                Response.AddHeader("content-disposition", "attachment;filename=Image.pdf");
                Response.OutputStream.Write(bytes, 0, bytes.Length);
                Response.End();
                return RedirectToAction("HighChart");
            }
            
            
            
            private void ExecuteCommand(string Command)
            {
                try
                {
                    ProcessStartInfo ProcessInfo;
                    Process Process;
            
                    ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + Command);
            
                    ProcessInfo.CreateNoWindow = true;
                    ProcessInfo.UseShellExecute = false;
            
                    Process = Process.Start(ProcessInfo);
                }
                catch { }
            }
            
            
            private byte[] DoWhile(string filePath)
            {
                byte[] bytes = new byte[0];
                bool fail = true;
            
                while (fail)
                {
                    try
                    {
                        using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                        {
                            bytes = new byte[file.Length];
                            file.Read(bytes, 0, (int)file.Length);
                        }
            
                        fail = false;
                    }
                    catch
                    {
                        Thread.Sleep(1000);
                    }
                }
            
                System.IO.File.Delete(filePath);
                return bytes;
            }
            

            【讨论】:

            • 你能分享你的完整源代码吗?我是 C# 新手,所以我什至在导入时遇到了困难。
            【解决方案18】:

            如果您希望用户在浏览器中下载渲染页面的 pdf,那么解决问题的最简单方法是

            window.print(); 
            

            在客户端它会提示用户保存当前页面的 pdf。也可以通过链接样式自定义pdf的外观

            <link rel="stylesheet" type="text/css" href="print.css" media="print">
            

            print.css 在打印时应用于 html。

            限制

            您不能将文件存储在服务器端。 用户提示打印页面而不是他必须手动保存页面。 页面必须在选项卡中呈现。

            【讨论】:

              【解决方案19】:

              如果你需要完美的 html 呈现在 pdf 中,你需要使用商业库。

              ExpertPdf Html To Pdf Converter非常好用,支持最新的html5/css3。您可以将整个 url 转换为 pdf:

              using ExpertPdf.HtmlToPdf; 
              byte[] pdfBytes = new PdfConverter().GetPdfBytesFromUrl(url);
              

              或一个 html 字符串:

              using ExpertPdf.HtmlToPdf; 
              byte[] pdfBytes = new PdfConverter().GetPdfBytesFromHtmlString(html, baseUrl);
              

              您还可以选择将生成的 pdf 文档直接保存到磁盘上的文件流中。

              【讨论】:

              • 如果您需要在pdf中完美呈现html,您不必使用商业库
              • 我开始相信这一点。我已经尝试了 5 个免费赠品,但他们都有一件事毁了我。从窒息到超出简单的 hello world 的页面,再到看起来很糟糕 - 我想我将不得不为真正的转换器掏出一些钱。每个商业产品的样本实际上都按照您期望的 PDF 的方式工作。
              • @obayhan - 我愿意相信你。也许您可以与我们分享一个链接,指向您认为非常好的任何工具。
              • @PeterWone 在顶部,您可以轻松看到许多开源替代方案。要求某人分享相同的东西只是在浪费时间。但是,如果您尝试了所有这些并且不满意,我希望您能在他们下分享您的 cmets 关于您不满意的地方,也许这将有助于增长知识。
              • @obayhan - 为什么要重复其他人已经做过的事情?它们分为三类:不是真正免费的、不可接受的依赖项,例如 wkhtmltopdf 或 IE9,以及用于 PDFSharp 的 HTML Renderer。 HR for PDF# 是纯 C# 中唯一的一个,它在分页方面做得很糟糕 - 它呈现一个长页面并将其剪切,通常会剪切文本行。如果我能抽出时间完全重写渲染器,PDF# 的 HR 将胜出:它快速、免费且没有依赖关系。但我担心那将是一个全新的渲染器。
              【解决方案20】:

              使用Winnovative HTML to PDF 转换器,您可以在一行中转换 HTML 字符串

              byte[] outPdfBuffer = htmlToPdfConverter.ConvertHtml(htmlString, baseUrl);
              

              基本 URL 用于解析 HTML 字符串中相对 URL 引用的图像。或者,您可以使用 HTML 中的完整 URL 或使用 src="data:image/png" 作为图像标签嵌入图像。

              在回答“fubaar”用户关于 Winnovative 转换器的评论时,需要进行更正。该转换器不使用 IE 作为渲染引擎。它实际上不依赖任何安装的软件,并且渲染与WebKit引擎兼容。

              【讨论】:

                【解决方案21】:

                您可以创建 HTML 页面的位图,然后将位图插入 PDF,而不是将 HTML 直接解析为 PDF,例如使用 iTextSharp

                以下是如何获取 URL 位图的代码。我在 SO 的某个地方找到了它,如果我找到了来源,我会链接它。

                public System.Drawing.Bitmap HTMLToImage(String strHTML)
                {
                    System.Drawing.Bitmap myBitmap = null;
                
                    System.Threading.Thread myThread = new System.Threading.Thread(delegate()
                    {
                        // create a hidden web browser, which will navigate to the page
                        System.Windows.Forms.WebBrowser myWebBrowser = new System.Windows.Forms.WebBrowser();
                        // we don't want scrollbars on our image
                        myWebBrowser.ScrollBarsEnabled = false;
                        // don't let any errors shine through
                        myWebBrowser.ScriptErrorsSuppressed = true;
                        // let's load up that page!    
                        myWebBrowser.Navigate("about:blank");
                
                        // wait until the page is fully loaded
                        while (myWebBrowser.ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete)
                            System.Windows.Forms.Application.DoEvents();
                
                        myWebBrowser.Document.Body.InnerHtml = strHTML;
                
                        // set the size of our web browser to be the same size as the page
                        int intScrollPadding = 20;
                        int intDocumentWidth = myWebBrowser.Document.Body.ScrollRectangle.Width + intScrollPadding;
                        int intDocumentHeight = myWebBrowser.Document.Body.ScrollRectangle.Height + intScrollPadding;
                        myWebBrowser.Width = intDocumentWidth;
                        myWebBrowser.Height = intDocumentHeight;
                        // a bitmap that we will draw to
                        myBitmap = new System.Drawing.Bitmap(intDocumentWidth - intScrollPadding, intDocumentHeight - intScrollPadding);
                        // draw the web browser to the bitmap
                        myWebBrowser.DrawToBitmap(myBitmap, new System.Drawing.Rectangle(0, 0, intDocumentWidth - intScrollPadding, intDocumentHeight - intScrollPadding));
                    });
                    myThread.SetApartmentState(System.Threading.ApartmentState.STA);
                    myThread.Start();
                    myThread.Join();
                
                    return myBitmap;
                }
                

                【讨论】:

                • 我相信这是有史以来最丑陋的做法。真的,谁愿意失去文本可访问性和复制文本的可能性?
                【解决方案22】:

                不久前我也在寻找这个。我遇到了 HTMLDOC http://www.easysw.com/htmldoc/,这是一个免费的开源命令行应用程序,它将 HTML 文件作为参数并从中输出 PDF。对于我的副业项目来说,这对我来说效果很好,但这一切都取决于你实际需要什么。

                制造它的公司出售编译后的二进制文件,但您可以免费下载和编译源代码并免费使用。我设法编译了一个最近的修订版(1.9 版),我打算在几天内发布一个二进制安装程序,所以如果你有兴趣,我可以在发布后立即提供它的链接。

                编辑(2014 年 2 月 25 日):似乎文档和网站已移至 http://www.msweet.org/projects.php?Z1

                【讨论】:

                【解决方案23】:

                大多数 HTML 到 PDF 转换器依赖 IE 来进行 HTML 解析和渲染。当用户更新他们的 IE 时,这可能会中断。 Here 是不依赖 IE 的。

                代码是这样的:

                EO.Pdf.HtmlToPdf.ConvertHtml(htmlText, pdfFileName);
                

                与许多其他转换器一样,您可以传递文本、文件名或 URL。结果可以保存到文件或流中。

                【讨论】:

                • 没用,必须购买库
                • d1jhoni1b,这怎么让它没用?如果它是一种付费工具,那么它可能会被认为是昂贵的,但仅就这一标准而言并非毫无用处。
                • 这是真的 EO.Pdf 不使用 IE。但它似乎确实在后台生成了 32 位 webkit 浏览器实例。检查您的进程列表,您将看到它们是指向 EO.PDF dll 的 rundll32.exe 实例。所以在我看来它仍然有点hacky。
                • 不支持media="print" 真的很痛苦。
                • 650 美元的单一开发者许可。这很昂贵。
                【解决方案24】:

                To convert HTML to PDF in C# use ABCpdf.

                ABCpdf 可以使用 Gecko 或 Trident 渲染引擎,因此您的 HTML 表格看起来与在 FireFox 和 Internet Explorer 中显示的一样。

                在 www.abcpdfeditor.com 上有一个 ABCpdf 的在线演示。您可以使用它来检查您的表格将如何首先呈现,而无需下载和安装软件。

                要渲染整个网页,您需要 AddImageUrl 或 AddImageHtml 函数。但是,如果您只想添加 HTML 样式的文本,那么您可以尝试 AddHtml 函数,如下所示:

                Doc theDoc = new Doc();
                theDoc.FontSize = 72;
                theDoc.AddHtml("<b>Some HTML styled text</b>");
                theDoc.Save(Server.MapPath("docaddhtml.pdf"));
                theDoc.Clear();
                

                ABCpdf 是商业软件名称,但标准版通常可以通过特价免费获得。

                【讨论】:

                • 你真的应该写下你为 websupergoo 工作的所有答案。来自常见问题:However, you must disclose your affiliation with the product in your answers. Also, if a huge percentage of your posts include a mention of your product, you're clearly here for the wrong reasons. 你所有的答案都是关于 ABCpdf
                • 哎哟!我建议使用 ABCpdf,因为它是我熟悉的组件。如果我的大部分帖子都与 PDF 相关,那只是因为我避免为我感兴趣的领域之外的主题做出贡献。道歉。
                • 在海报辩护中,网站确实证明产品相当不错。
                【解决方案25】:

                试试这个 PDF Duo .Net 转换组件来转换HTML to PDF from ASP.NET 应用程序,而无需使用额外的 dll。

                您可以传递 HTML 字符串或文件,或流以生成 PDF。 使用下面的代码(示例 C#):

                string file_html = @"K:\hdoc.html";   
                string file_pdf = @"K:\new.pdf";   
                try   
                {   
                    DuoDimension.HtmlToPdf conv = new DuoDimension.HtmlToPdf();   
                    conv.OpenHTML(file_html);   
                    conv.SavePDF(file_pdf);   
                    textBox4.Text = "C# Example: Converting succeeded";   
                }   
                

                Info + C#/VB 示例,您可以在以下位置找到:http://www.duodimension.com/html_pdf_asp.net/component_html_pdf.aspx

                【讨论】:

                • BitDefender 报告:“检测到恶意软件!访问此页面已被阻止。”。我对这份报告是真的还是假阳性没有意见。
                【解决方案26】:

                这取决于您的任何其他要求。

                一个非常简单但不易部署的解决方案是使用 WebBrowser 控件加载 Html,然后使用 Print 方法打印到本地安装的 PDF 打印机。有几种免费的 PDF 打印机可用,WebBrowser 控件是 .Net 框架的一部分。

                编辑: 如果您的 Html 是 XHtml,您可以使用 PDFizer 来完成这项工作。

                【讨论】:

                  猜你喜欢
                  • 2010-10-31
                  • 2011-09-29
                  • 2010-09-26
                  • 1970-01-01
                  • 2019-03-05
                  • 2011-07-27
                  • 2010-10-12
                  • 2011-02-23
                  相关资源
                  最近更新 更多