比較

TuesPechkin與IronPDF:技術比較指南

當.NET開發人員需要將HTML轉換為PDF時,出現了幾個基於舊版渲染引擎的包裝程式庫作為選擇。 TuesPechkin代表了這樣的一種解決方案,它包裝了wkhtmltopdf程式庫以提供PDF生成功能。 這項技術比較分析了TuesPechkin與IronPDF,以幫助架構師和開發人員理解遺留包裝器與現代PDF程式庫之間的權衡。

了解TuesPechkin

TuesPechkin是一個圍繞wkhtmltopdf程式庫的線程安全包裝器,旨在幫助開發人員從HTML內容生成PDF文件。 該程式庫試圖通過提供ThreadSafeConverter實現來解決wkhtmltopdf固有的並發挑戰。

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

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

安全性考量

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

了解IronPDF

IronPDF採取了一種根本不同的方法,提供了一個現代化的商用PDF程式庫,具有原生線程安全性和基於Chromium的渲染引擎。IronPDF不包裝遺留工具,而是將PDF生成作為其核心焦點。

IronPDF的關鍵特點包括:

  • 現代Chromium引擎: 支持HTML5、CSS3、Flexbox、CSS Grid和ES6+ JavaScript
  • 原生線程安全性: 不需要手動線程管理 — 並發操作自動工作
  • 積極開發: 每週更新和持續改進
  • 全面的PDF功能: 除了生成 PDF,還包含操作、數位簽名、PDF/A合規性和表單填寫
  • 簡單整合: 通過NuGet直接安裝,不需要原生二進位部署

功能比較

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

功能TuesPechkinIronPDF
授權免費(MIT授權)商業
線程安全性需要手動管理原生支援
並發性有限,載荷下可能崩潰穩定,能處理高並發性
開發狀態不活躍,最後更新於2015年活躍,持續改進
易用性複雜的設定用戶友好的指南
文件基本大量示例
渲染引擎Qt WebKit 4.8(已過時)現代Chromium
CSS3支援部分支持
Flexbox/Grid不支持支持
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

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

IronPDF實現

IronPDF通過其現代Chromium引擎提供專門用於URL渲染的方法:

// 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的渲染引擎差異在處理現代Web技術時尤其明顯。

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

這使開發人員可以對Web顯示和PDF生成使用相同的HTML/CSS,而不需要維護單獨的模板。

當團隊考慮TuesPechkin的替代品時

有幾個情境常常促使開發團隊評估TuesPechkin的替代品:

安全要求

由於CVE-2022-35583被評為嚴重(9.8/10),且底層的wkhtmltopdf程式庫已經正式被遺棄,具有安全合規性要求的組織不能繼續使用TuesPechkin。 SSRF漏洞允許攻擊者通過惡意HTML內容訪問內部網路、竊取憑證並提取數據。

現代Web技術採用

採用現代前端框架(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的兼容性。程式庫的非同步/等待支持貫穿其API,符合現代C#開發實踐,包括C# 13提供的功能和預期的C# 14的能力。

結論

TuesPechkin和IronPDF代表了不同時代的.NET PDF生成。 TuesPechkin提供了一種基於wkhtmltopdf的免費、MIT授權的包裝器,但繼承了嚴重的安全漏洞、過時的渲染引擎、複雜的線程管理需求,以及載荷下的不穩定性。 底層技術於2022年被遺棄,不會再有安全修補。

IronPDF提供了一個現代化、積極維護的替代方案,具有基於Chromium的渲染引擎,支持當前的Web技術。 其原生線程安全性、全面的PDF功能和簡單的API設計解決了wkhtmltopdf包裝器固有的限制。

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

欲瞭解更多實施指導,請探索IronPDF文檔教程,涵蓋具體使用案例和高級功能。

@@--CODE-##--@@(TuesPechkin和wkhtmltopdf是其各自所有者的註冊商標。 本網站未與TuesPechkin或wkhtmltopdf進行聯繫、授權或贊助。 所有產品名稱、標誌及商標均為其各自所有者的財產。 比較僅供信息參考,反映在寫作時公開的相關信息。)}]