如何用 C# 從 PuppeteerSharp 轉移到 IronPDF
從PuppeteerSharp轉換到IronPDF可將您的 PDF 生成工作流程從依賴 300MB 以上的瀏覽器自動化工具轉換為具有自動記憶體管理功能的專用 PDF 函式庫。 本指南提供完整的逐步遷移路徑,可消除 Chromium 下載、解決記憶體洩漏問題,並提供全面的 PDF 操作功能。
為什麼要從PuppeteerSharp轉移到 IronPDF?
瞭解 PuppeteerSharp。
PuppeteerSharp 是 Google 的 Puppeteer 的 .NET 移植,將瀏覽器自動化功能帶入 C#。 它使用 Chrome 內建的列印至 PDF 功能來產生 PDF,就像在瀏覽器中按下 Ctrl+P 一樣。 這會產生為紙張最佳化的印刷就緒輸出,與您在螢幕上看到的不同。
PuppeteerSharp 是專為網頁測試和搜刮而設計,而非文件生成。 使用PuppeteerSharp生成 PDF 虽然能够胜任,但会帶来巨大的生產挑战。
瀏覽器自動化問題
PuppeteerSharp 是專為瀏覽器自動化而設計,而非文件生成。 這在用於 PDF 時會產生基本問題:
1.首次使用前需下載 300MB+ Chromium。PuppeteerSharp的一個顯著缺點是其龐大的部署規模,這主要是由於它捆綁了 Chromium 二進位檔案。 這種龐大的規模會使 Docker 映像變得臃腫,並在無伺服器環境中造成冷啟動問題。
2.負載下的記憶體洩漏需要手動回收瀏覽器。 眾所周知,PuppeteerSharp 在高負載狀態下會發生記憶體洩漏。 瀏覽器實體累積的記憶體必須以手動方式進行流程管理與回收。
3.複雜的 async 模式與瀏覽器生命週期管理。
4.Print-to-PDF 輸出(等同於 Ctrl+P,而非螢幕擷取)。 版面可能會回流,背景可能會依預設省略,而且輸出會以分頁方式列印,而非配合瀏覽器的視埠。
5.不支援 PDF/A 或 PDF/UA,以符合法規要求。PuppeteerSharp無法製作 PDF/A (歸檔) 或 PDF/UA (無障礙) 相容的文件。
6.無 PDF 操作 - 僅生成,無合併/分割/編輯。 雖然PuppeteerSharp能有效率地產生 PDF,但它缺乏進一步操作的功能,例如合併、分割、保護或編輯 PDF。
PuppeteerSharp與IronPDF的比較
| 範疇 | PuppeteerSharp | IronPDF |
|---|---|---|
| 主要目的 | 瀏覽器自動化 | 生成 PDF |
| Chromium相依性 | 300MB+ 獨立下載 | 內建最佳化引擎 |
| API複雜性 | 同步瀏覽器/網頁生命週期 | 同步單行字 |
| 初始化 | BrowserFetcher.DownloadAsync() + LaunchAsync |
new ChromePdfRenderer() |
| 記憶體管理 | 需要手動回收瀏覽器 | 自動化 |
| 負載下的記憶體 | 500MB+ 有洩漏 | ~50MB 穩定 |
| 冷啟動 | 45 秒以上 | ~20 秒 |
| PDF/A支援 | 無法提供 | 支援 |
| PDF/UA 可訪問性 | 無法提供 | 支援 |
| PDF編輯 | 無法提供 | 合併、分割、蓋章、編輯 |
| 數位簽名 | 無法提供 | 支援 |
| 線程安全 | 限額 | 全文 |
| 專業支援。 | 社區 | 有 SLA 的商業翻譯 |
平台支援
| 圖書館 |.NET Framework 4.7.2|.NET Core 3.1|.NET 6-8|.NET 10| | --------- | :---: | :---: | :---: | :---: ||IronPDF| 全文 | 全文 | 全文 | 全文 ||PuppeteerSharp| 限額 | 全文 | 全文 | 待辦的 | IronPDF 跨 .NET 平台的廣泛支援,可確保開發人員在各種環境中利用IronPDF而不會遇到相容性問題,為 2025 年和 2026 年的現代 .NET 應用程式提供靈活的選擇。
開始之前
先決條件
- .NET環境: .NET Framework 4.6.2+ 或.NET Core 3.1+ / .NET 5/6/7/8/9+
- NuGet存取權限:能夠安裝NuGet套件
- IronPDF許可證:請從IronPDF取得您的許可證密鑰。
NuGet 套件變更
# Remove PuppeteerSharp
dotnet remove package PuppeteerSharp
# Remove downloaded Chromium binaries (~300MB recovered)
# Delete the .local-chromium folder
# Add IronPDF
dotnet add package IronPdf
# Remove PuppeteerSharp
dotnet remove package PuppeteerSharp
# Remove downloaded Chromium binaries (~300MB recovered)
# Delete the .local-chromium folder
# Add IronPDF
dotnet add package IronPdf
IronPDF 不需要 BrowserFetcher.DownloadAsync() - 渲染引擎會自動捆綁。
授權組態
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
' Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
完整的 API 參考資料
命名空間變更
// Before: PuppeteerSharp
using PuppeteerSharp;
using PuppeteerSharp.Media;
using System.Threading.Tasks;
// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
// Before: PuppeteerSharp
using PuppeteerSharp;
using PuppeteerSharp.Media;
using System.Threading.Tasks;
// After: IronPDF
using IronPdf;
using IronPdf.Rendering;
' Before: PuppeteerSharp
Imports PuppeteerSharp
Imports PuppeteerSharp.Media
Imports System.Threading.Tasks
' After: IronPDF
Imports IronPdf
Imports IronPdf.Rendering
核心 API 對應
| PuppeteerSharp API | IronPDF API | 筆記 |
|---|---|---|
new BrowserFetcher().DownloadAsync() |
不需要 | 無需下載瀏覽器 |
Puppeteer.LaunchAsync(options) |
不需要 | 無瀏覽器管理 |
browser.NewPageAsync() |
不需要 | 無頁面上下文 |
page.GoToAsync(url) |
renderer.RenderUrlAsPdf(url) |
直接渲染 |
page.SetContentAsync(html) |
renderer.RenderHtmlAsPdf(html) |
直接渲染 |
page.PdfAsync(path) |
pdf.SaveAs(path) |
渲染後 |
await page.CloseAsync() |
不需要 | 自動清理 |
await browser.CloseAsync() |
不需要 | 自動清理 |
PdfOptions.Format |
RenderingOptions.PaperSize |
紙張大小 |
PdfOptions.Landscape |
RenderingOptions.PaperOrientation |
導向 |
PdfOptions.MarginOptions |
RenderingOptions.MarginTop/Bottom/Left/Right |
個別邊距 |
PdfOptions.PrintBackground |
RenderingOptions.PrintHtmlBackgrounds |
背景印刷 |
PdfOptions.HeaderTemplate |
RenderingOptions.HtmlHeader |
HTML 標頭 |
PdfOptions.FooterTemplate |
RenderingOptions.HtmlFooter |
HTML 頁腳 |
page.WaitForSelectorAsync() |
RenderingOptions.WaitFor.HtmlElementId |
等待元素 |
程式碼遷移範例
範例 1:基本 HTML 到 PDF 的轉換
之前 (PuppeteerSharp):
// NuGet: Install-Package PuppeteerSharp
using PuppeteerSharp;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
await using var page = await browser.NewPageAsync();
await page.SetContentAsync("<h1>Hello World</h1><p>This is a PDF document.</p>");
await page.PdfAsync("output.pdf");
}
}
// NuGet: Install-Package PuppeteerSharp
using PuppeteerSharp;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
await using var page = await browser.NewPageAsync();
await page.SetContentAsync("<h1>Hello World</h1><p>This is a PDF document.</p>");
await page.PdfAsync("output.pdf");
}
}
Imports PuppeteerSharp
Imports System.Threading.Tasks
Module Program
Async Function Main(args As String()) As Task
Dim browserFetcher = New BrowserFetcher()
Await browserFetcher.DownloadAsync()
Using browser = Await Puppeteer.LaunchAsync(New LaunchOptions With {
.Headless = True
})
Using page = Await browser.NewPageAsync()
Await page.SetContentAsync("<h1>Hello World</h1><p>This is a PDF document.</p>")
Await page.PdfAsync("output.pdf")
End Using
End Using
End Function
End Module
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF document.</p>");
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF document.</p>");
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main(args As String())
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF document.</p>")
pdf.SaveAs("output.pdf")
End Sub
End Class
本範例展示了基本的架構差異。PuppeteerSharp需要六個非同步操作:BrowserFetcher.DownloadAsync()(300MB+ Chromium 下載),Puppeteer.LaunchAsync(),browser.NewPageAsync(),page.SetContentAsync(),@@--CODE-19528--@@ 以及 @@--CODE-19529--@@ 進行適當的處置。
IronPDF 消除了所有這些複雜性:建立一個 ChromePdfRenderer,呼叫 RenderHtmlAsPdf(),以及 SaveAs()。 沒有 async 模式、沒有瀏覽器生命週期、沒有 Chromium 下載。IronPDF的方法提供了更簡潔的語法,並能更好地與現代 .NET 應用程式整合。 請參閱 HTML to PDF 文件,以瞭解全面的範例。
範例 2:URL 到 PDF 的轉換
之前 (PuppeteerSharp):
// NuGet: Install-Package PuppeteerSharp
using PuppeteerSharp;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
await using var page = await browser.NewPageAsync();
await page.GoToAsync("https://www.example.com");
await page.PdfAsync("webpage.pdf");
}
}
// NuGet: Install-Package PuppeteerSharp
using PuppeteerSharp;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
await using var page = await browser.NewPageAsync();
await page.GoToAsync("https://www.example.com");
await page.PdfAsync("webpage.pdf");
}
}
Imports PuppeteerSharp
Imports System.Threading.Tasks
Module Program
Async Function Main(args As String()) As Task
Dim browserFetcher = New BrowserFetcher()
Await browserFetcher.DownloadAsync()
Using browser = Await Puppeteer.LaunchAsync(New LaunchOptions With {
.Headless = True
})
Using page = Await browser.NewPageAsync()
Await page.GoToAsync("https://www.example.com")
Await page.PdfAsync("webpage.pdf")
End Using
End Using
End Function
End Module
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
}
}
Imports IronPdf
Class Program
Shared Sub Main(ByVal args As String())
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
PuppeteerSharp 使用 GoToAsync() 導覽至 URL,然後使用 PdfAsync()。IronPDF提供了一個單一的 RenderUrlAsPdf() 方法,可以在一次呼叫中處理導覽和 PDF 產生。 請參閱我們的 教學,瞭解更多資訊。
範例 3:自訂頁面設定與邊界
之前 (PuppeteerSharp):
// NuGet: Install-Package PuppeteerSharp
using PuppeteerSharp;
using PuppeteerSharp.Media;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
await using var page = await browser.NewPageAsync();
await page.SetContentAsync("<h1>Custom PDF</h1><p>With landscape orientation and margins.</p>");
await page.PdfAsync("custom.pdf", new PdfOptions
{
Format = PaperFormat.A4,
Landscape = true,
MarginOptions = new MarginOptions
{
Top = "20mm",
Bottom = "20mm",
Left = "20mm",
Right = "20mm"
}
});
}
}
// NuGet: Install-Package PuppeteerSharp
using PuppeteerSharp;
using PuppeteerSharp.Media;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
await using var page = await browser.NewPageAsync();
await page.SetContentAsync("<h1>Custom PDF</h1><p>With landscape orientation and margins.</p>");
await page.PdfAsync("custom.pdf", new PdfOptions
{
Format = PaperFormat.A4,
Landscape = true,
MarginOptions = new MarginOptions
{
Top = "20mm",
Bottom = "20mm",
Left = "20mm",
Right = "20mm"
}
});
}
}
Imports PuppeteerSharp
Imports PuppeteerSharp.Media
Imports System.Threading.Tasks
Module Program
Async Function Main(args As String()) As Task
Dim browserFetcher = New BrowserFetcher()
Await browserFetcher.DownloadAsync()
Await Using browser = Await Puppeteer.LaunchAsync(New LaunchOptions With {
.Headless = True
})
Await Using page = Await browser.NewPageAsync()
Await page.SetContentAsync("<h1>Custom PDF</h1><p>With landscape orientation and margins.</p>")
Await page.PdfAsync("custom.pdf", New PdfOptions With {
.Format = PaperFormat.A4,
.Landscape = True,
.MarginOptions = New MarginOptions With {
.Top = "20mm",
.Bottom = "20mm",
.Left = "20mm",
.Right = "20mm"
}
})
End Using
End Using
End Function
End Module
After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>With landscape orientation and margins.</p>");
pdf.SaveAs("custom.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>With landscape orientation and margins.</p>");
pdf.SaveAs("custom.pdf");
}
}
Imports IronPdf
Imports IronPdf.Rendering
Class Program
Shared Sub Main(args As String())
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Custom PDF</h1><p>With landscape orientation and margins.</p>")
pdf.SaveAs("custom.pdf")
End Sub
End Class
此範例顯示 PDF 選項如何在兩個函式庫之間對應。PuppeteerSharp使用 PdfOptions,其中 Format、Landscape 和 MarginOptions 包含字串值 ("20mm")。IronPDF使用 RenderingOptions 屬性,其中包含直接的紙張尺寸枚舉、方向枚舉和以毫米為單位的數值邊距值。
關鍵對應:
Format = PaperFormat.A4→PaperSize = PdfPaperSize.A4Landscape = true→PaperOrientation = PdfPaperOrientation.LandscapeMarginOptions.Top = "20mm"→MarginTop = 20(數值毫米)
記憶體洩漏問題
PuppeteerSharp 在持續負載下會造成記憶體累積:
// ❌PuppeteerSharp- Memory grows with each operation
// Requires explicit browser recycling every N operations
for (int i = 0; i < 1000; i++)
{
var page = await browser.NewPageAsync();
await page.SetContentAsync($"<h1>Document {i}</h1>");
await page.PdfAsync($"doc_{i}.pdf");
await page.CloseAsync(); // Memory still accumulates!
}
// Must periodically: await browser.CloseAsync(); and re-launch
// ✅IronPDF- Stable memory, reuse renderer
var renderer = new ChromePdfRenderer();
for (int i = 0; i < 1000; i++)
{
var pdf = renderer.RenderHtmlAsPdf($"<h1>Document {i}</h1>");
pdf.SaveAs($"doc_{i}.pdf");
// Memory managed automatically
}
// ❌PuppeteerSharp- Memory grows with each operation
// Requires explicit browser recycling every N operations
for (int i = 0; i < 1000; i++)
{
var page = await browser.NewPageAsync();
await page.SetContentAsync($"<h1>Document {i}</h1>");
await page.PdfAsync($"doc_{i}.pdf");
await page.CloseAsync(); // Memory still accumulates!
}
// Must periodically: await browser.CloseAsync(); and re-launch
// ✅IronPDF- Stable memory, reuse renderer
var renderer = new ChromePdfRenderer();
for (int i = 0; i < 1000; i++)
{
var pdf = renderer.RenderHtmlAsPdf($"<h1>Document {i}</h1>");
pdf.SaveAs($"doc_{i}.pdf");
// Memory managed automatically
}
' ❌PuppeteerSharp- Memory grows with each operation
' Requires explicit browser recycling every N operations
For i As Integer = 0 To 999
Dim page = Await browser.NewPageAsync()
Await page.SetContentAsync($"<h1>Document {i}</h1>")
Await page.PdfAsync($"doc_{i}.pdf")
Await page.CloseAsync() ' Memory still accumulates!
Next
' Must periodically: Await browser.CloseAsync() and re-launch
' ✅IronPDF- Stable memory, reuse renderer
Dim renderer As New ChromePdfRenderer()
For i As Integer = 0 To 999
Dim pdf = renderer.RenderHtmlAsPdf($"<h1>Document {i}</h1>")
pdf.SaveAs($"doc_{i}.pdf")
' Memory managed automatically
Next
IronPDF 不需要PuppeteerSharp所需的瀏覽器池架構:
// Before (PuppeteerSharp - delete entire class)
public class PuppeteerBrowserPool
{
private readonly ConcurrentBag<IBrowser> _browsers;
private readonly SemaphoreSlim _semaphore;
private int _operationCount;
// ... recycling logic ...
}
// After (IronPDF - simple reuse)
public class PdfService
{
private readonly ChromePdfRenderer _renderer = new();
public byte[] Generate(string html)
{
return _renderer.RenderHtmlAsPdf(html).BinaryData;
}
}
// Before (PuppeteerSharp - delete entire class)
public class PuppeteerBrowserPool
{
private readonly ConcurrentBag<IBrowser> _browsers;
private readonly SemaphoreSlim _semaphore;
private int _operationCount;
// ... recycling logic ...
}
// After (IronPDF - simple reuse)
public class PdfService
{
private readonly ChromePdfRenderer _renderer = new();
public byte[] Generate(string html)
{
return _renderer.RenderHtmlAsPdf(html).BinaryData;
}
}
' Before (PuppeteerSharp - delete entire class)
Public Class PuppeteerBrowserPool
Private ReadOnly _browsers As ConcurrentBag(Of IBrowser)
Private ReadOnly _semaphore As SemaphoreSlim
Private _operationCount As Integer
' ... recycling logic ...
End Class
' After (IronPDF - simple reuse)
Public Class PdfService
Private ReadOnly _renderer As New ChromePdfRenderer()
Public Function Generate(html As String) As Byte()
Return _renderer.RenderHtmlAsPdf(html).BinaryData
End Function
End Class
關鍵遷移注意事項
Async 到 Sync 的轉換
PuppeteerSharp 自始至終需要 async/await;IronPDF支援同步作業:
// PuppeteerSharp: Async required
public async Task<byte[]> GeneratePdfAsync(string html)
{
await new BrowserFetcher().DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(...);
await using var page = await browser.NewPageAsync();
await page.SetContentAsync(html);
return await page.PdfDataAsync();
}
// IronPDF: Sync default
public byte[] GeneratePdf(string html)
{
var renderer = new ChromePdfRenderer();
return renderer.RenderHtmlAsPdf(html).BinaryData;
}
// Or async when needed
public async Task<byte[]> GeneratePdfAsync(string html)
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
// PuppeteerSharp: Async required
public async Task<byte[]> GeneratePdfAsync(string html)
{
await new BrowserFetcher().DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(...);
await using var page = await browser.NewPageAsync();
await page.SetContentAsync(html);
return await page.PdfDataAsync();
}
// IronPDF: Sync default
public byte[] GeneratePdf(string html)
{
var renderer = new ChromePdfRenderer();
return renderer.RenderHtmlAsPdf(html).BinaryData;
}
// Or async when needed
public async Task<byte[]> GeneratePdfAsync(string html)
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
Imports System.Threading.Tasks
Imports PuppeteerSharp
' PuppeteerSharp: Async required
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Await (New BrowserFetcher()).DownloadAsync()
Await Using browser = Await Puppeteer.LaunchAsync(...)
Await Using page = Await browser.NewPageAsync()
Await page.SetContentAsync(html)
Return Await page.PdfDataAsync()
End Using
End Using
End Function
' IronPDF: Sync default
Public Function GeneratePdf(html As String) As Byte()
Dim renderer = New ChromePdfRenderer()
Return renderer.RenderHtmlAsPdf(html).BinaryData
End Function
' Or async when needed
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Dim renderer = New ChromePdfRenderer()
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Function
邊際單位轉換
PuppeteerSharp 使用字串單位;IronPDF使用數字毫米:
//PuppeteerSharp- string units
MarginOptions = new MarginOptions
{
Top = "1in", // 25.4mm
Bottom = "0.75in", // 19mm
Left = "1cm", // 10mm
Right = "20px" // ~7.5mm at 96dpi
}
//IronPDF- numeric millimeters
renderer.RenderingOptions.MarginTop = 25; // mm
renderer.RenderingOptions.MarginBottom = 19;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 8;
//PuppeteerSharp- string units
MarginOptions = new MarginOptions
{
Top = "1in", // 25.4mm
Bottom = "0.75in", // 19mm
Left = "1cm", // 10mm
Right = "20px" // ~7.5mm at 96dpi
}
//IronPDF- numeric millimeters
renderer.RenderingOptions.MarginTop = 25; // mm
renderer.RenderingOptions.MarginBottom = 19;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 8;
MarginOptions = New MarginOptions With {
.Top = "1in", ' 25.4mm
.Bottom = "0.75in", ' 19mm
.Left = "1cm", ' 10mm
.Right = "20px" ' ~7.5mm at 96dpi
}
renderer.RenderingOptions.MarginTop = 25 ' mm
renderer.RenderingOptions.MarginBottom = 19
renderer.RenderingOptions.MarginLeft = 10
renderer.RenderingOptions.MarginRight = 8
頁首/頁尾占位符轉換
| PuppeteerSharp 類別 | IronPDF 占位符 |
|---|---|
<span class='pageNumber'> |
{page} |
<span class='totalPages'> |
{total-pages} |
<span class='date'> |
{date} |
<span class='title'> |
{html-title} |
遷移後的新功能
轉移到IronPDF之後,您將獲得PuppeteerSharp無法提供的功能:
PDF 合併
var pdf1 = renderer.RenderHtmlAsPdf(html1);
var pdf2 = renderer.RenderHtmlAsPdf(html2);
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
var pdf1 = renderer.RenderHtmlAsPdf(html1);
var pdf2 = renderer.RenderHtmlAsPdf(html2);
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
Dim pdf1 = renderer.RenderHtmlAsPdf(html1)
Dim pdf2 = renderer.RenderHtmlAsPdf(html2)
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
水印。
var watermark = new TextStamper
{
Text = "CONFIDENTIAL",
FontSize = 48,
Opacity = 30,
Rotation = -45
};
pdf.ApplyStamp(watermark);
var watermark = new TextStamper
{
Text = "CONFIDENTIAL",
FontSize = 48,
Opacity = 30,
Rotation = -45
};
pdf.ApplyStamp(watermark);
Dim watermark As New TextStamper With {
.Text = "CONFIDENTIAL",
.FontSize = 48,
.Opacity = 30,
.Rotation = -45
}
pdf.ApplyStamp(watermark)
密碼保護
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "readonly";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "readonly";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.OwnerPassword = "admin"
pdf.SecuritySettings.UserPassword = "readonly"
pdf.SecuritySettings.AllowUserCopyPasteContent = False
數位簽名
var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);
var signature = new PdfSignature("certificate.pfx", "password");
pdf.Sign(signature);
Dim signature = New PdfSignature("certificate.pfx", "password")
pdf.Sign(signature)
PDF/A 合規性
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b)
效能比較摘要
| 指標 | PuppeteerSharp | IronPDF | 改進 |
|---|---|---|---|
| 第一份 PDF (冷启動) | 45s+ | ~20s | 速度快 55% 以上。 |
| 後續 PDF | 變數 | 一致性 | 可預測性。 |
| 記憶體使用情況 | 500MB+ (成長中) | ~50MB (穩定) | 減少 90% 記憶體 |
| 磁碟空間 (Chromium) | 300MB+ | 0 | 消除下載。 |
| 瀏覽器下載 | 要求 | 不需要 | 零設定 |
| 線程安全 | 限額 | 全文 | 可靠的並發性 |
| PDF 生成時間 | 45s | 20s | 快55%。 |
遷移清單
預遷移
- 識別程式碼庫中所有PuppeteerSharp的使用情況
- 文檔邊距值(將字串轉換為毫米)
- 注意頁首/頁尾佔位符語法以進行轉換
- 刪除瀏覽器池/回收基礎設施
- 從ironpdf.com取得IronPDF許可證金鑰
套件變更
- 刪除
PuppeteerSharpNuGet 套件 - 刪除
.local-chromium資料夾回收約 300MB 磁碟空間 - 安裝
IronPdfNuGet 套件:dotnet add package IronPdf
程式碼變更
- 更新命名空間匯入
- 刪除
BrowserFetcher.DownloadAsync()調用 - 移除
Puppeteer.LaunchAsync()和瀏覽器管理 - 將
page.SetContentAsync()+page.PdfAsync()替換為RenderHtmlAsPdf() - 將
page.GoToAsync()+page.PdfAsync()替換為RenderUrlAsPdf() - 將邊距字串轉換為毫米值
- 轉換頁首/頁尾佔位符語法
- 刪除所有瀏覽器/頁面銷毀程式碼
- 刪除瀏覽器池基礎架構
- 在應用程式啟動時新增許可證初始化
後遷移
- PDF 輸出的視覺比較
- 記憶體穩定性負載測試(應保持穩定,無需重新啟動)
- 驗證頁首/頁尾的顯示是否正確,並顯示頁碼
- 根據需要新增功能(安全性、浮水印、合併)

