比較

PuppeteerSharp與IronPDF:技術比較指南

當.NET開發者需要將HTML轉換為PDF時,有幾個基於舊版渲染引擎的封裝程式庫茁壯生存,成為選項。 TuesPechkin就是這樣的一種解決方案,包裝wkhtmltopdf程式庫以提供PDF生成功能。 這項技術比較分析TuesPechkin與IronPDF,以便架構師和開發者了解在舊版封裝與現代PDF程式庫之間的取捨。

了解TuesPechkin

TuesPechkin是一個環繞wkhtmltopdf程式庫的執行緒安全封裝,旨在幫助開發者從HTML內容生成PDF文件。 這個程式庫試圖通過提供ThreadSafeConverter實現來解決wkhtmltopdf固有的併發挑戰。

然而,TuesPechkin從其底層技術繼承了根本的限制:

  • 被遺棄的基礎: TuesPechkin包裝了wkhtmltopdf,該程式庫最後一次更新是在2015年,並在2022年12月正式被遺棄。
  • 過時的渲染引擎: 使用了Qt WebKit 4.8,一個在Chrome時代前的渲染引擎。
  • 複雜的執行緒管理: 需要開發者手動通過RemotingToolset和部署模式來配置執行緒安全。
  • 負載下的穩定性: 即便有執行緒安全配置,該程式庫在高併發情況下可能會崩潰以AccessViolationException或進程掛起。
  • 有限的CSS支援: 不支援現代CSS功能,如Flexbox或CSS Grid。
  • JavaScript的限制: JavaScript執行不可靠,不支持ES6+。

安全考量

TuesPechkin繼承了來自wkhtmltopdf的所有安全漏洞。 CVE-2022-35583,評分9.8/10,代表一個伺服器端請求偽造漏洞,影響所有TuesPechkin版本。 由於wkhtmltopdf已被遺棄,這個漏洞永遠不會被修補,這意味著使用TuesPechkin的應用程式將永久暴露。

了解IronPDF

IronPDF採取了一種根本不同的方法,通過提供一個現代化的商業PDF程式庫,具備內建的執行緒安全和基於Chromium的渲染引擎。與其說是包裝舊版工具,IronPDF將PDF生成作為其主要焦點。

IronPDF的關鍵特性包括:

  • 現代Chromium引擎: 支持HTML5、CSS3、Flexbox、CSS Grid和ES6+ JavaScript。
  • 內建的執行緒安全: 不需要手動執行緒管理——併發操作自動運行。
  • 主動開發: 每週更新和持續改進。
  • 全面的PDF特性: 除了生成,還包括操作、數位簽名、PDF/A合規性和表單填寫。
  • 簡單的整合: 無需本機二進位部署的簡單NuGet安裝。

功能比較

下表突顯了TuesPechkin和IronPDF之間的技術差異:

功能TuesPechkinIronPDF
授權免費(MIT許可證)商業
執行緒安全性需要手動管理本機支援
併發性有限,在負載下可能崩潰強大,能處理高併發
開發狀態非活動的,最後更新於2015年積極進行,不斷改進
易用性複雜的設置使用者友好,有指南
文件基本廣泛的範例
渲染引擎Qt WebKit 4.8(過時)現代Chromium
CSS3 支持部分支持支持
Flexbox/網格不支持支持
JavaScript不可靠完整的ES6+
PDF 操作不可用支持
數位簽名不可用支持
PDF/A合規性不可用支持
表格填寫不可用支持
水印不可用支持
合併/分割不可用支持
頁眉/頁腳僅基本文字完整HTML支持
安全補丁從未(被遺棄)定期更新

API 架構差異

當檢查初始化模式和基本使用時,TuesPechkin和IronPDF的架構差異立即顯而易見。

TuesPechkin的初始化複雜性

TuesPechkin需要複雜的初始化儀式,涉及轉換器、工具組和部署配置:

// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Hello World</h1></body></html>";
        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = { new ObjectSettings { HtmlText = html } }
        });

        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Hello World</h1></body></html>";
        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = { new ObjectSettings { HtmlText = html } }
        });

        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}
Imports TuesPechkin
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter = New StandardConverter(
            New RemotingToolset(Of PdfToolset)(
                New Win64EmbeddedDeployment(
                    New TempFolderDeployment())))

        Dim html As String = "<html><body><h1>Hello World</h1></body></html>"
        Dim pdfBytes As Byte() = converter.Convert(New HtmlToPdfDocument With {
            .Objects = {New ObjectSettings With {.HtmlText = html}}
        })

        File.WriteAllBytes("output.pdf", pdfBytes)
    End Sub
