比較

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 使用 SynchronizedConverterPdfTools 進行轉換。 配置透過 HtmlToPdfDocument 物件進行管理,其中包含 GlobalSettings 頁選項(ColorMode、Orientation、PaperSize、Margins)和 ObjectSettings 內容(HtmlContent 用於 HTML 字串,Page 用於 URL)。 converter.Convert(doc) 方法傳回原始 byte[] 資料。

該庫需要特定於平台的本機二進位檔案:libwkhtmltox.dylib(macOS)。 由於 wkhtmltopdf 的限制,線程安全要求在單例模式中使用 SynchronizedConverter

探索IronPDF

IronPDF是一個獨立開發的.NET函式庫,它使用現代 Chromium 渲染引擎。該庫持續維護,定期更新,提供專業支援和持續安全性修補程式。

IronPDF使用 ChromePdfRenderer 作為其主要渲染類,並透過 RenderingOptions 屬性進行配置。 類似 RenderHtmlAsPdf()RenderUrlAsPdf() 的方法返回 PdfDocument 對象,這些對象可以用 SaveAs() 保存,也可以用 SaveAs() 保存,也可以用 @@--CO 該庫是獨立的,不需要任何外部本地二進位文件,並且從設計上就保證了線程安全,不需要單例模式。

關鍵安全考量

這些庫之間最顯著的差異在於安全性。 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.DinkToPdfIronPDF
關鍵 CVECVE-2022-35583(CVSS 9.8,無法修復)已積極打補丁
底層引擎wkhtmltopdf(Qt WebKit ~2015)Chromium(定期更新)
專案狀態廢棄項目的分支積極開發
安全性更新預計不會發生定期發布
支援僅限社區專業支援

架構和引擎比較

根本性的架構差異會影響渲染品質、現代網路標準支援和部署複雜性。

方面Haukcode.DinkToPdfIronPDF
渲染引擎Qt WebKit(約2015年)鉻(當前)
HTML5/CSS3有限的支援
JavaScript有限、不安全全V8發動機
本地二進位文件必需(平台特定)自給自足
螺紋安全需要單例模式螺紋安全設計
更新預計不會發生定期發布

Haukcode.DinkToPdf 依賴過時的 Qt WebKit 引擎,這意味著它缺少多年的安全補丁,並且對現代 Web 標準的支援有限。 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);
    }
}
$vbLabelText   $csharpLabel

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");
    }
}
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 需要建立一個 SynchronizedConverter 對象,並包含 PdfTools 對象,然後建構一個 HtmlToPdfDocument 對象,並嵌套 GlobalSettings 和 @@CODE-15--15-- 5-2來取得原始字節,然後使用 File.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);
    }
}
$vbLabelText   $csharpLabel

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");
    }
}
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 使用相同的 HtmlToPdfDocument 結構,並帶有 ObjectSettings.Page 屬性用於 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);
    }
}
$vbLabelText   $csharpLabel

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");
    }
}
$vbLabelText   $csharpLabel

Haukcode.DinkToPdf 透過嵌套的 GlobalSettings 物件配置頁面設定。 屬性使用枚舉,例如 Orientation.LandscapePaperKind.Letter

IronPDF直接在渲染器上使用 RenderingOptions 屬性。 屬性是單獨設定的(PdfPaperOrientation.Landscape@)。 兩者都使用毫米作為邊距單位。

了解更多關於渲染配置的信息,請參閱IronPDF教學

API對應參考

對於正在評估 Haukcode.DinkToPdf 遷移或比較功能的開發人員來說,此映射顯示了等效操作:

轉換器類別映射

Haukcode.DinkToPdfIronPDF
SynchronizedConverterChromePdfRenderer
BasicConverterChromePdfRenderer
PdfTools不適用
IConverter不適用

文檔配置映射

Haukcode.DinkToPdfIronPDF
HtmlToPdfDocument方法調用
GlobalSettingsRenderingOptions
ObjectSettingsRenderingOptions
converter.Convert(doc)renderer.RenderHtmlAsPdf(html)

全域設定屬性映射

全域設定屬性IronPDF屬性
ColorModeRenderingOptions.GrayScale
OrientationRenderingOptions.PaperOrientation
PaperSizeRenderingOptions.PaperSize
Margins.TopRenderingOptions.MarginTop
Margins.BottomRenderingOptions.MarginBottom
Margins.LeftRenderingOptions.MarginLeft
Margins.RightRenderingOptions.MarginRight

物件設定屬性映射

ObjectSettings 屬性IronPDF當量
HtmlContent第一個參數給 RenderHtmlAsPdf()
Page (URL)renderer.RenderUrlAsPdf(url)
HeaderSettings.Right = "[page]"TextHeader.RightText = "{page}"

佔位符語法差異

不同庫中使用的頁首/頁尾佔位符語法不同:

Haukcode.DinkToPdfIronPDF
[page]{page}
[toPage]{total-pages}
[date]{date}

線程安全和依賴注入

由於繼承自 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()));
}
$vbLabelText   $csharpLabel

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!
}
$vbLabelText   $csharpLabel

IronPDF從設計上就是線程安全的,允許靈活的依賴注入模式,而無需單例模式。

功能對比總結

特徵Haukcode.DinkToPdfIronPDF
來源廢棄項目的分支獨立發展
安全從上游繼承的 CVE(無法修復)主動打補丁並確保安全
社區與支持小而零星規模龐大、積極活躍且盡職盡責
功能與更新有限且零星定期積極發展
多線程支持需要單例模式全面支援並已優化
本地二進位文件必需(平台特定)自給自足
HTML5/CSS3有限的支援
JavaScript有限的全V8發動機
執照麻省理工學院(免費)提供免費試用的商業廣告

當團隊考慮從 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.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),這些漏洞永遠不會被修復。 該庫需要本地二進位分發,採用單例模式以確保線程安全,並提供有限的現代 Web 標準支援。

IronPDF提供了一個積極維護的替代方案,它採用現代 Chromium 引擎、定期安全更新和執行緒安全架構。 此獨立函式庫消除了原生二進位檔案的管理,同時提供了完整的 HTML5/CSS3/ JavaScript支援。

隨著各組織規劃.NET 10、C# 14 以及到 2026 年的應用程式開發,在繼續依賴存在嚴重且無法修復的漏洞的已棄用技術與採用具有現代功能的積極維護的解決方案之間做出選擇,會對安全態勢和開發速度產生重大影響。 對於需要安全產生 PDF、現代渲染或簡化部署的團隊來說, IronPDF可以有效地滿足這些需求。

立即開始免費試用IronPDF ,並瀏覽其全面的文檔,以評估其是否符合您的特定需求。