跳至頁尾內容
PDF工具

發現2025年最佳PDF刪除軟體

在2026年選擇一個C#函式庫將HTML轉換為PDF的唯一定決策因素是:哪個渲染引擎適合您實際製作的文件。 在.NET 10上,這個領域分成三類。 基於瀏覽器的引擎(通過PuppeteerSharp、Playwright,或嵌入構建的Chromium)能夠準確渲染現代CSS和JavaScript。 程式化的函式庫(iText、PdfSharp)使用自訂解析器繪製PDF,放棄了現代網頁的保真度以換取更小的系統佔用。 程式碼優先布局工具(QuestPDF)完全跳過HTML。 這個比較通過工作中的C#程式碼、評估標準、原始基準測試和決定您可以發送哪些文件的授權條款來介紹每個選項。

簡述:快速回答和最速的工作程式碼

為了準確渲染當前的CSS和JavaScript,請使用瀏覽器級的引擎。免費的方法是PuppeteerSharp或Playwright,它們提供Chrome級的輸出,但需要您管理一個獨立的瀏覽器進程及一個大型的二進制文件。 商業路徑將Chromium嵌入在包內,無需單獨安裝或啟動。 對於簡單靜態文件,一個輕量級的函式庫如PdfSharp就足夠了。 對於沒有HTML來源的程式碼定義布局,QuestPDF是最短的路徑。

使用嵌入引擎到PDF的最快工作路徑是一次渲染調用:

using IronPdf;

// The embedded Chromium engine ships inside the package, so no browser is launched or downloaded
var renderer = new ChromePdfRenderer();
// One synchronous call parses the HTML string and produces an in-memory PDF document
var pdf = renderer.RenderHtmlAsPdf("<h1>Invoice</h1><p>Generated from HTML.</p>");
// Write the rendered document to disk
pdf.SaveAs("output.pdf");
using IronPdf;

// The embedded Chromium engine ships inside the package, so no browser is launched or downloaded
var renderer = new ChromePdfRenderer();
// One synchronous call parses the HTML string and produces an in-memory PDF document
var pdf = renderer.RenderHtmlAsPdf("<h1>Invoice</h1><p>Generated from HTML.</p>");
// Write the rendered document to disk
pdf.SaveAs("output.pdf");
Imports IronPdf

' The embedded Chromium engine ships inside the package, so no browser is launched or downloaded
Dim renderer As New ChromePdfRenderer()
' One synchronous call parses the HTML string and produces an in-memory PDF document
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Invoice</h1><p>Generated from HTML.</p>")
' Write the rendered document to disk
pdf.SaveAs("output.pdf")
$vbLabelText   $csharpLabel

完整的比較、基準測試和授權詳細資訊如下所示。

根據場景的快速推薦表

在閱讀深入研究之前,請將您的限制與選擇匹配。

如果您需要 推薦選擇 為何
現代CSS、Flexbox、Grid、大規模網頁字體 IronPDF(嵌入Chromium) 準確渲染,快速預熱渲染,無需部署外部瀏覽器
免費的瀏覽器級渲染,願意管理運營 PuppeteerSharp或Playwright 真正的Chromium,MIT許可,部署負擔較重
簡單靜態HTML,無JavaScript PdfSharp 配合 HtmlRenderer 輕量級,免費,僅限於遺留CSS
程式化固定布局,無HTML來源 QuestPDF 流暢的C# API,非常快速,不是HTML渲染器
零基礎設施,託管處理 HTML到PDF API 無需在您的應用中維護渲染引擎
遺留項目在wkhtmltopdf上 遷移到Chromium引擎 wkhtmltopdf被歸檔,無法處理當前的CSS,並帶有一個關鍵的SSRF CVE

使HTML到PDF在C#中困難的原因

瀏覽器會為螢幕渲染流體內容; PDF需要固定的頁面,精確的尺寸,以及嚴格的分頁。 這兩種模型之間的差距是函式庫成功或失敗的地方。 五個標準將它們分開,並且它們適用於每個工具,無論供應商如何。

  1. 渲染引擎和現代CSS:解析HTML和CSS的引擎是核心差異化因素。 當前的模板依賴於CSS Flexbox進行對齊、CSS Grid進行二維布局、@font-face進行排版以及SVG進行矢量資產。 使用基於舊WebKit分支或定制解析器的引擎往往在這些方面沉默失敗,並將樣式化布局折疊為垂直堆疊。 在將螢幕布局轉換為紙張布局時,正確處理@media print規則同樣重要。

  2. JavaScript執行和渲染等待:如今許多內容是在客戶端建立的。圖表庫如Chart.js和單頁框架如Blazor WebAssembly在頁面完成之前用JavaScript構建DOM。 沒有JavaScript引擎的函式庫會生成空白圖表或半載入的頁面,這使得執行腳本和等待渲染準備信號的能力對於動態文件是決定性的。

  3. 部署權重和冷啟動:驅動外部無頭瀏覽器的工具下載數百兆字節的二進制文件,這會膨脹容器映像並減慢冷啟動。 在如AWS Lambda或Azure Functions這樣的無伺服器環境中,儲存和記憶體很緊張,容器重量可以決定某個函式庫是否可行。

  4. 授權及其法律範圍:授權規定的不僅僅是成本。在.NET PDF領域,涵蓋了寬鬆的條款(MIT、Apache 2.0)、可能要求披露您對網路面向應用的源程式碼的互壟斷條款(AGPLv3)、收入限制的社群層,以及永久商業許可。 錯誤的選擇可能會在審計時顯示出一個義務。

  5. 性能和大規模記憶體:在控制台測試中正常的函式庫可能在並發的網路API下停滯不前。 一些會流式處理工作; 其他會一次性載入整個文件到記憶體中,並在批處理作業期間觸發垃圾收集暫停。 冷啟動、預熱渲染和每次渲染記憶體是三個需要獨立關注的測量指標。