End Class
$vbLabelText   $csharpLabel

此模式需要了解多個巢狀類別:TempFolderDeployment。 部署配置還必須匹配目標平台架構(x86/x64)。

IronPDF簡化方法

IronPDF以簡單的API完全消除了部署的複雜性:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        string html = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        string html = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("output.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()

        Dim html As String = "<html><body><h1>Hello World</h1></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(html)

        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

ChromePdfRenderer類提供了立即存取PDF生成的功能,無需特定於平台的配置。 有關全面的HTML轉換指導,請參見HTML轉PDF教程

URL 轉 PDF

將網頁轉換為PDF文件展示了兩個程式庫之間API的可用性差異。

TuesPechkin實施

TuesPechkin在PageUrl屬性指定URL:

// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = {
                new ObjectSettings {
                    PageUrl = "https://www.example.com"
                }
            }
        });

        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = {
                new ObjectSettings {
                    PageUrl = "https://www.example.com"
                }
            }
        });

        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}
Imports TuesPechkin
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter = New StandardConverter(
            New RemotingToolset(Of PdfToolset)(
                New Win64EmbeddedDeployment(
                    New TempFolderDeployment())))

        Dim pdfBytes As Byte() = converter.Convert(New HtmlToPdfDocument With {
            .Objects = {
                New ObjectSettings With {
                    .PageUrl = "https://www.example.com"
                }
            }
        })

        File.WriteAllBytes("webpage.pdf", pdfBytes)
    End Sub
End Class
$vbLabelText   $csharpLabel

相同的初始化複雜性適用,由於缺少CSS3和JavaScript支持,過時的WebKit引擎可能會錯誤地渲染現代網站。

IronPDF實施

IronPDF為URL渲染提供了一個專用的方法,配合其現代Chromium引擎:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()

        Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")

        pdf.SaveAs("webpage.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

RenderUrlAsPdf方法將頁面載入到無頭Chromium瀏覽器中,正確執行JavaScript並應用所有現代CSS樣式。 這對於使用React、Angular或Vue.js等框架構建的Web應用程式至關重要,而TuesPechkin無法正確渲染這些應用程式。

自訂渲染設置

配置頁面尺寸、邊距和方向揭示了不同的文件設置方式。

TuesPechkin配置

TuesPechkin使用ObjectSettings類進行巢狀配置:

// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Custom PDF</h1></body></html>";

        var document = new HtmlToPdfDocument
        {
            GlobalSettings = {
                Orientation = GlobalSettings.PdfOrientation.Landscape,
                PaperSize = GlobalSettings.PdfPaperSize.A4,
                Margins = new MarginSettings { Unit = Unit.Millimeters, Top = 10, Bottom = 10 }
            },
            Objects = {
                new ObjectSettings { HtmlText = html }
            }
        };

        byte[] pdfBytes = converter.Convert(document);
        File.WriteAllBytes("custom.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Custom PDF</h1></body></html>";

        var document = new HtmlToPdfDocument
        {
            GlobalSettings = {
                Orientation = GlobalSettings.PdfOrientation.Landscape,
                PaperSize = GlobalSettings.PdfPaperSize.A4,
                Margins = new MarginSettings { Unit = Unit.Millimeters, Top = 10, Bottom = 10 }
            },
            Objects = {
                new ObjectSettings { HtmlText = html }
            }
        };

        byte[] pdfBytes = converter.Convert(document);
        File.WriteAllBytes("custom.pdf", pdfBytes);
    }
}
Imports TuesPechkin
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New StandardConverter(
            New RemotingToolset(Of PdfToolset)(
                New Win64EmbeddedDeployment(
                    New TempFolderDeployment())))

        Dim html As String = "<html><body><h1>Custom PDF</h1></body></html>"

        Dim document = New HtmlToPdfDocument With {
            .GlobalSettings = New GlobalSettings With {
                .Orientation = GlobalSettings.PdfOrientation.Landscape,
                .PaperSize = GlobalSettings.PdfPaperSize.A4,
                .Margins = New MarginSettings With {.Unit = Unit.Millimeters, .Top = 10, .Bottom = 10}
            },
            .Objects = {
                New ObjectSettings With {.HtmlText = html}
            }
        }

        Dim pdfBytes As Byte() = converter.Convert(document)
        File.WriteAllBytes("custom.pdf", pdfBytes)
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF配置

