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之間的技術差異:
| 功能 | TuesPechkin | IronPDF |
|---|---|---|
| 授權 | 免費(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此模式需要了解多個巢狀類別: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 ClassChromePdfRenderer類提供了立即存取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相同的初始化複雜性適用,由於缺少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 ClassRenderUrlAsPdf方法將頁面載入到無頭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 ModuleIronPDF配置
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 ModuleRenderingOptions類提供了統一的配置方法,其中邊距值直接用毫米指定,無需封裝物件。
執行緒安全性和併發性
對於伺服器端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底層的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 loadChromePdfRenderer在內部處理併發,使開發者能專注於應用邏輯而非執行緒同步。
現代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>使用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 supportDim 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這使開發者能使用相同的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的團隊會發現此映射有助於理解概念等價:
| TuesPechkin | IronPDF |
|---|---|
StandardConverter / ThreadSafeConverter | ChromePdfRenderer |
HtmlToPdfDocument | 方法參數 |
GlobalSettings.PaperSize | RenderingOptions.PaperSize |
GlobalSettings.Orientation | RenderingOptions.PaperOrientation |
GlobalSettings.Margins | RenderingOptions.MarginTop/Bottom/Left/Right |
ObjectSettings.HtmlText | RenderHtmlAsPdf(html) |
ObjectSettings.PageUrl | RenderUrlAsPdf(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文件和教程,涵蓋特定用例和高級功能。
