IRONSOFTWAREHOME
影片

如何在 C# | IronPDF 中新增目錄

Curtis Chau
Curtis Chau
Updated: 2026年7月19日

wkhtmltopdf 一直是一個廣泛使用的工具,用於利用 Qt 4.8 + QtWebKit 將 HTML 文件轉換為 PDF。 儘管它在開發者中因為其命令行功能和免費授權而廣受歡迎,但該專案現在已產生無法忽視的關鍵安全風險。 GitHub 資源庫已於 2023年1月2日被歸檔; 最後的上游發布版本是 2020年6月11日的 0.12.6; 而 CVE-2022-35583 (CVSS 9.8,SSRF)尚未修補。

本指南提供從 wkhtmltopdf 遷移到IronPDF的完整路徑,為需要消除此安全風險的專業 .NET 開發人員提供逐步指導、程式碼比較和實際範例。

關鍵安全警告:CVE-2022-35583

wkhtmltopdf 包含永遠不會被修補的關鍵安全漏洞:

問題詳情狀況
CVE-2022-35583 (SSRF, CWE-918)危險 (CVSS 9.8)未修補 - 維護者有爭議
GitHub 資源庫已歸檔唯讀2023年1月2日
最後的上游發布0.12.62020年6月11日
底層引擎Qt 4.8 + QtWebKit (Qt 4.8 在 2015 年結束支援)已過時
CSS Grid 支援None已中斷
Flexbox 支援部分已中斷
ES6+ JavaScript有限已中斷

SSRF 攻擊的工作原理

伺服器端請求偽造漏洞允許攻擊者存取內部服務、竊取憑據、掃描您的內部網路,並通過精心設計的 HTML 滲透敏感資料:

<!-- Malicious HTML submitted to your PDF generator -->
<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>
HTML

當 wkhtmltopdf 渲染此 HTML 時,會從您伺服器的網路上下文中獲取這些 URL,從而繞過防火牆和安全控件。

受影響的封裝程式庫

每個 .NET 封裝都會捆綁或包裹同一個 wkhtmltopdf 本地二進制檔案,因此無論封裝程式庫本身的活動程度如何,它們都會繼承其 CVE 暴露:

封裝程式庫最新 NuGet安全風險
DinkToPdf1.0.8 (2017年4月) - 已放棄繼承 CVE-2022-35583
Rotativa.AspNetCore (webgio 分叉)1.4.0 (2023年11月) - 封裝更新,二進制凍結繼承 CVE-2022-35583
TuesPechkin2.1.1 (2015年1月) - 已放棄繼承 CVE-2022-35583
Haukcode.WkHtmlToPdfDotNet (以前是 WkHtmlToPdf-DotNet)1.5.95 (2024年10月) - 封裝更新,二進制凍結繼承 CVE-2022-35583
NReco.PdfGenerator封裝更新,捆綁 wkhtmltopdf繼承 CVE-2022-35583

如果您使用了任何這些程式庫,那麼除非您清理所有 HTML 輸入,否則您的應用程式就暴露於 CVE-2022-35583。

##IronPDFvs wkhtmltopdf:功能比較

了解結構差異有助於技術決策者評估遷移投資:

功能wkhtmltopdfIronPDF
授權LGPLv3 (免費)商業
渲染引擎Qt 4.8 + QtWebKit (Qt 4.8 在 2015 年結束支援)當前的 Chromium 引擎
安全漏洞CVE-2022-35583 (CVSS 9.8)未修補,有爭議未報告關鍵 CVE
主動維護GitHub 資源庫於 2023年1月2日被歸檔; 最後一次發布是 2020年6月積極維護,定期發布
對現代 Web 標準的支援有限(Flexbox 已中斷,無 CSS Grid)支援
整合和支援僅限於社區論壇詳盡的文件和專門的支援
CSS Grid CSS 網格布局❌ 不支援✅ 支援
Flexbox⚠ 已中斷✅ 支援
ES6+ JavaScript❌ 不支援✅ 支援
Async/Await❌ 不支援✅ 支援
PDF 操作❌ 不支援✅ 支援
數位簽名❌ 不支援✅ 支援
PDF/A合規性❌ 不支援✅ 支援

快速開始:wkhtmltopdf 遷移到 IronPDF

可以立即透過這些基本步驟開始遷移。

步驟 1:移除 wkhtmltopdf 套件和二進制文件

移除所有 wkhtmltopdf 封裝套件:

# Remove wkhtmltopdf wrapper (whichever you're using)
dotnet remove package Haukcode.WkHtmlToPdfDotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

# Remove wkhtmltopdf binary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
SHELL

步驟 2:安裝 IronPDF

# AddIronPDF(secure, modern alternative)
dotnet add package IronPdf
SHELL

步驟 3:更新命名空間

用IronPDF命名空間替換 wkhtmltopdf 命名空間:

// Before (wkhtmltopdf)
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;

// After (IronPDF)
using IronPdf;

步驟 4:初始化授權

在應用啓動時新增授權初始化:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

程式碼遷移範例

將HTML轉換為PDF