每個都配有工作程式碼的函式庫

免費和開源的選項首先出現。以下的每段程式碼片段都在.NET 10上編譯並運行,並且Chromium引擎顯示了支持HTML字串和URL輸入,因為它們都支持這兩種格式。

PuppeteerSharp

PuppeteerSharp是谷歌Node.js Puppeteer的.NET移植,首次在2017年發布。它通過Chrome DevTools協議驅動一個無頭的Chromium實例。 它是進程編排器,而不是一個進程內函式庫:應用程式下載帶有BrowserFetcher的Chromium構建,啟動瀏覽器,設置頁面內容並抓取PDF。

using PuppeteerSharp;
using System.Threading.Tasks;

public class PuppeteerExample
{
    public async Task GeneratePdfAsync()
    {
        // Download a matching Chromium build if it is not already present (the 100-300 MB fetch)
        await new BrowserFetcher().DownloadAsync();

        // Start a headless browser process; await using disposes it to avoid orphaned processes
        await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
        // Open a fresh tab to work in
        await using var page = await browser.NewPageAsync();

        // Load the HTML directly into the page instead of navigating to a URL
        await page.SetContentAsync("<h1>Invoice Report</h1><p>Rendered with PuppeteerSharp.</p>");
        // Drive Chrome's print pipeline to emit the PDF file
        await page.PdfAsync("puppeteer_output.pdf");
    }
}
using PuppeteerSharp;
using System.Threading.Tasks;

public class PuppeteerExample
{
    public async Task GeneratePdfAsync()
    {
        // Download a matching Chromium build if it is not already present (the 100-300 MB fetch)
        await new BrowserFetcher().DownloadAsync();

        // Start a headless browser process; await using disposes it to avoid orphaned processes
        await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
        // Open a fresh tab to work in
        await using var page = await browser.NewPageAsync();

        // Load the HTML directly into the page instead of navigating to a URL
        await page.SetContentAsync("<h1>Invoice Report</h1><p>Rendered with PuppeteerSharp.</p>");
        // Drive Chrome's print pipeline to emit the PDF file
        await page.PdfAsync("puppeteer_output.pdf");
    }
}
Imports PuppeteerSharp
Imports System.Threading.Tasks

Public Class PuppeteerExample
    Public Async Function GeneratePdfAsync() As Task
        ' Download a matching Chromium build if it is not already present (the 100-300 MB fetch)
        Await New BrowserFetcher().DownloadAsync()

        ' Start a headless browser process; using disposes it to avoid orphaned processes
        Using browser = Await Puppeteer.LaunchAsync(New LaunchOptions With {.Headless = True})
            ' Open a fresh tab to work in
            Using page = Await browser.NewPageAsync()
                ' Load the HTML directly into the page instead of navigating to a URL
                Await page.SetContentAsync("<h1>Invoice Report</h1><p>Rendered with PuppeteerSharp.</p>")
                ' Drive Chrome's print pipeline to emit the PDF file
                Await page.PdfAsync("puppeteer_output.pdf")
            End Using
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

要抓取實時URL而非字串,請在調用之前導航到它:

// Navigate the tab to a live URL so the loaded page becomes the render source
await page.GoToAsync("https://example.com");
// Capture whatever is currently displayed as a PDF
await page.PdfAsync("from_url.pdf");
// Navigate the tab to a live URL so the loaded page becomes the render source
await page.GoToAsync("https://example.com");
// Capture whatever is currently displayed as a PDF
await page.PdfAsync("from_url.pdf");
Imports System.Threading.Tasks

' Navigate the tab to a live URL so the loaded page becomes the render source
Await page.GoToAsync("https://example.com")
' Capture whatever is currently displayed as a PDF
Await page.PdfAsync("from_url.pdf")
$vbLabelText   $csharpLabel

優勢:

  • 渲染符合Google Chrome,具有完整的Flexbox、Grid和網路字體支持。
  • 執行JavaScript並能在捕獲之前等待網路空閒。
  • MIT許可,因此商業使用不需要互壟斷義務。

限制條件:

  • 首次運行下載100 MB至300 MB的Chromium構建。
  • 每個瀏覽器實例消耗大量記憶體,因此並發批次需要瀏覽器池。
  • 無內建的PDF/A或PDF/UA輸出。

授權:MIT。 當您希望免費獲得Chrome保真度輸出並且團隊可以消化操作開銷時,選擇它。 有關此權衡的專注對比,請參見PuppeteerSharp vs IronPDF對比

編劇for .NET

Playwright由微軟維護,作為Chromium、WebKit和Firefox的跨瀏覽器自動化框架。 團隊通過Page.PdfAsync重用它進行HTML到PDF轉換,雖然PDF生成僅在Chromium上工作。 設置通過一次性安裝步驟獲取瀏覽器二進制文件。

