跳過到頁腳內容
遷移指南

如何在 C# 中從 wkhtmltopdf 轉移到 IronPDF

wkhtmltopdf 一直是使用 Qt WebKit 將 HTML 文件轉換為 PDF 的廣泛工具。 儘管該專案因其命令列功能和免費授權而廣受開發人員歡迎,但現在卻出現了再也不能忽視的重大安全風險。 該函式庫已於 2016-2017 年正式棄用,一個 CRITICAL 嚴重性漏洞 (CVE-2022-35583) 仍永久未修補。

本指南提供了從wkhtmltopdf到IronPDF的完整轉換路徑,並提供逐步說明、程式碼比較以及實用範例,適合需要從應用程式中消除此安全風險的專業 .NET 開發人員使用。

重要安全警告:CVE-2022-35583

wkhtmltopdf 包含永遠無法修復的重要安全漏洞:

問題 嚴重性 狀態
CVE-2022-35583 關鍵 (9.8/10) UNPATCHED 未修訂。
SSRF 漏洞 基礎架構接管風險 UNPATCHED 未修訂。
最近更新 2016-2017 被拋棄
WebKit版本 2015 (Qt WebKit) OBSOLETE 刪除。
CSS 網格支援 破損
Flexbox 支援 部分的 破損
ES6+ JavaScript 破損

SSRF 攻擊如何運作

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


<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>

<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,繞過防火牆和安全控制。

受影響的套用程式庫

wkhtmltopdf 的所有 .NET wrapper 都會繼承這些漏洞:

包裝程式庫 狀態 安全風險
DinkToPdf ⚠️ CRITICAL
<強>Rotativa</強 ⚠️ CRITICAL
TuesPechkin ⚠️ CRITICAL
WkHtmlToPdf-DotNet ⚠️ CRITICAL
NReco.PdfGenerator 使用 wkhtmltopdf ⚠️ CRITICAL

如果您使用任何這些函式庫,就有可能受到 CVE-2022-35583 的攻擊。

IronPDFvs wkhtmltopdf:功能比較

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

特點 wkhtmltopdf IronPDF
授權 LGPLv3 (免費) 商業的
渲染引擎 Qt WebKit (2015) 目前的 Chromium 引擎
安全漏洞 CVE-2022-35583, 主要未修補問題 無已知 CVE
主動維護 已放棄,自 2017 年起無任何有意義的更新 定期發佈,積極維護
支援現代網路標準 受限(flexbox 斷裂、無 CSS Grid) 支援
整合與支援 僅限於社群論壇 廣泛的文件和專門的支援
CSS 網格 ❌ 不支援 ✅ 已支援
<強>Flexbox</強 ⚠️ 破譯 ✅ 已支援
ES6+ JavaScript ❌ 不支援 ✅ 已支援
Async/等待 ❌ 不支援 ✅ 已支援
PDF 操作 ❌ 不支援 ✅ 已支援
數位簽名 ❌ 不支援 ✅ 已支援
PDF/A合規性 ❌ 不支援 ✅ 已支援

快速入門:wkhtmltopdf 到IronPDF的遷移。

只要完成這些基本步驟,就可以立即開始遷移。

步驟 1:移除wkhtmltopdf套件和二進位檔案

移除所有wkhtmltopdfwrapper 套件:

# Removewkhtmltopdfwrapper (whichever you're using)
dotnet remove package WkHtmlToPdf-DotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

# Removewkhtmltopdfbinary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
# Removewkhtmltopdfwrapper (whichever you're using)
dotnet remove package WkHtmlToPdf-DotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

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

步驟 2:安裝 IronPDF

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

步驟 3:更新命名空間

以IronPDF命名空間取代wkhtmltopdf命名空間:

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

// After (IronPDF)
using IronPdf;
// Before (wkhtmltopdf)
using WkHtmlToPdfDotNet;
using WkHtmlToPdfDotNet.Contracts;

// After (IronPDF)
using IronPdf;
' Before (wkhtmltopdf)
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts

' After (IronPDF)
Imports IronPdf
$vbLabelText   $csharpLabel

步驟 4:初始化授權

在應用程式啟動時加入授權初始化:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

程式碼遷移範例

將 HTML 轉換為 PDF

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

wkhtmltopdf 方法:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                New ObjectSettings() With {
                    .HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("output.pdf", pdf)
    End Sub
End Class
$vbLabelText   $csharpLabel

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");
    }
}
// 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");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

wkhtmltopdf 需要建立一個 SynchronizedConverter,並使用 PdfTools 建構一個 HtmlToPdfDocument,使用 @@--CODE-20560--@@ 和 @@--CODE-20561--@@ 設定屬性,包括 @@--CODE-20562--@@、@@--CODE-20563--@@ 和 @@--CODE-20564--@@ 等,呼叫 @@--CODE-20565--@@ 取得原始位元組,並使用 @@--CODE-20566--@@ 手動寫入檔案。