最基本的操作揭示了這些 .NET PDF 方法之間的複雜性差異。

wkhtmltopdf 方法:

// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.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 = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}

IronPDF 方法:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}

wkhtmltopdf 需要使用 SynchronizedConverter 建立 PdfTools,使用 GlobalSettings 和 Objects 構建 HtmlToPdfDocument,設置如 ColorMode, Orientation, 和 PaperSize 的屬性,調用 converter.Convert() 以獲取原始字節,並使用 File.WriteAllBytes() 手動寫入文件。

IronPDF 完全消除這一程式 - 建立 ChromePdfRenderer,調用 RenderHtmlAsPdf(),使用內建的 SaveAs() 方法。

如需進階 HTML 到 PDF 的場景,請參見 HTML 到 PDF 轉換指南。

將 URL 轉換為 PDF

URL到PDF轉換顯示了類似的複雜性模式。

wkhtmltopdf 方法:

// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.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");
    }
}

wkhtmltopdf 在 ObjectSettings 中使用 Page 屬性來指定 URL,需要相同的文件構建模式。IronPDF提供了一個專門的 RenderUrlAsPdf() 方法,清楚地表達意圖。

查看 URL 到 PDF 文件,了解認證和自定義標頭選項。

自訂設定:具有頁面配置的 HTML 文件

配置方向、邊距和紙張尺寸需要不同的方法。

wkhtmltopdf 方法:

// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.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.A4,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "input.html",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom-output.pdf", pdf);
    }
}

IronPDF 方法:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        
        var pdf = renderer.RenderHtmlFileAsPdf("input.html");
        pdf.SaveAs("custom-output.pdf");
    }
}

wkhtmltopdf 在 GlobalSettings 和 Objects 中巢狀設置,MarginSettings 作為單獨的物件。IronPDF提供了直接的 RenderingOptions 屬性,具有明確的名稱,如 PaperOrientation, MarginTop, 和 PaperSize。

wkhtmltopdf API 到IronPDF映射參考

此映射透過展示直接的 API 等價加速遷移:

CLI 到IronPDF映射

wkhtmltopdf CLI 選項IronPDF等價
wkhtmltopdf input.html output.pdfrenderer.RenderHtmlFileAsPdf()
wkhtmltopdf URL output.pdfrenderer.RenderUrlAsPdf()
--page-size A4RenderingOptions.PaperSize = PdfPaperSize.A4
--page-size LetterRenderingOptions.PaperSize = PdfPaperSize.Letter
--orientation LandscapeRenderingOptions.PaperOrientation = Landscape
--margin-top 10mmRenderingOptions.MarginTop = 10
--margin-bottom 10mmRenderingOptions.MarginBottom = 10
--margin-left 10mmRenderingOptions.MarginLeft = 10
--margin-right 10mmRenderingOptions.MarginRight = 10
--header-html header.htmlRenderingOptions.HtmlHeader
--footer-center "[page]"{page} 佔位符
--footer-center "[toPage]"{total-pages} 佔位符
--enable-javascript預設啟用
--javascript-delay 500RenderingOptions.WaitFor.RenderDelay = 500
--dpi 300RenderingOptions.Dpi = 300
--grayscaleRenderingOptions.GrayScale = true

C# 封裝 API 映射

wkhtmltopdf 封裝IronPDF
SynchronizedConverterChromePdfRenderer
HtmlToPdfDocumentRenderingOptions
GlobalSettings.Outpdf.SaveAs()
GlobalSettings.PaperSizeRenderingOptions.PaperSize
GlobalSettings.OrientationRenderingOptions.PaperOrientation
GlobalSettings.MarginsRenderingOptions.Margin*
ObjectSettings.PageRenderHtmlFileAsPdf()
ObjectSettings.HtmlContentRenderHtmlAsPdf()
converter.Convert(doc)renderer.RenderHtmlAsPdf()

佔位符語法遷移

wkhtmltopdf 佔位符IronPDF 佔位符
[page]{page}
[toPage]{total-pages}
[date]{date}
[time]{time}
[title]{html-title}
[url]{url}

常見遷移問題及解決方案

問題 1:頁眉/頁腳佔位符語法

wkhtmltopdf: 使用方括號語法,如 [page] 和 [toPage]。

解決方案: 更新為IronPDF的大括號佔位符:

// Before (wkhtmltopdf)
FooterSettings = { Left = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
    MaxHeight = 25
};

問題 2:JavaScript 延遲配置

wkhtmltopdf: 使用 JavaScriptDelay 屬性,可靠性有限。

解決方案:IronPDF提供多種選擇:

renderer.RenderingOptions.EnableJavaScript = true;

// Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500);

// Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");

// Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true");

問題 3:現代 CSS 無法渲染

症狀: CSS Grid 和 Flexbox 佈局在 wkhtmltopdf 中渲染不正確。

解決方案:IronPDF的 Chromium 引擎正確處理現代 CSS:

// This CSS now works with IronPDF
var html = @"
<style>
    .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
    .flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
    <div>Column 1</div>
    <div>Column 2</div>
    <div>Column 3</div>
</div>";