using Microsoft.Playwright;
using System.Threading.Tasks;

public class PlaywrightExample
{
    public async Task GeneratePdfAsync()
    {
        // Create the編劇driver that manages the installed browser binaries
        using var playwright = await Playwright.CreateAsync();
        // PDF output is Chromium-only, so launch the Chromium build specifically
        await using var browser = await playwright.Chromium.LaunchAsync();
        // Open a new page (tab) to render into
        var page = await browser.NewPageAsync();

        // Set the HTML content in place rather than navigating to a URL
        await page.SetContentAsync("<html><body><h1>Sales Dashboard</h1></body></html>");
        // Emit the PDF with an explicit A4 page format
        await page.PdfAsync(new PagePdfOptions { Path = "playwright_output.pdf", Format = "A4" });
    }
}
using Microsoft.Playwright;
using System.Threading.Tasks;

public class PlaywrightExample
{
    public async Task GeneratePdfAsync()
    {
        // Create the編劇driver that manages the installed browser binaries
        using var playwright = await Playwright.CreateAsync();
        // PDF output is Chromium-only, so launch the Chromium build specifically
        await using var browser = await playwright.Chromium.LaunchAsync();
        // Open a new page (tab) to render into
        var page = await browser.NewPageAsync();

        // Set the HTML content in place rather than navigating to a URL
        await page.SetContentAsync("<html><body><h1>Sales Dashboard</h1></body></html>");
        // Emit the PDF with an explicit A4 page format
        await page.PdfAsync(new PagePdfOptions { Path = "playwright_output.pdf", Format = "A4" });
    }
}
Imports Microsoft.Playwright
Imports System.Threading.Tasks

Public Class PlaywrightExample
    Public Async Function GeneratePdfAsync() As Task
        ' Create the Playwright driver that manages the installed browser binaries
        Using playwright = Await Playwright.CreateAsync()
            ' PDF output is Chromium-only, so launch the Chromium build specifically
            Await Using browser = Await playwright.Chromium.LaunchAsync()
                ' Open a new page (tab) to render into
                Dim page = Await browser.NewPageAsync()

                ' Set the HTML content in place rather than navigating to a URL
                Await page.SetContentAsync("<html><body><h1>Sales Dashboard</h1></body></html>")
                ' Emit the PDF with an explicit A4 page format
                Await page.PdfAsync(New PagePdfOptions With {.Path = "playwright_output.pdf", .Format = "A4"})
            End Using
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

在首次運行之前,通過pwsh bin/Debug/net10.0/playwright.ps1 install chromium安裝瀏覽器(或在程式碼中調用等效的安裝入口)。

對於實時URL,請先導航到該頁面:

// Load a live URL so its rendered DOM becomes the PDF source
await page.GotoAsync("https://example.com");
// Export the loaded page as an A4 PDF
await page.PdfAsync(new PagePdfOptions { Path = "from_url.pdf", Format = "A4" });
// Load a live URL so its rendered DOM becomes the PDF source
await page.GotoAsync("https://example.com");
// Export the loaded page as an A4 PDF
await page.PdfAsync(new PagePdfOptions { Path = "from_url.pdf", Format = "A4" });
Imports System.Threading.Tasks

' Load a live URL so its rendered DOM becomes the PDF source
Await page.GotoAsync("https://example.com")
' Export the loaded page as an A4 PDF
Await page.PdfAsync(New PagePdfOptions With {.Path = "from_url.pdf", .Format = "A4"})
$vbLabelText   $csharpLabel

其最優之處:

  • 由微軟支持,具有活躍的發布周期。
  • 一旦瀏覽器啟動,首次渲染延遲低。
  • 準確渲染現代網頁標準和客戶端JavaScript。

陷阱:

  • 與PuppeteerSharp一樣,二進制文件負擔重且需要瀏覽器管理。
  • 如果不仔細處理瀏覽器上下文,記憶體會上升。
  • PDF輸出是Chrome列印流水線的側功能,因此缺乏文件操作功能。

授權:MIT。 當一個項目已經運行Playwright進行測試並希望免費渲染時,這是理想選擇。

wkhtmltopdf(通過DinkToPdf)

十多年來,wkhtmltopdf是預設的HTML到PDF工具。 在.NET中,通常通過DinkToPdf消費,這是對本機libwkhtmltox庫的C#包裝。 包裝的API很乾淨,但下面的引擎是問題所在。

using DinkToPdf;

public class DinkToPdfExample
{
    public void GeneratePdf()
    {
        // SynchronizedConverter serializes calls into the non-thread-safe native libwkhtmltox library
        var converter = new SynchronizedConverter(new PdfTools());

        // Describe the document: global page settings plus one or more HTML content objects
        var doc = new HtmlToPdfDocument
        {
            // Set the paper size and the output file path for the whole document
            GlobalSettings = { PaperSize = PaperKind.A4, Out = "legacy_output.pdf" },
            // Each object is a chunk of HTML to render into the PDF
            Objects = { new ObjectSettings { HtmlContent = "<h1>Legacy Report</h1>" } }
        };

        // Hand the descriptor to the native engine, which writes the file defined in Out
        converter.Convert(doc);
    }
}
using DinkToPdf;