IronPDF在RenderingOptions屬性中集中設置,具直觀的屬性名稱:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;

        string html = "<html><body><h1>Custom PDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("custom.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;

        string html = "<html><body><h1>Custom PDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("custom.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Engines.Chrome
Imports System

Module Program
    Sub Main()
        Dim renderer As New ChromePdfRenderer()

        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
        renderer.RenderingOptions.MarginTop = 10
        renderer.RenderingOptions.MarginBottom = 10

        Dim html As String = "<html><body><h1>Custom PDF</h1></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(html)

        pdf.SaveAs("custom.pdf")
    End Sub
End Module
$vbLabelText   $csharpLabel

RenderingOptions類提供了統一的配置方法,其中邊距值直接用毫米指定,無需封裝物件。

執行緒安全性和併發性

對於伺服器端PDF生成,執行緒安全性代表了一個關鍵考量,兩個程式庫採取了根本不同的方法。

TuesPechkin執行緒管理

TuesPechkin通過ThreadSafeConverter廣告其執行緒安全運作,但實施有記錄的限制:

//TuesPechkin- Even with ThreadSafeConverter, crashes under load
var converter = new TuesPechkin.ThreadSafeConverter(
    new TuesPechkin.RemotingToolset<PechkinBindings>());

// Under high load, applications may experience:
// - System.AccessViolationException
// - StackOverflowException
// - Process hangs indefinitely
// - Memory corruption
//TuesPechkin- Even with ThreadSafeConverter, crashes under load
var converter = new TuesPechkin.ThreadSafeConverter(
    new TuesPechkin.RemotingToolset<PechkinBindings>());

// Under high load, applications may experience:
// - System.AccessViolationException
// - StackOverflowException
// - Process hangs indefinitely
// - Memory corruption
' TuesPechkin- Even with ThreadSafeConverter, crashes under load
Dim converter = New TuesPechkin.ThreadSafeConverter(
    New TuesPechkin.RemotingToolset(Of PechkinBindings)())

' Under high load, applications may experience:
' - System.AccessViolationException
' - StackOverflowException
' - Process hangs indefinitely
' - Memory corruption
$vbLabelText   $csharpLabel

底層的wkhtmltopdf程式庫並非設計用於高併發場景,即便有封裝級的執行緒管理,在負載很大的情況下穩定性問題依然存在。

IronPDF原生併發

IronPDF提供了天然的執行緒安全性,無需任何配置:

//IronPDF- Native thread safety
var renderer = new ChromePdfRenderer();

// Safe for concurrent use across multiple threads
// No AccessViolationException
// No process hangs
// Stable under high load
//IronPDF- Native thread safety
var renderer = new ChromePdfRenderer();

// Safe for concurrent use across multiple threads
// No AccessViolationException
// No process hangs
// Stable under high load
'IronPDF- Native thread safety
Dim renderer As New ChromePdfRenderer()

' Safe for concurrent use across multiple threads
' No AccessViolationException
' No process hangs
' Stable under high load
$vbLabelText   $csharpLabel

ChromePdfRenderer在內部處理併發,使開發者能專注於應用邏輯而非執行緒同步。

現代CSS和JavaScript支持

當使用現代網路技術時,TuesPechkin和IronPDF之間的渲染引擎差異最為顯著。

TuesPechkin渲染限制

TuesPechkin的Qt WebKit 4.8引擎早於現代CSS佈局系統:


<div style="display: flex; justify-content: space-between; gap: 20px;">
    <div style="flex: 1;">Column 1</div>
    <div style="flex: 1;">Column 2</div>
</div>

<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
    <div>Grid Item 1</div>
    <div>Grid Item 2</div>
    <div>Grid Item 3</div>
</div>

<div style="display: flex; justify-content: space-between; gap: 20px;">
    <div style="flex: 1;">Column 1</div>
    <div style="flex: 1;">Column 2</div>
</div>

<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
    <div>Grid Item 1</div>
    <div>Grid Item 2</div>
    <div>Grid Item 3</div>
</div>
HTML

使用TuesPechkin的應用程式必須依賴於基於表格的佈局或其他CSS2.1的變通方案來實現多列設計。

IronPDF現代渲染

IronPDF的Chromium引擎支持所有現代的CSS和JavaScript:

// Modern CSS works correctly with IronPDF
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Renders correctly with full Flexbox support
// Modern CSS works correctly with IronPDF
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Renders correctly with full Flexbox support
Dim html As String = "
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>"

Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
' Renders correctly with full Flexbox support
$vbLabelText   $csharpLabel

