如何在 C# 中清理 PDF | IronPDF
WebView2, Microsoft 的嵌入式 Edge/Chromium 瀏覽器控制項 (Microsoft.Web.WebView2),為開發者提供了一種在 Windows 應用程式中顯示網頁內容的方法。 然而,當開發團隊嘗試使用 WebView2 進行 PDF 生成時,會遇到架構上的限制,這使得它不適合用於無頭和伺服器場景。 WebView2 是一種為 UI 應用設計的瀏覽器嵌入控制項,並不是 PDF 生成程式庫。
本指南提供從 WebView2 遷移到IronPDF的路徑,包含程式碼比較和一個實用的範例,適合需要可靠 PDF 生成的 .NET 開發者。
為什麼 WebView2 不適合做 PDF 生成
在檢視遷移路徑之前,了解一下為什麼 WebView2 不適合無頭 PDF 建立有幫助:
| 問題 | 影響 | 嚴重性 |
|---|---|---|
| 記憶體洩漏 | 在長時間運行的進程中報告的記憶體增長,這些進程反覆建立 WebView2 實例。 | 高 |
| 僅限 Windows | 不支持 Linux、macOS、Docker 或非 Windows 的雲環境 | 關鍵 |
| 需要 UI 執行緒 | 必須在包含消息泵的 STA 執行緒上運行。不適用於 Web 伺服器或背景 API。 | 關鍵 |
| 非能為 PDF 設計 | PrintToPdfAsync 是次要的能力,非核心功能 |
高 |
| 在服務中不穩定 | 在 Windows 服務和背景工作中報告的崩潰和卡死 | 高 |
| 復雜的異步流 | 導航事件、完成回調、競賽條件 | 高 |
| Edge 執行環境的依存性 | 需要目標計算機上安裝 Edge WebView2 執行環境 | 中等 |
| 無頭模式 | 圍繞 UI 控制進行設計; 不是無頭渲染器 | 中等 |
| 性能 | 啟動緩慢,資源消耗大 | 中等 |
| 沒有 PDF 支持故事 | Microsoft 並不將 WebView2 定位為 PDF 生成產品 | 中等 |
真實世界的失敗場景
這些程式碼模式通常在生產中引起問題:
// WARNING: These patterns are known to cause problems in headless / server scenarios
//問題1: Memory growth - creates a new WebView2 per PDF
public async Task<byte[]> GeneratePdf(string html) // High call volume accumulates memory
{
using var webView = new WebView2(); // Disposal does not fully reclaim native resources
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.NavigateToString(html);
// ... memory growth reported over time
}
//問題2: UI thread requirement - crashes in ASP.NET
public IActionResult GenerateReport() // FAILS - no STA thread
{
var webView = new WebView2(); // InvalidOperationException
}
//問題3: Windows Service instability
public class PdfService : BackgroundService // Random crashes
{
protected override async Task ExecuteAsync(CancellationToken token)
{
// WebView2 + no message pump = hangs, crashes, undefined behavior
}
}
// WARNING: These patterns are known to cause problems in headless / server scenarios
//問題1: Memory growth - creates a new WebView2 per PDF
public async Task<byte[]> GeneratePdf(string html) // High call volume accumulates memory
{
using var webView = new WebView2(); // Disposal does not fully reclaim native resources
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.NavigateToString(html);
// ... memory growth reported over time
}
//問題2: UI thread requirement - crashes in ASP.NET
public IActionResult GenerateReport() // FAILS - no STA thread
{
var webView = new WebView2(); // InvalidOperationException
}
//問題3: Windows Service instability
public class PdfService : BackgroundService // Random crashes
{
protected override async Task ExecuteAsync(CancellationToken token)
{
// WebView2 + no message pump = hangs, crashes, undefined behavior
}
}
' WARNING: These patterns are known to cause problems in headless / server scenarios
'問題1: Memory growth - creates a new WebView2 per PDF
Public Async Function GeneratePdf(html As String) As Task(Of Byte()) ' High call volume accumulates memory
Using webView As New WebView2() ' Disposal does not fully reclaim native resources
Await webView.EnsureCoreWebView2Async()
webView.CoreWebView2.NavigateToString(html)
' ... memory growth reported over time
End Using
End Function
'問題2: UI thread requirement - crashes in ASP.NET
Public Function GenerateReport() As IActionResult ' FAILS - no STA thread
Dim webView As New WebView2() ' InvalidOperationException
' Additional logic needed to handle UI thread requirement
Return Nothing
End Function
'問題3: Windows Service instability
Public Class PdfService
Inherits BackgroundService ' Random crashes
Protected Overrides Async Function ExecuteAsync(token As CancellationToken) As Task
' WebView2 + no message pump = hangs, crashes, undefined behavior
End Function
End Class
IronPDF與 WebView2: 功能比較
了解結構差異有助於技術決策者評估遷移投資:
| 方面 | WebView2 | IronPDF |
|---|---|---|
| 用途 | 瀏覽器控制(UI) | PDF 程式庫(用於 PDF 設計) |
| 投產準備 | 否 | 是 |
| 記憶體管理 | 在長時間運行中報告的記憶體增長 | 穩定,適當處理 |
| 平台支持 | 僅限於Windows | Windows, Linux, macOS, Docker |
| 執行緒要求 | STA + 消息泵 | 支持任何執行緒 |
| 伺服器/雲 | 不支持 | 支援 |
| Azure/AWS/GCP | 有問題 | 完美運作 |
| Docker | 不可能 | 提供官方映像 |
| ASP.NET Core | 無法工作 | 一流支持 |
| 背景服務 | 不穩定 | 穩定 |
| 支持的上下文 | 僅限 WinForms/WPF | 任何 .NET 上下文:控制台、網頁桌面 |
| HTML 到 PDF | 基本 | 全面 |
| URL至PDF | 基本 | 全面 |
| 頁首/頁尾 | 否 | 是(HTML) |
| 水印 | 否 | 是 |
| 合併PDF | 否 | 是 |
| 分割PDF | 否 | 是 |
| 數位簽名 | 否 | 是 |
| 密碼保護 | 否 | 是 |
| PDF/A合規性 | 否 | 是 |
| 專業支持 | 無 PDF 支持 | 是 |
| 文件 | 有限 | 廣泛的 |
快速開始:從 WebView2 遷移到 IronPDF
可以立即透過這些基本步驟開始遷移。
步驟 1:移除 WebView2 套件
dotnet remove package Microsoft.Web.WebView2
dotnet remove package Microsoft.Web.WebView2
或者從您的專案文件中移除:
<PackageReference Include="Microsoft.Web.WebView2" Version="*" Remove />
<PackageReference Include="Microsoft.Web.WebView2" Version="*" Remove />
步驟 2:安裝 IronPDF
dotnet add package IronPdf
步驟 3:更新命名空間
用IronPDF命名空間替換 WebView2 命名空間:
// Before (WebView2)
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
// After (IronPDF)
using IronPdf;
// Before (WebView2)
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
// After (IronPDF)
using IronPdf;
Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2.WinForms
' After (IronPDF)
Imports IronPdf
步驟 4:初始化授權
在應用啓動時新增授權初始化:
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
程式碼遷移範例
將HTML轉換為PDF
最基本的操作揭示了這些 .NET PDF 方法之間的複雜性差異。
WebView2 方法:
// NuGet: Install-Package Microsoft.Web.WebView2
// (the WinForms host lives in the same package; no separate .WinForms package)
// Requires the Edge WebView2 Runtime installed on the target machine. Windows-only.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.NavigateToString("<html><body><h1>Hello World</h1></body></html>");
await Task.Delay(2000);
// PrintToPdfAsync(path, settings) returns Task<bool>; null = default settings
bool ok = await webView.CoreWebView2.PrintToPdfAsync("output.pdf", null);
}
}
// NuGet: Install-Package Microsoft.Web.WebView2
// (the WinForms host lives in the same package; no separate .WinForms package)
// Requires the Edge WebView2 Runtime installed on the target machine. Windows-only.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.NavigateToString("<html><body><h1>Hello World</h1></body></html>");
await Task.Delay(2000);
// PrintToPdfAsync(path, settings) returns Task<bool>; null = default settings
bool ok = await webView.CoreWebView2.PrintToPdfAsync("output.pdf", null);
}
}
Imports System
Imports System.IO
Imports System.Threading.Tasks
Imports Microsoft.Web.WebView2.WinForms
Imports Microsoft.Web.WebView2.Core
Module Program
Async Function Main() As Task
Dim webView As New WebView2()
Await webView.EnsureCoreWebView2Async()
webView.CoreWebView2.NavigateToString("<html><body><h1>Hello World</h1></body></html>")
Await Task.Delay(2000)
' PrintToPdfAsync(path, settings) returns Task(Of Boolean); Nothing = default settings
Dim ok As Boolean = Await webView.CoreWebView2.PrintToPdfAsync("output.pdf", Nothing)
End Function
End Module
IronPDF 方法:
// NuGet: Install-Package IronPdf
using IronPdf;
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;
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");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<html><body><h1>Hello World</h1></body></html>")
pdf.SaveAs("output.pdf")
End Sub
End Class
WebView2 版本需要包含 EnsureCoreWebView2Async() 的異步初始化,使用 NavigateToString() 的導航,等待渲染的 Task.Delay(2000),以及最後返回 Task<bool> 表示成功的 PrintToPdfAsync 呼叫。IronPDF消除了這些繁瑣——建立一個渲染器、渲染 HTML、保存。
如需進階 HTML 到 PDF 的場景,請參見 HTML 到 PDF 轉換指南。
將 URL 轉換為 PDF
URL 到 PDF 的轉換展示了 WebView2 的複雜異步導航流程。
WebView2 方法:
// NuGet: Install-Package Microsoft.Web.WebView2
// (Edge Chromium control; requires Edge WebView2 Runtime; Windows-only.)
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
var tcs = new TaskCompletionSource<bool>();
webView.CoreWebView2.NavigationCompleted += (s, e) => tcs.SetResult(true);
webView.CoreWebView2.Navigate("https://example.com");
await tcs.Task;
await Task.Delay(1000);
var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
"Page.printToPDF",
"{\"printBackground\": true}"
);
var base64 = System.Text.Json.JsonDocument.Parse(result).RootElement.GetProperty("data").GetString();
File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64));
}
}
// NuGet: Install-Package Microsoft.Web.WebView2
// (Edge Chromium control; requires Edge WebView2 Runtime; Windows-only.)
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
var tcs = new TaskCompletionSource<bool>();
webView.CoreWebView2.NavigationCompleted += (s, e) => tcs.SetResult(true);
webView.CoreWebView2.Navigate("https://example.com");
await tcs.Task;
await Task.Delay(1000);
var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
"Page.printToPDF",
"{\"printBackground\": true}"
);
var base64 = System.Text.Json.JsonDocument.Parse(result).RootElement.GetProperty("data").GetString();
File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64));
}
}
Imports System
Imports System.IO
Imports System.Threading.Tasks
Imports Microsoft.Web.WebView2.WinForms
Imports Microsoft.Web.WebView2.Core
Module Program
Async Function Main() As Task
Dim webView As New WebView2()
Await webView.EnsureCoreWebView2Async()
Dim tcs As New TaskCompletionSource(Of Boolean)()
AddHandler webView.CoreWebView2.NavigationCompleted, Sub(s, e) tcs.SetResult(True)
webView.CoreWebView2.Navigate("https://example.com")
Await tcs.Task
Await Task.Delay(1000)
Dim result As String = Await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
"Page.printToPDF",
"{""printBackground"": true}"
)
Dim base64 As String = System.Text.Json.JsonDocument.Parse(result).RootElement.GetProperty("data").GetString()
File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64))
End Function
End Module
IronPDF 方法:
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("output.pdf")
End Sub
End Class
WebView2 需要建立一個 TaskCompletionSource,訂閱 NavigationCompleted 事件,呼叫 CallDevToolsProtocolMethodAsync,解析 JSON 響應,並手動解碼 base64 資料。IronPDF提供一個專用的 RenderUrlAsPdf 方法,這個方法在內部處理所有複雜性。
查看 URL 到 PDF 文件,了解認證和自定義標頭選項。
從 HTML 文件生成自定義 PDF 設置
配置頁面方向、邊距和紙張大小需要不同的方法。
WebView2 方法:
// NuGet: Install-Package Microsoft.Web.WebView2
// CreatePrintSettings() lives on CoreWebView2Environment.
// Margin* / PageWidth / PageHeight on CoreWebView2PrintSettings are in INCHES.
// PrintToPdfAsync(path, settings) returns Task<bool> (true on success) — not a stream.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
string htmlFile = Path.Combine(Directory.GetCurrentDirectory(), "input.html");
webView.CoreWebView2.Navigate(htmlFile);
await Task.Delay(3000);
CoreWebView2PrintSettings printSettings = webView.CoreWebView2.Environment.CreatePrintSettings();
printSettings.Orientation = CoreWebView2PrintOrientation.Landscape;
printSettings.MarginTop = 0.5; // inches
printSettings.MarginBottom = 0.5; // inches
printSettings.ShouldPrintBackgrounds = true;
bool ok = await webView.CoreWebView2.PrintToPdfAsync("custom.pdf", printSettings);
Console.WriteLine(ok ? "Custom PDF created" : "PrintToPdfAsync returned false");
}
}
// NuGet: Install-Package Microsoft.Web.WebView2
// CreatePrintSettings() lives on CoreWebView2Environment.
// Margin* / PageWidth / PageHeight on CoreWebView2PrintSettings are in INCHES.
// PrintToPdfAsync(path, settings) returns Task<bool> (true on success) — not a stream.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Web.WebView2.Core;
using Microsoft.Web.WebView2.WinForms;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
string htmlFile = Path.Combine(Directory.GetCurrentDirectory(), "input.html");
webView.CoreWebView2.Navigate(htmlFile);
await Task.Delay(3000);
CoreWebView2PrintSettings printSettings = webView.CoreWebView2.Environment.CreatePrintSettings();
printSettings.Orientation = CoreWebView2PrintOrientation.Landscape;
printSettings.MarginTop = 0.5; // inches
printSettings.MarginBottom = 0.5; // inches
printSettings.ShouldPrintBackgrounds = true;
bool ok = await webView.CoreWebView2.PrintToPdfAsync("custom.pdf", printSettings);
Console.WriteLine(ok ? "Custom PDF created" : "PrintToPdfAsync returned false");
}
}
Imports System
Imports System.IO
Imports System.Threading.Tasks
Imports Microsoft.Web.WebView2.Core
Imports Microsoft.Web.WebView2.WinForms
Module Program
Async Function Main() As Task
Dim webView As New WebView2()
Await webView.EnsureCoreWebView2Async()
Dim htmlFile As String = Path.Combine(Directory.GetCurrentDirectory(), "input.html")
webView.CoreWebView2.Navigate(htmlFile)
Await Task.Delay(3000)
Dim printSettings As CoreWebView2PrintSettings = webView.CoreWebView2.Environment.CreatePrintSettings()
printSettings.Orientation = CoreWebView2PrintOrientation.Landscape
printSettings.MarginTop = 0.5 ' inches
printSettings.MarginBottom = 0.5 ' inches
printSettings.ShouldPrintBackgrounds = True
Dim ok As Boolean = Await webView.CoreWebView2.PrintToPdfAsync("custom.pdf", printSettings)
Console.WriteLine(If(ok, "Custom PDF created", "PrintToPdfAsync returned false"))
End Function
End Module
IronPDF 方法:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 50;
renderer.RenderingOptions.MarginBottom = 50;
string htmlFile = Path.Combine(Directory.GetCurrentDirectory(), "input.html");
var pdf = renderer.RenderHtmlFileAsPdf(htmlFile);
pdf.SaveAs("custom.pdf");
Console.WriteLine("Custom PDF created");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
using System.IO;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 50;
renderer.RenderingOptions.MarginBottom = 50;
string htmlFile = Path.Combine(Directory.GetCurrentDirectory(), "input.html");
var pdf = renderer.RenderHtmlFileAsPdf(htmlFile);
pdf.SaveAs("custom.pdf");
Console.WriteLine("Custom PDF created");
}
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System
Imports System.IO
Module Program
Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
renderer.RenderingOptions.MarginTop = 50
renderer.RenderingOptions.MarginBottom = 50
Dim htmlFile As String = Path.Combine(Directory.GetCurrentDirectory(), "input.html")
Dim pdf = renderer.RenderHtmlFileAsPdf(htmlFile)
pdf.SaveAs("custom.pdf")
Console.WriteLine("Custom PDF created")
End Sub
End Module
WebView2 需要一個 3 秒的 Task.Delay(不可靠的估計),通過 CoreWebView2.Environment 建立列印設置,以及對 PrintToPdfAsync(path, settings) 進行的 await,該設定返回 Task<bool> 而不是流。 WebView2 用英寸表達邊距;IronPDF通過直接的 RenderingOptions 屬性使用毫米。
使用開發工具協議的高級 PDF 選項
複雜的 WebView2 配置需要開發工具協議交互。
WebView2 方法:
// NuGet: Install-Package Microsoft.Web.WebView2
// Uses raw Chrome DevTools Protocol via CallDevToolsProtocolMethodAsync.
// (Page.printToPDF returns base64 in result.data; units are inches.)
using System;
using System.IO;
using System.Threading.Tasks;
using System.Text.Json;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
var htmlPath = Path.GetFullPath("document.html");
var tcs = new TaskCompletionSource<bool>();
webView.CoreWebView2.NavigationCompleted += (s, e) => tcs.SetResult(true);
webView.CoreWebView2.Navigate($"file:///{htmlPath}");
await tcs.Task;
await Task.Delay(1000);
var options = new
{
landscape = false,
printBackground = true,
paperWidth = 8.5,
paperHeight = 11,
marginTop = 0.4,
marginBottom = 0.4,
marginLeft = 0.4,
marginRight = 0.4
};
var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
"Page.printToPDF",
JsonSerializer.Serialize(options)
);
var base64 = JsonDocument.Parse(result).RootElement.GetProperty("data").GetString();
File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64));
}
}
// NuGet: Install-Package Microsoft.Web.WebView2
// Uses raw Chrome DevTools Protocol via CallDevToolsProtocolMethodAsync.
// (Page.printToPDF returns base64 in result.data; units are inches.)
using System;
using System.IO;
using System.Threading.Tasks;
using System.Text.Json;
using Microsoft.Web.WebView2.WinForms;
using Microsoft.Web.WebView2.Core;
class Program
{
static async Task Main()
{
var webView = new WebView2();
await webView.EnsureCoreWebView2Async();
var htmlPath = Path.GetFullPath("document.html");
var tcs = new TaskCompletionSource<bool>();
webView.CoreWebView2.NavigationCompleted += (s, e) => tcs.SetResult(true);
webView.CoreWebView2.Navigate($"file:///{htmlPath}");
await tcs.Task;
await Task.Delay(1000);
var options = new
{
landscape = false,
printBackground = true,
paperWidth = 8.5,
paperHeight = 11,
marginTop = 0.4,
marginBottom = 0.4,
marginLeft = 0.4,
marginRight = 0.4
};
var result = await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
"Page.printToPDF",
JsonSerializer.Serialize(options)
);
var base64 = JsonDocument.Parse(result).RootElement.GetProperty("data").GetString();
File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64));
}
}
Imports System
Imports System.IO
Imports System.Threading.Tasks
Imports System.Text.Json
Imports Microsoft.Web.WebView2.WinForms
Imports Microsoft.Web.WebView2.Core
Module Program
Async Function Main() As Task
Dim webView As New WebView2()
Await webView.EnsureCoreWebView2Async()
Dim htmlPath As String = Path.GetFullPath("document.html")
Dim tcs As New TaskCompletionSource(Of Boolean)()
AddHandler webView.CoreWebView2.NavigationCompleted, Sub(s, e) tcs.SetResult(True)
webView.CoreWebView2.Navigate($"file:///{htmlPath}")
Await tcs.Task
Await Task.Delay(1000)
Dim options = New With {
.landscape = False,
.printBackground = True,
.paperWidth = 8.5,
.paperHeight = 11,
.marginTop = 0.4,
.marginBottom = 0.4,
.marginLeft = 0.4,
.marginRight = 0.4
}
Dim result As String = Await webView.CoreWebView2.CallDevToolsProtocolMethodAsync(
"Page.printToPDF",
JsonSerializer.Serialize(options)
)
Dim base64 As String = JsonDocument.Parse(result).RootElement.GetProperty("data").GetString()
File.WriteAllBytes("output.pdf", Convert.FromBase64String(base64))
End Function
End Module
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.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.MarginLeft = 40;
renderer.RenderingOptions.MarginRight = 40;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
var pdf = renderer.RenderHtmlFileAsPdf("document.html");
pdf.SaveAs("output.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.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.MarginLeft = 40;
renderer.RenderingOptions.MarginRight = 40;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
var pdf = renderer.RenderHtmlFileAsPdf("document.html");
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports IronPdf.Rendering
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
renderer.RenderingOptions.MarginTop = 40
renderer.RenderingOptions.MarginBottom = 40
renderer.RenderingOptions.MarginLeft = 40
renderer.RenderingOptions.MarginRight = 40
renderer.RenderingOptions.PrintHtmlBackgrounds = True
Dim pdf = renderer.RenderHtmlFileAsPdf("document.html")
pdf.SaveAs("output.pdf")
End Sub
End Class
WebView2 需要構造匿名物件,序列化為 JSON,呼叫 DevTools Protocol 方法,解析 JSON 響應,並手動解碼 base64。IronPDF 提供帶有明確名稱和枚舉值如 PdfPaperSize.Letter 的型別屬性。
WebView2 API 到IronPDF映射參考
此映射透過展示直接的 API 等價加速遷移:
| WebView2 API | IronPDF等價 |
|---|---|
new WebView2() |
new ChromePdfRenderer() |
EnsureCoreWebView2Async() |
無 |
NavigateToString(html) + PrintToPdfAsync() |
RenderHtmlAsPdf(html) |
Navigate(url) + PrintToPdfAsync() |
RenderUrlAsPdf(url) |
PrintSettings.PageWidth |
RenderingOptions.PaperSize |
PrintSettings.PageHeight |
RenderingOptions.PaperSize |
PrintSettings.MarginTop |
RenderingOptions.MarginTop |
PrintSettings.Orientation |
RenderingOptions.PaperOrientation |
ExecuteScriptAsync() |
HTML中的JavaScript |
AddScriptToExecuteOnDocumentCreatedAsync() |
HTML <script> 標籤 |
| 導航事件 | WaitFor.JavaScript() |
CallDevToolsProtocolMethodAsync("Page.printToPDF") |
RenderHtmlAsPdf() |
常見遷移問題及解決方案
問題 1:記憶體增長
WebView2 問題:記憶體增長報告在長時間運行的進程中,這些進程重複建立 WebView2 實例,尤其在沒有穩定的消息泵的情況下。
IronPDF 解決方案:可預測的消除和 using 良好的生命週期:
//IronPDF- clean memory management
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
pdf.SaveAs("output.pdf");
} // Properly disposed
//IronPDF- clean memory management
using (var pdf = renderer.RenderHtmlAsPdf(html))
{
pdf.SaveAs("output.pdf");
} // Properly disposed
Imports IronPdf
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Using
問題 2:網頁應用中沒有 UI 執行緒
WebView2 問題:需要包含消息泵的 STA 執行緒。ASP.NET Core 控制器無法建立 WebView2 實例。
IronPDF 解決方案:支援任何執行緒:
// ASP.NET Core - just works
public async Task<IActionResult> GetPdf()
{
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
// ASP.NET Core - just works
public async Task<IActionResult> GetPdf()
{
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
Imports System.Threading.Tasks
Imports Microsoft.AspNetCore.Mvc
Public Class YourController
Inherits Controller
Public Async Function GetPdf() As Task(Of IActionResult)
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return File(pdf.BinaryData, "application/pdf")
End Function
End Class
問題 3:導航事件複雜性
WebView2 問題:必須處理 TaskCompletionSource 的異步導航事件、完成回調以及競賽條件。
IronPDF 解決方案:同步或異步單一方法呼叫:
// Simple and predictable
var pdf = renderer.RenderHtmlAsPdf(html);
// or
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
// Simple and predictable
var pdf = renderer.RenderHtmlAsPdf(html);
// or
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
問題 4:測量單位
WebView2 使用英寸為尺寸單位(如:8.5 x 11 用於 Letter)。 IronPDF 使用毫米提供更精確的尺寸。
轉換方法:
// WebView2: PageWidth = 8.27 (inches for A4)
// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// Or custom size in mm
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(210, 297);
// WebView2: PageWidth = 8.27 (inches for A4)
// IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
// Or custom size in mm
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(210, 297);
' WebView2: PageWidth = 8.27 (inches for A4)
' IronPDF: Use enum
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
' Or custom size in mm
renderer.RenderingOptions.SetCustomPaperSizeInMillimeters(210, 297)
WebView2 遷移檢查表
遷移前任務
記錄您程式碼庫中所有 WebView2 PDF 生成程式碼。 確定 WebView2 引起問題的地方(記憶體洩漏、崩潰、部署問題)。 查看 IronPDF 文件 以熟悉其功能。
程式碼更新任務
- 移除 Microsoft.Web.WebView2 NuGet 套件
- 安裝IronPDFNuGet 套件
- 如僅用於 PDF 生成,移除 WinForms/WPF 依賴
- 用
ChromePdfRenderer替換 WebView2 程式碼 - 移除 STA 執行緒要求
- 移除導航事件處理程式和
TaskCompletionSource模式 - 移除
Task.Delay破解 - 在啟動時新增IronPDF授權初始化
遷移後測試
遷移後,驗證以下方面:
- 在目標環境中測試(如適用,ASP.NET、Docker、Linux)
- 驗證 PDF 輸出質量符合期望
- 測試包含大量 JavaScript 的頁面是否正確呈現
- 驗證頁眉和頁腳是否能與IronPDF的 HTML 功能協同運作
- 在長期運行的操作中測試記憶體穩定性
- 測試無記憶體累積的長時間運行場景
部署更新
- 如適用,更新 Docker 映像(移除 Edge WebView2 執行環境)
- 從伺服器需求中移除 Edge WebView2 執行環境依賴
- 更新伺服器需求文件
- 驗證跨平台部署是否能在目標平台上運行