var pdf = renderer.RenderHtmlAsPdf(html);

問題 4:同步與異步渲染

wkhtmltopdf: 封裝是同步的,並且會阻塞執行緒。

解決方案:IronPDF支援異步渲染:

public async Task<byte[]> GeneratePdfAsync(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}

wkhtmltopdf 遷移檢查清單

遷移前任務

審核您的程式碼庫以識別所有 wkhtmltopdf 的使用:

# Find all wkhtmltopdf references
grep -r "Haukcode.WkHtmlToPdfDotNet\|WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa\|NReco.PdfGenerator" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
SHELL

找到並記錄需要移除的 wkhtmltopdf 二進制文件。 記錄當前設定(紙張尺寸,邊距,頁眉/頁腳)。

程式碼更新任務

  1. 移除所有 wkhtmltopdf 封裝 NuGet 套件
  2. 移除 wkhtmltopdf 二進制文件(wkhtmltopdf.exe, wkhtmltox.dll)
  3. 安裝IronPDFNuGet 套件
  4. 將命名空間導入從 Haukcode.WkHtmlToPdfDotNet (或您使用的封裝)更新到 IronPdf
  5. 將 SynchronizedConverter 替換為 ChromePdfRenderer
  6. 將 HtmlToPdfDocument 模式轉換為直接渲染方法
  7. 將 GlobalSettings 配置更新為 RenderingOptions
  8. 將邊距配置從 MarginSettings 轉換為單一屬性
  9. 更新佔位符語法([page] → {page}, [toPage] → {total-pages})
  10. 在啟動時新增IronPDF授權初始化

遷移後測試

遷移後,驗證以下方面:

  • 視覺比較 PDF 輸出(應改進現代 CSS 支援)
  • 驗證現代 CSS 渲染(CSS Grid 和 Flexbox 現在可用)
  • 測試帶有大量 JavaScript 的頁面
  • 安全掃描確認不再有 wkhtmltopdf 二進制文件
  • 負載測試進行性能比較

安全驗證

# Scan for any remaining wkhtmltopdf artifacts
find /var/www/ -name "*wkhtmlto*" 2>/dev/null
find /usr/local/bin/ -name "*wkhtmlto*" 2>/dev/null
docker images | grep wkhtmltopdf

# Check if any process is still using it
ps aux | grep wkhtmltopdf
SHELL

遷移到IronPDF的關鍵好處

從 wkhtmltopdf 遷移到IronPDF提供了幾個關鍵優勢:

安全: CVE-2022-35583 和所有 wkhtmltopdf 漏洞均被消除。IronPDF沒有已知的 CVE,並定期接收安全更新。

現代渲染引擎:IronPDF使用當前的 Chromium 引擎,確保完整的 CSS3、CSS Grid、Flexbox 和 ES6+ JavaScript 支援。 現代框架會正確渲染。

簡化的 API: 直接渲染方法取代了文件構建模式。 內建的 SaveAs() 方法消除了手動字節處理。

擴展功能: PDF 操作、數位簽名、PDF/A 合規性、水印和合併/分裂操作是 wkhtmltopdf 提供不了的內建功能。

主動開發:IronPDF經常更新以跟進當前的 .NET 版本,因此現代 .NET 和 C# 語言版本會在發佈時提供支援。

異步支援: 本地異步/等待支援可防止高負載網頁應用程式中的執行緒阻塞。

請注意: DinkToPdf, NReco, Rotativa, TuesPechkin, 和 wkhtmltopdf 是其各自所有者的註冊商標。 此網站與 DinkToPdf、NReco、Rotativa、TuesPechkin 或 wkhtmltopdf 無關聯、未經認可或未得到贊助。 所有產品名稱、標誌和品牌均為其各自所有者的財產。 比較僅供參考,反映撰寫時公開可用的資訊。
Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

...
閱讀更多

相關文章

Key in blue circle

立即免費取得 30 天試用金鑰。

Your trial license will be sent to your email address

無任何限制。100% 解鎖。無需信用卡。

bullet_checked無需信用卡或建立帳號無任何限制。100% 解鎖。無需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
預訂您的免費現場演示
Booking Badge

受到全球數百萬工程師的信任

Iron Software的客戶標誌
獲取您的無義務諮詢
您的詳細資訊將始終保密。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
受到全球數百萬工程師的信任
立即獲取您的30天試用金鑰。
無需信用卡或帳戶建立
C# 用於PDF的NuGet程式庫
使用NuGet安裝

版本: 2026.10

PM > Install-Package IronPdf
nuget.org/packages/IronPdf/
  1. 在解決方案資源管理器,右鍵點選參考,管理NuGet包
  2. 選擇瀏覽並搜尋"IronPdf"
  3. 選擇套件並安裝
C# PDF DLL
下載DLL

版本: 2026.10

或者點擊此處下載Windows安裝程式。

  1. 下載並解壓IronPDF到類似~/Libs的位置,位於您的解決方案目錄中
  2. 在Visual Studio解決方案資源管理器,右鍵點選參考。選擇瀏覽,"IronPdf.dll"

授權從$999起