這使開發者能使用相同的HTML/CSS同時進行網頁顯示和PDF生成,無需維護單獨的模板。

當團隊考慮TuesPechkin的替代方案時

若干情景通常促使開發團隊評估TuesPechkin的替代品:

安全需求

由於CVE-2022-35583評分9.8/10,並且底層的wkhtmltopdf程式庫已正式被棄用,具有安全合規需求的組織不能繼續使用TuesPechkin。 SSRF漏洞允許攻擊者通過惡意HTML內容存取內部網路、竊取憑證並傳輸資料。

現代網路技術採用

採用現代前端框架(React、Angular、Vue.js)或CSS佈局系統(Flexbox, Grid)的團隊發現TuesPechkin無法準確渲染他們的內容。 過時的WebKit 4.8引擎不支持已經標準了近十年的技術。

負載下的穩定性

伺服器端應用程式在併發PDF生成負載下,經歷崩潰、掛起或AccessViolationException錯誤,通常將這些問題歸因於TuesPechkin的執行緒限制。 即便有ThreadSafeConverter配置,底層的wkhtmltopdf程式庫並非設計用於高併發環境。

PDF特性需求

TuesPechkin只提供HTML到PDF的轉換。 需要PDF操作(合併、分割)、數位簽名、PDF/A合規性、表單填寫或水印的團隊必須新增額外的程式庫,或考慮像IronPDF這樣本身提供這些功能的替代方案。

簡化部署

TuesPechkin的初始化模式使用TempFolderDeployment增加了部署的複雜性。 必須為每個目標環境正確配置特定平台的本機二進位。 IronPDF通過標準的NuGet安裝消除了這一複雜性。

API映射參考

正在評估從TuesPechkin過渡到IronPDF的團隊會發現此映射有助於理解概念等價:

TuesPechkinIronPDF
StandardConverter / ThreadSafeConverterChromePdfRenderer
HtmlToPdfDocument方法參數
GlobalSettings.PaperSizeRenderingOptions.PaperSize
GlobalSettings.OrientationRenderingOptions.PaperOrientation
GlobalSettings.MarginsRenderingOptions.MarginTop/Bottom/Left/Right
ObjectSettings.HtmlTextRenderHtmlAsPdf(html)
ObjectSettings.PageUrlRenderUrlAsPdf(url)
RemotingToolset + Deployment無需
[page]佔位符{page}佔位符
[toPage]佔位符{total-pages}佔位符

額外的 PDF 功能

除了HTML到PDF的轉換外,IronPDF還提供TuesPechkin無法提供的文件處理功能:

.NET相容性和未來準備

TuesPechkin的非活動開發狀態意味著對於較新的.NET版本沒有任何更新。IronPDF保持積極地開發,提供定期更新,確保與 .NET 8、.NET 9 和即將於 2026 年推出的 .NET 10 相容。 該程式庫的 async/await 支援貫穿其 API,符合現代 C# 開發 做法,包括 C# 13 可用的功能和預期的 C# 14 功能。

結論

TuesPechkin和IronPDF代表了不同時代的.NET PDF生成。 TuesPechkin提供了一個免費的,MIT授權的wkhtmltopdf封裝,但繼承了關鍵的安全漏洞、過時的渲染引擎、複雜的執行緒管理要求和負載下的穩定性問題。 底層的技術於2022年被遺棄,不會有安全補丁。

IronPDF提供了一個現代的,積極維護的替代方案,具備基於Chromium的渲染引擎,支持現代網路技術。 其內建的執行緒安全性、全面的PDF功能和簡單的API設計解決了wkhtmltopdf封裝固有的限制。

目前使用TuesPechkin的團隊,遷移的決定常常來自於安全需求、渲染質量需求、穩定性顧慮,或對超越基本HTML轉換的PDF功能的需求。 兩個程式庫之間的API映射是直接的,由於IronPDF簡化的初始化和配置模式,通常需要更少的程式碼。

如需額外的實施指南,請探索IronPDF文件教程,涵蓋特定用例和高級功能。

請注意TuesPechkin和wkhtmltopdf是其各自所有者的註冊商標。 本網站與TuesPechkin或wkhtmltopdf沒有任何關聯,也未受到其支持或贊助。 所有產品名稱、標誌和品牌均為其各自所有者的財產。 比較僅供資訊參考,並反映了撰寫時公開的資訊。)}