public class DinkToPdfExample
{
    public void GeneratePdf()
    {
        // SynchronizedConverter serializes calls into the non-thread-safe native libwkhtmltox library
        var converter = new SynchronizedConverter(new PdfTools());

        // Describe the document: global page settings plus one or more HTML content objects
        var doc = new HtmlToPdfDocument
        {
            // Set the paper size and the output file path for the whole document
            GlobalSettings = { PaperSize = PaperKind.A4, Out = "legacy_output.pdf" },
            // Each object is a chunk of HTML to render into the PDF
            Objects = { new ObjectSettings { HtmlContent = "<h1>Legacy Report</h1>" } }
        };

        // Hand the descriptor to the native engine, which writes the file defined in Out
        converter.Convert(doc);
    }
}
Imports DinkToPdf

Public Class DinkToPdfExample
    Public Sub GeneratePdf()
        ' SynchronizedConverter serializes calls into the non-thread-safe native libwkhtmltox library
        Dim converter = New SynchronizedConverter(New PdfTools())

        ' Describe the document: global page settings plus one or more HTML content objects
        Dim doc = New HtmlToPdfDocument With {
            ' Set the paper size and the output file path for the whole document
            .GlobalSettings = New GlobalSettings With {.PaperSize = PaperKind.A4, .Out = "legacy_output.pdf"},
            ' Each object is a chunk of HTML to render into the PDF
            .Objects = {New ObjectSettings With {.HtmlContent = "<h1>Legacy Report</h1>"}}
        }

        ' Hand the descriptor to the native engine, which writes the file defined in Out
        converter.Convert(doc)
    End Sub
End Class
$vbLabelText   $csharpLabel

這段程式碼編譯,但在清潔機器上運行時會出現System.DllNotFoundException: Unable to load DLL 'libwkhtmltox',直到本機二進制文件被複製到輸出目錄。 那一步本機依賴是這個引擎帶來的部署摩擦的第一個跡象。

優勢:

  • 冷啟動速度快,沒有現代瀏覽器需要初始化。
  • 記憶體低,約50 MB每次渲染。

劣勢:

  • 它發送的QtWebKit引擎(大約是2012-2013的WebKit快照,而Qt自2015年棄用並於2016年移除)無法渲染Flexbox、Grid或現代JavaScript。
  • wkhtmltopdf資料庫在2023年1月2日被歸檔,最後一次釋出,0.12.6,追溯到2020年6月。
  • 它帶有CVE-2022-35583,一個評為9.8(危急)的伺服器端請求偽造漏洞,由於該項目不再維護而未修補。

授權:DinkToPdf本身是MIT,但它連結到LGPLv3的wkhtmltopdf二進制文件,所以實際的義務來自wkhtmltopdf。 適合遺留流程待遷移,保持安全風險在視野中。 查看wkhtmltopdf vs IronPDF對比以獲得完整的遷移圖片。

PdfSharp and HtmlRenderer

PdfSharp是一個廣泛使用的開源庫,但一個常見的誤解是它可以自行轉換HTML。 它不會。 PdfSharp提供了一個低級的,以座標為基礎的繪制API。 要轉換HTML,您需要配合社區橋HtmlRenderer.PdfSharp,它解析HTML並發出PdfSharp繪圖命令。

using PdfSharp;
using TheArtOfDev.HtmlRenderer.PdfSharp;

public class PdfSharpExample
{
    public void GeneratePdf()
    {
        string html = "<h1>Simple Title</h1><p>Statically rendered text.</p>";

        // The HtmlRenderer bridge parses the HTML and emits PdfSharp drawing commands onto an A4 page
        var pdf = PdfGenerator.GeneratePdf(html, PageSize.A4);
        // Persist the resulting PdfSharp document to disk
        pdf.Save("simple_document.pdf");
    }
}
using PdfSharp;
using TheArtOfDev.HtmlRenderer.PdfSharp;

public class PdfSharpExample
{
    public void GeneratePdf()
    {
        string html = "<h1>Simple Title</h1><p>Statically rendered text.</p>";

        // The HtmlRenderer bridge parses the HTML and emits PdfSharp drawing commands onto an A4 page
        var pdf = PdfGenerator.GeneratePdf(html, PageSize.A4);
        // Persist the resulting PdfSharp document to disk
        pdf.Save("simple_document.pdf");
    }
}
Imports PdfSharp
Imports TheArtOfDev.HtmlRenderer.PdfSharp

Public Class PdfSharpExample
    Public Sub GeneratePdf()
        Dim html As String = "<h1>Simple Title</h1><p>Statically rendered text.</p>"

        ' The HtmlRenderer bridge parses the HTML and emits PdfSharp drawing commands onto an A4 page
        Dim pdf = PdfGenerator.GeneratePdf(html, PageSize.A4)
        ' Persist the resulting PdfSharp document to disk
        pdf.Save("simple_document.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

在.NET 10上有兩個設置細節很重要。這個橋期望Windows-1252程式碼頁,這在現代.NET上預設缺失,所以在啟動時用Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)註冊一次。 將這個橋配合新的PdfSharp 6.x包在運行時會報MissingMethodException,所以讓HtmlRenderer拉取其自身相容的PdfSharp而不是鎖定最新的。

有效:

  • 真正寬鬆的MIT許可,無收入限制。
  • 輕量級,無本機二進制文件或瀏覽器下載者。
  • 純C#,所以跨操作系統的部署是直接的。

