Haukcode.DinkToPdf vs IronPDF:技術比較指南
當 .NET 開發人員考慮 PDF 生成選項時,Haukcode.DinkToPdf 脫穎而出,它是已停止開發的 DinkToPdf 專案的延續,該專案使用 wkhtmltopdf 二進位。 雖然 Haukcode.DinkToPdf 提供基本的 HTML 到 PDF 轉換功能,但由於 wkhtmltopdf 專案的停止,它存在嚴重的安全風險,這些風險將永遠無法修復。IronPDF提供了一種不同的選擇:一個使用現代 Chromium 引擎並定期進行安全更新的積極維護的庫。
本次比較從相關技術方面對這兩個庫進行了審查,以幫助開發人員和架構師根據其 .NET PDF 需求做出明智的選擇。
探索 Haukcode.DinkToPdf
Haukcode.DinkToPdf 是曾經流行的 DinkToPdf 庫的延續,它基於現已停止使用的 wkhtmltopdf 二進位檔案構建。 該程式庫旨在保持與 .NET Core 的兼容性,同時提供 HTML 到 PDF 的轉換功能。 作為一項已放棄專案的延續,Haukcode.DinkToPdf 有明顯的限制。
Haukcode.DinkToPdf 使用SynchronizedConverter和PdfTools進行轉換。 配置透過HtmlToPdfDocument物件進行管理,該物件包含用於頁面選項(ColorMode、Orientation、PaperSize、Margins)的GlobalSettings和用於內容(HtmlContent 用於 HTML 字串,Page 用於 URL)的ObjectSettings 。converter.Convert(doc)方法返回原始 byte[] 資料。
該函式庫需要特定平台的本機二進位檔:libwkhtmltox.dll (Windows), libwkhtmltox.so (Linux), 和 libwkhtmltox.dylib (macOS). 由於 wkhtmltopdf 的限制,線程安全要求在單例模式下使用SynchronizedConverter 。
探索鐵質PDF
IronPDF 是一個獨立開發的 .NET 函式庫,使用現代的 Chromium 演算引擎。該函式庫透過定期更新、專業支援和持續的安全修補程式進行積極的維護。
IronPDF 使用<代碼>ChromePdfRenderer</代碼作為其主要的渲染類別,並透過渲染選項屬性進行設定。 像 RenderHtmlAsPdf() 和 RenderUrlAsPdf() 之類的方法會返回 PdfDocument 物件,這些物件可以用 SaveAs() 儲存或以 BinaryData 存取。 這個函式庫是獨立的,不需要外部的原生二進位檔,而且在設計上是線程安全的,不需要單件模式。
關鍵的安全性考量
這些函式庫最顯著的差異在於安全性。 Haukcode.DinkToPdf 繼承了 CVE-2022-35583,這是一個重要的伺服器端請求偽造 (SSRF) 漏洞,CVSS 得分為 9.8。
CVE-2022-35583攻擊向量:
- 惡意的 HTML 內容會使伺服器擷取內部資源
- AWS 元資料攻擊可存取
http://169.254.169.254以竊取憑證 - 內部網路掃描及存取內部服務
- 透過
file://通訊協定包含本機檔案 - 有可能完全接管基礎架構
此漏洞沒有修補程式,因為 wkhtmltopdf 已經廢棄 (自 2023 年 1 月開始歸檔,最後一次發行是 2020 年的 0.12.6)。
| 安全方面 | Haukcode.DinkToPdf | IronPDF |
|---|---|---|
| 關鍵 CVE。 | CVE-2022-35583 (CVSS 9.8, 不可修復) | 積極修補 |
| 基礎引擎 | wkhtmltopdf (Qt WebKit ~2015) | Chromium (定期更新) |
| 專案狀態 | 廢棄專案的分叉 | 積極開發 |
| 安全性更新 | 無預期 | 定期發佈 |
| <強>支援</強 | 僅限社群 | 專業支援 |
架構與引擎比較
基本的架構差異會影響渲染品質、現代網路標準支援以及部署複雜度。
| 範疇 | Haukcode.DinkToPdf | IronPDF |
|---|---|---|
| 渲染引擎 | Qt WebKit (~2015) | Chromium (目前) |
| HTML5/CSS3。 | 限額 | 支援 |
| JavaScript。 | 有限、不安全 | 完整的 V8 引擎 |
| 原生二進位 | 必需(特定平台) | 自成一格 |
| 線程安全 | 需要單元模式 | 線程安全的設計 |
| 更新 | 無預期 | 定期發佈 |
Haukcode.DinkToPdf 依賴於過時的 Qt WebKit 引擎,這意味著會錯過多年的安全修補程式,且對現代網頁標準的支援有限。IronPDF的 Chromium 引擎可定期更新,提供當前的 Web 標準支援。
程式碼比較:常見的 PDF 作業
HTML 至 PDF 轉換
最基本的操作展示了 API 設計上的差異。
Haukcode.DinkToPdf:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
HtmlContent = "<html><body><h1>Hello World</h1></body></html>",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
HtmlContent = "<html><body><h1>Hello World</h1></body></html>",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>");
pdf.SaveAs("output.pdf");
}
}Haukcode.DinkToPdf需要使用PdfTools建立一個SynchronizedConverter,用嵌套的GlobalSettings和ObjectSettings物件建構一個HtmlToPdfDocument,呼叫Convert()取得原始位元組,然後用File.WriteAllBytes()手動寫入磁碟。WriteAllBytes()。
IronPDF 創建一個<代碼>ChromePdfRenderer</代碼,直接使用 HTML 字串呼叫 RenderHtmlAsPdf() ,並使用 SaveAs() 儲存。 透過現代化的 API 設計,操作顯得更加簡潔。
如需進階的 HTML 呈現選項,請探索 HTML 至 PDF 轉換指南。
URL 轉 PDF
轉換網頁展示了處理外部內容的不同方法。
Haukcode.DinkToPdf:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
Page = "https://www.example.com",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("webpage.pdf", pdf);
}
}// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4,
},
Objects = {
new ObjectSettings() {
Page = "https://www.example.com",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("webpage.pdf", pdf);
}
}IronPDF:
// 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");
}
}Haukcode.DinkToPdf 使用與 ObjectSettings.Page 屬性相同的<編碼>HtmlToPdfDocument</編碼結構來指定 URL。IronPDF提供了一個專用的 RenderUrlAsPdf() 方法,可直接接受 URL--對於此特定用例而言,這是一個更乾淨的 API。
請注意,使用 Haukcode.DinkToPdf 的 URL 渲染會帶有 CVE-2022-35583 SSRF 漏洞風險,因為惡意 URL 或重定向可能會利用伺服器。
自訂頁面設定
頁面配置展示了不同的配置模型。
Haukcode.DinkToPdf:
// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.Letter,
Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
},
Objects = {
new ObjectSettings() {
HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("landscape.pdf", pdf);
}
}// NuGet: Install-Package DinkToPdf
using DinkToPdf;
using DinkToPdf.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.Letter,
Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
},
Objects = {
new ObjectSettings() {
HtmlContent = "<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>",
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("landscape.pdf", pdf);
}
}IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>");
pdf.SaveAs("landscape.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
var pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Landscape Document</h1><p>Custom page settings</p></body></html>");
pdf.SaveAs("landscape.pdf");
}
}Haukcode.DinkToPdf 透過嵌套 MarginSettings 物件的全局設定來設定頁面設定。 屬性使用諸如 Orientation.Landscape 和 PaperKind.Letter 之類的枚數。
IronPdf 直接在渲染器上使用渲染選項屬性。 屬性可個別設定 (PaperSize、PaperOrientation、MarginTop 等) 與類型化的枚舉 (PdfPaperSize.Letter、PdfPaperOrientation.Landscape)。 兩者都使用毫米作為邊界單位。
在IronPDF教學中了解更多關於渲染配置的資訊。
API 對應參考。
對於評估 Haukcode.DinkToPdf 遷移或比較功能的開發人員而言,此對應圖顯示等效的操作:
轉換器類別對應
| Haukcode.DinkToPdf | IronPDF |
|---|---|
同步轉換器 | <代碼>ChromePdfRenderer</代碼 |
基本轉換器 | <代碼>ChromePdfRenderer</代碼 |
| <編碼>PdfTools</編碼 | 不適用 |
IConverter | 不適用 |
文件配置映射
| Haukcode.DinkToPdf | IronPDF |
|---|---|
| <編碼>HtmlToPdfDocument</編碼 | 方法調用 |
全局設定 | 渲染選項 |
物件設定 | 渲染選項 |
converter.Convert(doc) | renderer.RenderHtmlAsPdf(html)。 |
GlobalSettings 屬性對應
| GlobalSettings 屬性 | IronPdf 特性 |
|---|---|
| <編碼>ColorMode</編碼 | RenderingOptions.GrayScale |
| <編碼>方向</編碼 | <編碼>RenderingOptions.PaperOrientation</編碼 |
紙張大小 | RenderingOptions.PaperSize |
Margins.Top | RenderingOptions.MarginTop |
邊界.底部 | RenderingOptions.MarginBottom |
Margins.Left | RenderingOptions.MarginLeft |
Margins.Right | <編碼>RenderingOptions.MarginRight</編碼 |
物件設定屬性對應
| 物件設定屬性 | IronPdf 同等級產品 |
|---|---|
| <編碼>Html內容</編碼 | RenderHtmlAsPdf() 的第一個參數 |
頁面 (URL) | renderer.RenderUrlAsPdf(url)。 |
HeaderSettings.Right = "[page]" | TextHeader.RightText="{page}"。 |
占位符語法差異
Header/footer 占位符在不同的程式庫中使用不同的語法:
| Haukcode.DinkToPdf | IronPDF |
|---|---|
[page] | {page} |
[toPage] | {總頁數} |
[日期] | <編碼>{日期}</編碼 |
線程安全與依賴注入
由於從 wkhtmltopdf 繼承的線程安全限制,Haukcode.DinkToPdf 需要小心處理。
Haukcode.DinkToPdf(需要單件):
// Startup.cs - MUST be singleton due to thread safety issues
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
}// Startup.cs - MUST be singleton due to thread safety issues
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
}IronPDF(靈活):
// Startup.cs - Can be singleton or transient (both work)
public void ConfigureServices(IServiceCollection services)
{
IronPdf.License.LicenseKey = Configuration["IronPdf:LicenseKey"];
services.AddSingleton<IPdfService, IronPdfService>();
// Or services.AddTransient<IPdfService, IronPdfService>() - both are safe!
}// Startup.cs - Can be singleton or transient (both work)
public void ConfigureServices(IServiceCollection services)
{
IronPdf.License.LicenseKey = Configuration["IronPdf:LicenseKey"];
services.AddSingleton<IPdfService, IronPdfService>();
// Or services.AddTransient<IPdfService, IronPdfService>() - both are safe!
}IronPdf 在設計上是線程安全的,允許靈活的依賴注入模式,而不需要單例。
功能比較摘要
| 特點 | Haukcode.DinkToPdf | IronPDF |
|---|---|---|
| 來源 | 廢棄專案的分叉 | 獨立開發 |
| 安全性 | 從上游繼承的 CVE (無法修復) | 主動修補與安全 |
| 社群與支援 | 少量零星 | 大型、活躍且專業 |
| 功能與更新 | 有限且零星 | 定期與活躍開發 |
| 多執行緒支援 | 需要單元模式 | 全面支援與最佳化 |
| 原生二進位 | 必需(特定平台) | 自成一格 |
| HTML5/CSS3。 | 限額 | 支援 |
| JavaScript。 | 限額 | 完整的 V8 引擎 |
| 執照 | MIT (免費) | 免費試用的商業版 |
當團隊考慮從 Haukcode.DinkToPdf 移轉到IronPDF時。
開發團隊評估從 Haukcode.DinkToPdf 過渡到IronPDF有幾個原因:
嚴重安全漏洞: CVE-2022-35583 (SSRF) 是一個嚴重漏洞,CVSS 評分為 9.8,永遠不會被修復。 對於處理使用者提供的 HTML 或呈現外部 URL 的應用程式而言,此漏洞會導致 AWS 信賴竊取、內部網路存取和本機檔案包含攻擊。
已棄用的底層技術: wkhtmltopdf 已棄用(已於 2023 年 1 月存檔,最後一次發佈於 2020 年)。 Haukcode.DinkToPdf 作為延續無法解決底層技術中的根本問題。 過時的 Qt WebKit 引擎 (~2015) 錯過了多年的安全修補程式。
本地二進位檔案管理: Haukcode.DinkToPdf 需要分發特定於平台的二進位檔案( libwkhtmltox.dll 、 libwkhtmltox.so 、 libwkhtmltox.dylib )。 這使得部署、CI/CD 管道和容器化變得複雜。 IronPdf 是獨立的,沒有外部二進位檔案。
執行緒安全限制:所需的SynchronizedConverter單例模式限制了架構靈活性,並且可能在負載下造成瓶頸。IronPDF在設計上是線程安全的,允許按要求實體。
現代網路標準: HTML5/CSS3 支援有限以及 JavaScript 執行不安全,限制了現代網頁內容的渲染能力。IronPDF的 Chromium 引擎提供當前的 Web 標準支援。
長期可行性:對已棄用技術的依賴會造成技術債務,並且隨著時間的推移而不斷累積。隨著專案在 2026 年前逐步擴展到 .NET 10 和 C# 14,繼續依賴不再維護的 wkhtmltopdf 封裝庫將變得越來越成問題。
優勢和考慮因素
Haukcode.DinkToPdf 的優勢
-免費開源:採用 MIT 許可證,無需支付任何許可費用 -基本功能:支援基本的 HTML 轉 PDF 轉換 -現有程式碼庫:對於已經使用 DinkToPdf 的團隊來說比較熟悉
Haukcode.DinkToPdf 注意事項
-嚴重安全漏洞: CVE-2022-35583 無法修復 -廢棄技術:基於已停止使用的 wkhtmltopdf 構建 -本地二進位依賴項:需要特定於平台的 DLL 文件 -螺紋安全問題:需要單例模式 -受限的 Web 標準:過時的 Qt WebKit 引擎 -不提供專業支援:僅提供社區援助 技術債:對廢棄項目的依賴加劇了風險
IronPDF的優勢
-主動安全性修補程式:定期更新以修復漏洞 -現代 Chromium 引擎:支援當前 Web 標準 -自包含:無原生二進位依賴項 -線程安全設計:靈活的部署模式 -全面支援 HTML5/CSS3/JavaScript:具備現代渲染功能 -專業支援:專屬工程支持 -豐富的資源:大量的教學和文檔
IronPDF注意事項
-商業許可:生產用途必需
結論
Haukcode.DinkToPdf 和IronPDF代表了在 .NET 應用程式中生成 PDF 的基本不同方法。 Haukcode.DinkToPdf 作為已停止開發的 DinkToPdf 專案的延續,封裝了已停止開發的 wkhtmltopdf 二進位文件,存在嚴重的安全漏洞 (CVE-2022-35583),這些漏洞永遠不會被修復。 該函式庫需要本機二進位發行、單機模式以確保線程安全,並提供有限的現代網路標準支援。
IronPDF 提供積極維護的替代方案,具有現代化的 Chromium 引擎、定期的安全更新以及線程安全的架構。 這個自足的函式庫省去原生二進位管理,同時提供完整的 HTML5/CSS3/JavaScript 支援。
由於組織要規劃 .NET 10、C# 14,以及到 2026 年的應用程式開發,因此在維持對有嚴重無法修復漏洞的廢棄技術的依賴,與採用具有現代功能的積極維護解決方案之間,兩者的選擇都會對安全勢態與開發速度造成重大影響。 需要安全生成 PDF、現代化渲染或簡化部署的團隊會發現IronPDF能有效滿足這些需求。