IronPDF 完全消除了這種繁瑣的步驟——創建一個 ChromePdfRenderer,呼叫 RenderHtmlAsPdf(),然後使用內建的 SaveAs() 方法。

如需進階的 HTML 至IronPDF情境,請參閱 HTML 至 PDF 轉換指南

將 URL 轉換為 PDF

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

wkhtmltopdf 方法:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                New ObjectSettings() With {
                    .Page = "https://www.example.com"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("webpage.pdf", pdf)
    End Sub
End Module
$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");
    }
}
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

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

探索URL至PDF文件的認證和自訂標頭選項。

自訂設定:具有頁面組態的 HTML 檔案

配置方向、邊界和紙張大小需要不同的方法。

wkhtmltopdf 方法:

// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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);
    }
}
// NuGet: Install-Package WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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);
    }
}
' NuGet: Install-Package WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Landscape,
                .PaperSize = PaperKind.A4,
                .Margins = New MarginSettings() With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
            },
            .Objects = {
                New ObjectSettings() With {
                    .Page = "input.html",
                    .WebSettings = New WebSettings() With {.DefaultEncoding = "utf-8"}
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("custom-output.pdf", pdf)
    End Sub
End Class
$vbLabelText   $csharpLabel

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");
    }
}
// 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");
    }
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System

Class Program
    Shared Sub Main()
        Dim renderer As 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

        Dim pdf = renderer.RenderHtmlFileAsPdf("input.html")
        pdf.SaveAs("custom-output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

wkhtmltopdf 將設定嵌套在 GlobalSettingsObjects 中,並將 MarginSettings 作為單獨的物件。IronPDF提供直接的 RenderingOptions 屬性,其名稱清晰明了,例如 PaperOrientationMarginTopPaperSize

wkhtmltopdfAPI 到IronPDF的映射參考。

此對應可透過顯示直接的 API 對應關係來加速遷移:

CLI 到IronPDF的映射

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

C# Wrapper API 對應。

wkhtmltopdf Wrapper IronPDF
SynchronizedConverter ChromePdfRenderer
HtmlToPdfDocument RenderingOptions
GlobalSettings.Out pdf.SaveAs()
GlobalSettings.PaperSize RenderingOptions.PaperSize
GlobalSettings.Orientation RenderingOptions.PaperOrientation
GlobalSettings.Margins RenderingOptions.Margin*
ObjectSettings.Page RenderHtmlFileAsPdf()
ObjectSettings.HtmlContent RenderHtmlAsPdf()
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
};
// 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
};
' Before (wkhtmltopdf)
FooterSettings = New With {.Left = "Page [page] of [toPage]"}

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

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

第 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);
// 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);
Dim html As String = "
<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>"

Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

第 4 期:同步與非同步渲染

wkhtmltopdf:裹包是同步和阻塞線程。

解決方案:IronPDF支援動態渲染:

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

Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
    Dim renderer As New ChromePdfRenderer()
    Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
    Return pdf.BinaryData
End Function
$vbLabelText   $csharpLabel

wkhtmltopdf遷移清單

遷移前的任務

審核您的程式碼庫,找出所有wkhtmltopdf的用法:

# Find allwkhtmltopdfreferences
grep -r "WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
# Find allwkhtmltopdfreferences
grep -r "WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
SHELL

找出並記錄wkhtmltopdf二進位檔案,以便移除。 文件目前的設定(紙張大小、邊界、頁首/頁腳)。

程式碼更新任務

1.移除所有wkhtmltopdfwrapper NuGet 套件 2.移除wkhtmltopdf的二進位檔 (wkhtmltopdf.exe, wkhtmltox.dll) 3.安裝IronPDFNuGet 套件

  1. 將命名空間導入從 WkHtmlToPdfDotNet 更新為 IronPdf
  2. SynchronizedConverter 替換為 ChromePdfRenderer
  3. HtmlToPdfDocument 模式轉換為直接渲染方法
  4. GlobalSettings 配置更新為 RenderingOptions
  5. 將邊距配置從 MarginSettings 轉換為單獨的屬性
  6. 更新佔位語法([page]{page}, [toPage]{total-pages}) 10.在啟動時增加IronPDF授權初始化功能

後遷移測試

轉移後,驗證這些方面:

  • PDF 輸出的視覺比較 (應使用現代 CSS 支援來改善)
  • 驗證現代的 CSS 渲染(CSS Grid 和 Flexbox 現在可以使用)
  • 測試 JavaScript 繁重的頁面
  • 安全掃描以確認沒有wkhtmltopdf的二進位檔存在
  • 性能比較的負載測試

安全性驗證

# Scan for any remainingwkhtmltopdfartifacts
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
# Scan for any remainingwkhtmltopdfartifacts
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無法提供的內建功能。

積極開發:隨著 .NET 10 和 C# 14 的普及,IronPDF 將持續更新,確保與目前和未來的 .NET 版本相容。

非同步支援:透過原生 async/await 支持,防止高負載 Web 應用程式中的執行緒阻塞。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我