中斷點:

  • HTML橋大約限於HTML 4.01和CSS Level 2,而它在經歷了九年的休眠之後,僅在2025年下半年的發行集中發行了一套。
  • 完全不支援JavaScript執行。
  • 印刷規則如page-break-inside: avoid不支援,因此表格行橫跨頁面分裂。

授權:PdfSharp MIT,HtmlRenderer BSD-3-Clause。 對於沒有複雜布局的簡單靜態文件,這是正確的選擇。 若想要逐功能分解,請參見PdfSharp vs IronPDF對比

QuestPDF

QuestPDF走的是不同的路徑:它拋棄HTML,通過流暢的API在C#中定義布局。 對於來自物件而非標記的資料,它取消了只為了再次解析而生成HTML這一步。

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

public class QuestPdfExample
{
    public void GeneratePdf()
    {
        // The revenue-gated license tier must be declared before any document is built
        QuestPDF.Settings.License = LicenseType.Community;

        // Compose the layout in C# through the fluent API; no HTML anywhere
        var document = Document.Create(container =>
        {
            container.Page(page =>
            {
                // Define the physical page size and margins
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                // Place content into named page regions (header and body)
                page.Header().Text("Programmatic Invoice").FontSize(24);
                page.Content().Text("This document is generated without HTML.");
            });
        });

        // Run the layout engine and write the composed document to a file
        document.GeneratePdf("fluent_layout.pdf");
    }
}
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

public class QuestPdfExample
{
    public void GeneratePdf()
    {
        // The revenue-gated license tier must be declared before any document is built
        QuestPDF.Settings.License = LicenseType.Community;

        // Compose the layout in C# through the fluent API; no HTML anywhere
        var document = Document.Create(container =>
        {
            container.Page(page =>
            {
                // Define the physical page size and margins
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                // Place content into named page regions (header and body)
                page.Header().Text("Programmatic Invoice").FontSize(24);
                page.Content().Text("This document is generated without HTML.");
            });
        });

        // Run the layout engine and write the composed document to a file
        document.GeneratePdf("fluent_layout.pdf");
    }
}
Imports QuestPDF.Fluent
Imports QuestPDF.Helpers
Imports QuestPDF.Infrastructure

Public Class QuestPdfExample
    Public Sub GeneratePdf()
        ' The revenue-gated license tier must be declared before any document is built
        QuestPDF.Settings.License = LicenseType.Community

        ' Compose the layout in VB.NET through the fluent API; no HTML anywhere
        Dim document = Document.Create(Sub(container)
                                           container.Page(Sub(page)
                                                              ' Define the physical page size and margins
                                                              page.Size(PageSizes.A4)
                                                              page.Margin(2, Unit.Centimetre)
                                                              ' Place content into named page regions (header and body)
                                                              page.Header().Text("Programmatic Invoice").FontSize(24)
                                                              page.Content().Text("This document is generated without HTML.")
                                                          End Sub)
                                       End Sub)

        ' Run the layout engine and write the composed document to a file
        document.GeneratePdf("fluent_layout.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

優點:

  • 因為它跳過了DOM解析和瀏覽器布局,所以非常快。
  • 具有可預測、線性的記憶體,適合高吞吐量的批次作業。
  • 有一個伴隨應用程式在設計期間提供實時預覽和熱重新載入。

劣勢:

  • 它是一個布局引擎,不是HTML渲染器,所以不能轉換URL或現有的HTML模板。
  • 現有的HTML或Razor文件需要完全重寫為流暢的API。
  • 授權從MIT轉向收入限制的模型。

授權:社群授權(對於年收入低於100萬美元的企業免費)或付費專業和企業層。 適合由結構化資料驅動的程式碼定義、固定布局文件。 查看QuestPDF vs IronPDF對比了解HTML與流暢布局的權衡。

iText(pdfHTML)

iText 7和8因程式化的PDF操作而聞名,而pdfHTML附加功能轉換HTML。 與Chromium工具不同,pdfHTML使用自訂解析器,將HTML標籤映射到iText物件而不是運行瀏覽器。

using iText.Html2pdf;
using System.IO;

public class iTextExample
{
    public void GeneratePdf()
    {
        string html = "<h1>Report</h1><p>Converted with pdfHTML.</p>";

        // Open the destination stream; using ensures the file handle is released after writing
        using var dest = File.Create("output.pdf");
        // pdfHTML maps the HTML tags to iText objects and writes them to the stream (no browser involved)
        HtmlConverter.ConvertToPdf(html, dest);
    }
}
using iText.Html2pdf;
using System.IO;

public class iTextExample
{
    public void GeneratePdf()
    {
        string html = "<h1>Report</h1><p>Converted with pdfHTML.</p>";

        // Open the destination stream; using ensures the file handle is released after writing
        using var dest = File.Create("output.pdf");
        // pdfHTML maps the HTML tags to iText objects and writes them to the stream (no browser involved)
        HtmlConverter.ConvertToPdf(html, dest);
    }
}
Imports iText.Html2pdf
Imports System.IO

Public Class iTextExample
    Public Sub GeneratePdf()
        Dim html As String = "<h1>Report</h1><p>Converted with pdfHTML.</p>"

        ' Open the destination stream; using ensures the file handle is released after writing
        Using dest As FileStream = File.Create("output.pdf")
            ' pdfHTML maps the HTML tags to iText objects and writes them to the stream (no browser involved)
            HtmlConverter.ConvertToPdf(html, dest)
        End Using
    End Sub
End Class
$vbLabelText   $csharpLabel

在一個新的專案上這會拋出,直到您新增itext7.bouncy-castle-adapter包,這是iText在其加密路徑中的必要條件。 那個額外的依賴很容易被忽略,如果沒有它會產生一個不透明的錯誤。

優勢:

  • 深入的PDF操作、簽名和在iText生態系統中的修正。
  • 從語義HTML生成PDF/A和PDF/UA,適合合規工作。
  • 快速啟動時間,因為它不啟動瀏覽器。

缺點:

  • 無腳本執行,所以動態內容不渲染。
  • CSS3功能如Grid不支持並靜默失敗。
  • AGPLv3許可要求封閉源應用的商業許可,大文件被完全緩衝而不是流式。

授權: AGPLv3或商業。 用於重度PDF操作和具有控制、靜態HTML的合規工作流程。 有關授權和操作詳細資訊,請參見iText 7 vs IronPDF對比

IronPDF

IronPDF將Chromium引擎嵌入到其NuGet包中,並通過C# API曝露它,因此不需要啟動或池外部的任何東西。 它夾在免費的瀏覽器工具和程式化的函式庫之間,交易一個許可成本來獲得渲染保真度,不需要管理瀏覽器。

using IronPdf;
using System.Threading.Tasks;

public class IronPdfExample
{
    public async Task GeneratePdfAsync()
    {
        // Create the in-process Chromium renderer (no external browser to launch)
        var renderer = new ChromePdfRenderer();
        // Turn on theJavaScriptengine so client-side chart scripts execute before capture
        renderer.RenderingOptions.EnableJavaScript = true;
        // Wait 500 ms after load to let JavaScript-built content settle before rendering
        renderer.RenderingOptions.WaitFor.RenderDelay(500);

        // Render the HTML string asynchronously into an in-memory PDF
        var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Quarterly Report</h1><div class='chart'></div>");
        // Save the finished PDF to disk
        pdf.SaveAs("report.pdf");
    }
}
using IronPdf;
using System.Threading.Tasks;

public class IronPdfExample
{
    public async Task GeneratePdfAsync()
    {
        // Create the in-process Chromium renderer (no external browser to launch)
        var renderer = new ChromePdfRenderer();
        // Turn on theJavaScriptengine so client-side chart scripts execute before capture
        renderer.RenderingOptions.EnableJavaScript = true;
        // Wait 500 ms after load to let JavaScript-built content settle before rendering
        renderer.RenderingOptions.WaitFor.RenderDelay(500);

        // Render the HTML string asynchronously into an in-memory PDF
        var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Quarterly Report</h1><div class='chart'></div>");
        // Save the finished PDF to disk
        pdf.SaveAs("report.pdf");
    }
}
Imports IronPdf
Imports System.Threading.Tasks

Public Class IronPdfExample
    Public Async Function GeneratePdfAsync() As Task
        ' Create the in-process Chromium renderer (no external browser to launch)
        Dim renderer As New ChromePdfRenderer()
        ' Turn on the JavaScript engine so client-side chart scripts execute before capture
        renderer.RenderingOptions.EnableJavaScript = True
        ' Wait 500 ms after load to let JavaScript-built content settle before rendering
        renderer.RenderingOptions.WaitFor.RenderDelay(500)

        ' Render the HTML string asynchronously into an in-memory PDF
        Dim pdf = Await renderer.RenderHtmlAsPdfAsync("<h1>Quarterly Report</h1><div class='chart'></div>")
        ' Save the finished PDF to disk
        pdf.SaveAs("report.pdf")
    End Function
End Class
$vbLabelText   $csharpLabel

同一渲染器只需一次調用便可將URL轉換為PDF

// RenderUrlAsPdf fetches and renders the live page in one call, no navigation step needed
var fromUrl = new ChromePdfRenderer().RenderUrlAsPdf("https://example.com");
// Write the captured page to disk
fromUrl.SaveAs("from_url.pdf");
// RenderUrlAsPdf fetches and renders the live page in one call, no navigation step needed
var fromUrl = new ChromePdfRenderer().RenderUrlAsPdf("https://example.com");
// Write the captured page to disk
fromUrl.SaveAs("from_url.pdf");
' RenderUrlAsPdf fetches and renders the live page in one call, no navigation step needed
Dim fromUrl = (New ChromePdfRenderer()).RenderUrlAsPdf("https://example.com")
' Write the captured page to disk
fromUrl.SaveAs("from_url.pdf")
$vbLabelText   $csharpLabel

它還能將Razor和MVC視圖渲染成PDF並直接轉換HTML文件。 完整的功能介紹位於HTML to PDF教程

優點:

  • 瀏覽器級的渲染,處理Grid、Flexbox和客戶端腳本。
  • 無需外部可執行文件或瀏覽器池的部署。
  • 生成PDF/A並應用數位簽章,這將它與測試框架分開。

缺點:

  • 需要商業許可,無免費的生產層。
  • 在新的部署後,首次渲染承擔一次性初始化成本,然後後續渲染穩定在快速的預熱路徑上。

授權:商業,永久。 在大批量重要的當前CSS的地方使用它,優先提高操作開銷的同時保持高保真度。

完整比較表格

每個函式庫一行,包括授權列,因為它直接驅使免費與付費的決定。

圖書館 引擎 JavaScript 現代 CSS 部署權重 許可證 最適合
IronPDF 嵌入式Chromium 全文 輕量級(NuGet) 商業的 大規模現代CSS
PuppeteerSharp 外部Chromium 全文 重量級(二進制下載) 免費瀏覽器渲染
編劇 外部Chromium 全文 重量級(二進制下載) 現代免費渲染
wkhtmltopdf 舊QtWebKit 限額 中等(本機庫) LGPLv3(包裝者MIT) 遺留工作流程
PdfSharp + HtmlRenderer 自定繪圖 限額 輕量級 和 / BSD-3 簡單靜態HTML
QuestPDF 程式化 不適用 不適用 輕量級 社區 / 付費 程式碼定義布局
iText pdfHTML 自訂解析器 限額 語言 AGPLv3 / 商業 PDF 操作

在整合前檢查每個函式庫的當前發行版本中的每個單元格,因為許可和引擎支持會改變。

免費與付費:何時是正確的選擇

被標稱為"免費"的工具可以在.NET PDF領域隱藏操作和法律成本,因此命名在什麼情況下使用免費工具是正確的選擇是誠實的起點。

對於簡單、靜態文件、低量或擁有管理外部過程能力的團隊,免費的開源函式庫確實足夠。 一個文字繁重的收據,沒有精緻的樣式,可以用MIT許可的PdfSharp順利渲染。當團隊已經為測試運行了Playwright並且解決了容器化問題,偶爾的PDF工作可以高效地重用它。

免費軟體不等於免費實施。 開放源程式碼無頭瀏覽器的隱藏成本顯現在維護時間上:迴圈瀏覽器生命週期以防止伺服器在負載下崩潰、配置Linux共享庫依賴跨容器映像,以及吸收沉重瀏覽器進程的基礎設施成本。 對於簡單的靜態文件,付費的瀏覽器引擎有點過頭,一個輕量級的免費函式庫是更好的選擇。

當工作需要大批量準確的CSS3、可存取的PDF/UA輸出和部署簡單性而超過採購成本時,商業的Chromium庫就變得有必要了。商業授權還能去除互鎖曝光。 將像iText這樣的AGPLv3庫新增到SaaS平台可以使公司承擔釋放其源程式碼的義務,除非購買商業許可。 真正的比較是所有權的總成本:一方面是操作時間和法律風險,另一方面是許可費用。

基準測試

以下每個數字均來自在一台機器上的實際運行,因此將它們視為方向性。 測試文件是使用CSS Grid在頁頭和內聯JavaScript條形圖的30行發票。 測試在標準的Windows工作站上運行在.NET 10。每個預熱數字是首次後的八次渲染的平均值,峰值記憶體是.NET進程及其生成的任何瀏覽器子進程的峰值工作集。

圖書館 冷啟動(每次進程) 預熱渲染(8次平均) 峰值記憶體
IronPDF 345毫秒 202毫秒 406 MB
PuppeteerSharp 746毫秒 204毫秒 611 MB
編劇 588毫秒 132毫秒 515 MB
wkhtmltopdf,iText,PdfSharp sub-second not comparable 50到120 MB

一旦預熱,三個瀏覽器引擎大約在130到200毫秒內渲染同一文件,在這次運行中Playwright速度最快,IronPDF和PuppeteerSharp緊隨其後。 在冷啟動時,嵌入引擎在此處啟動最快,因為它在進程內運行,無需啟動單獨的瀏覽器,儘管在全新部署後的首次渲染吸收了單次的引擎初始化成本,後續的進程啟動則避免了這一點。遺留的和自訂解析器工具(wkhtmltopdf,iText,PdfSharp)在一秒內啟動並使用最少的記憶體,但對於測試文件來說這個優勢是多餘的,因為它們無法正確渲染其Grid佈局或其JavaScript圖表。 wkhtmltopdf在不先提供本機二進制文件的情況下根本無法運行。

輸出中顯示出保真度的差距。 瀏覽器引擎渲染CSS Grid頁頭、樣式化表格和JavaScript條形圖:

由Chromium引擎生成的測試發票,具有CSS Grid頁頭、樣式化表格和JavaScript條形圖都存在

同一文件通過PdfSharp配合HtmlRenderer,漏掉了Grid頁頭、表頭樣式化和JavaScript圖表:

由PdfSharp配合HtmlRenderer生成的同一發票,缺少CSS Grid頁頭和JavaScript圖表

您應該使用哪一個?

對每個常見情景的簡要判定:

  • CSS框架和單頁輸出:只有瀏覽器級的渲染器能跟上。
  • 簡單靜態HTML或文字收據:PdfSharp和一個小型免費堆疊可以涵蓋。
  • 程式化的、資料驅動的布局,沒有標記:QuestPDF最快到達。
  • 擁有操作容量的免費瀏覽器渲染:PuppeteerSharp或Playwright。
  • 零基礎設施:一個託管的HTML到PDF API。
  • 遺留wkhtmltopdf遷移:為安全性和CSS支持遷移到嵌入引擎。

當重型CSS框架輸出滿足低操作需求時,IronPDF是首先值得考慮的嵌入選項,而免費的瀏覽器工具則對於能夠掌握無頭瀏覽器操作的團隊來說仍然是正確的選擇。

部署考慮

.NET文件生成中最大的摩擦是運行在Windows筆記本電腦上的函式庫和在Linux容器中失敗的函式庫之間的差距。 選擇一個函式庫意味著預測它何時發送。

在Docker中,像PuppeteerSharp和Playwright這樣的編排瀏覽器需要一個承載Chromium的Linux依賴的基本映像,包括libgbm1。 微軟在mcr.microsoft.com/playwright/dotnet發布了Playwright .NET映像(例如,一個v1.NN.0-noble標籤)來涵蓋這些,這些映像運行接近一GB。 嵌入引擎通過發送按結構打包的NuGet套件,如apt-get步驟。

AWS Lambda提出了不同的限制。 它在解壓的部署包上實行250 MB的硬限制,但一個無頭的Chromium構建本身運行150 MB到300 MB。 這使得標準的PuppeteerSharp或Playwright的zip部署變得不切實際,並將團隊推向基於容器的Lambda,這允許最多10 GB,代價是更差的冷啟動。

Azure應用服務在操作系統上增加了自身的約束。 Windows應用服務沙箱阻止大多數User32和GDI32調用,從而破壞依賴GDI的渲染路徑。 在Linux應用服務上部署DinkToPdf意味著將未管理的libxrender1; 缺少一個會顯示為不透明的System.DllNotFoundException。 這些是驗證運行重現的相同本機依賴和沙箱問題。

結論和建議

在.NET 10上,C#的HTML到PDF領域獎勵將工具與文件匹配。 完整的瀏覽器引擎是CSS框架和響應式布局及JavaScript驅動頁面的基線,而免費與商業之間的分歧實際上是操作工作量與許可成本之間的分歧。程式化的庫對於固定的、靜態的布局仍然高效,而當輸入是結構化資料而不是標記時,QuestPDF是最快的路徑。wkhtmltopdf只應該在遷移計劃中考慮,因為它的引擎被歸檔且未修補的SSRF漏洞。 對於想要準確渲染又不太操心操作開銷的團隊來說,IronPDF是預設的嵌入選擇,具有URL到PDFRazor視圖渲染PDF/A輸出數位簽章都從同一API可用,而PuppeteerSharp和Playwright則在團隊可以掌握瀏覽器生命週期的地方仍然是強勢的免費選擇。

在您自己的HTML上試試看

如果準確渲染且輕量運輸成本適合您的項目,您可以開始免費的IronPDF試用並在您自己的模板上運行相同的測試發票,然後再做出承諾。 IronPDF由Iron Software建造,其.NET函式庫還涵蓋OCR、條形碼、Word和Excel。

感謝您的閱讀。 無論您選擇哪個函式庫,請將其與您面前的文件匹配。

請注意IronPDF是Iron Software的產品。 PuppeteerSharp、Playwright、wkhtmltopdf、DinkToPdf、PdfSharp、HtmlRenderer、QuestPDF和iText是各自擁有者的項目或商標。 此文章未與這些項目有聯繫、經這些項目的認可或由這些項目贊助。 比較反映了在撰寫時的公開資訊和實際測試結果; 在依賴之前,請驗證當前的授權和發行詳細資訊。

常見問題

What are the main types of C# HTML to PDF libraries available for .NET 10 in 2026?

The main types of C# HTML to PDF libraries for .NET 10 in 2026 include browser-based engines like Chromium using PuppeteerSharp or Playwright, programmatic libraries such as iText and PdfSharp, and code-first layout tools like QuestPDF.

How do browser-based engines compare to programmatic libraries for HTML to PDF conversion?

Browser-based engines render modern CSS and JavaScript accurately, providing high fidelity to web standards, whereas programmatic libraries like iText and PdfSharp trade some web fidelity for a smaller footprint by drawing PDFs from custom parsers.

What advantages do code-first layout tools offer over traditional HTML to PDF methods?

Code-first layout tools like QuestPDF allow developers to skip HTML entirely, often resulting in more efficient and customizable PDF generation tailored to specific application needs.

Why is choosing the right rendering engine important for HTML to PDF conversion?

Choosing the right rendering engine is crucial because it determines how accurately your documents are rendered, especially in terms of modern CSS and JavaScript fidelity, which is important for maintaining the visual integrity of your PDFs.

What role do licensing terms play in selecting a C# HTML to PDF library?

Licensing terms are important as they dictate what you can legally do with the library, such as distributing the software commercially, and can affect the overall cost and feasibility of using the library in your projects.

Are there free options available for C# HTML to PDF conversion?

Yes, there are free options available, though they may come with limitations in terms of features and support compared to paid alternatives. It's important to weigh these against your project needs.

How do benchmarks help in evaluating C# HTML to PDF libraries?

Benchmarks provide a quantitative measure of performance, allowing developers to compare libraries based on speed, resource usage, and output quality, helping in making an informed decision.

What is the significance of runnable code examples in library comparisons?

Runnable code examples are significant as they allow developers to test libraries in real-world scenarios, providing insights into ease of use, integration complexity, and how well a library fits specific project requirements.

Can IronPDF be a suitable option for HTML to PDF conversion in .NET 10?

Yes, IronPDF is a suitable option, known for its ease of use, comprehensive features, and support for modern web standards, making it a strong contender for HTML to PDF conversion in .NET 10.

Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話