跳至頁尾內容
影片

如何在 C# 中渲染 Azure Blob 儲存中的圖像

從PuppeteerSharp遷移到IronPDF可將您的PDF生成流程從具有300MB+ Chromium依賴的瀏覽器自動化工具轉換為具備自動記憶體管理的專用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. 復雜的異步模式與瀏覽器生命周期管理。

  4. 列印至PDF輸出(相當於Ctrl+P,而不是螢幕截圖)。 布局可能會重新流動,背景可能預設會被省略,輸出是為列印而分頁的,而不是匹配瀏覽器視圖的。

  5. 不支持PDF/A或PDF/UA以滿足合規要求。 PuppeteerSharp無法生成符合PDF/A(歸檔)或PDF/UA(可存取性)規範的文件。

  6. 無PDF操作 - 僅生成,無合併/拆分/編輯功能。 雖然PuppeteerSharp在生成PDF方面很高效,但它缺乏進一步操作的能力,如合併、拆分、保護或編輯PDF。

PuppeteerSharp vs IronPDF比較

方面 PuppeteerSharp IronPDF
主要目的 瀏覽器自動化 PDF生成
Chromium依賴 300MB+單獨下載 內建優化引擎
API複雜性 異步瀏覽器/頁面生命周期 同步一行程式碼
初始化 BrowserFetcher.DownloadAsync() + LaunchAsync new ChromePdfRenderer()
記憶體管理 手動瀏覽器回收 自動
載入時記憶體 在高負載下報告增長 在持續運行下穩定
PDF/A支持 不可用 支援
PDF/UA可存取性 不可用 支援
PDF編輯 不可用 合併、拆分、加蓋、編輯
數位簽名 不可用 支援
執行緒安全 限制(根據上游指導) 全面
授權 MIT(開源) 商業授權

平台支持

程式庫 .NET Framework 4.7.2 .NET Core 3.1 .NET 6-8 .NET 10
IronPDF 全面 全面 全面 全面
PuppeteerSharp 透過netstandard2.0 全面 全面 全面

IronPDF支持現代.NET目標,這意味著它可以無阻礙相容地進入大多數現有應用程式。


開始之前

前提條件

  1. .NET環境:.NET Framework 4.6.2+ 或.NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet存取: 有能力安裝NuGet套件
  3. IronPDF授權:ironpdf.com獲取您的授權金鑰

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
SHELL

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

完整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
$vbLabelText   $csharpLabel

核心API對應

PuppeteerSharp API IronPDFAPI 注釋
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
$vbLabelText   $csharpLabel

之後(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
$vbLabelText   $csharpLabel

此範例說明基本的架構差異。 PuppeteerSharp需要六個異步操作:BrowserFetcher.DownloadAsync()(300MB+ 的Chromium下載)、await using處置。

IronPDF消除了所有這些復雜性:建立一個SaveAs()。 無異步模式,無瀏覽器生命周期,無Chromium下載。 IronPDF的方法提供了更清晰的語法和與現代.NET應用程式的更好整合。 查看更多HTML到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
$vbLabelText   $csharpLabel

之後(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
$vbLabelText   $csharpLabel

PuppeteerSharp使用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
$vbLabelText   $csharpLabel

之後(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
$vbLabelText   $csharpLabel

此範例展示了兩個程式庫之間的PDF選項映射。 PuppeteerSharp使用MarginOptions包含字串值 ("20mm")。 IronPDF使用RenderingOptions屬性,帶有直接紙張大小枚舉、方向枚舉和以毫米為單位的數值邊距值。

關鍵映射:

  • Format = PaperFormat.A4PaperSize = PdfPaperSize.A4
  • Landscape = truePaperOrientation = PdfPaperOrientation.Landscape
  • MarginOptions.Top = "20mm"MarginTop = 20 (數值毫米)

持續負載下的記憶體增長

使用者報告在持續負載下使用PuppeteerSharp發生記憶體累積,通常需要手動回收瀏覽器來緩解:

// PuppeteerSharp - memory growth typically requires periodic recycling
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();
}
// Recommended: await browser.CloseAsync(); and re-launch every N operations

//IronPDF- reuse a single renderer across operations
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 growth typically requires periodic recycling
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();
}
// Recommended: await browser.CloseAsync(); and re-launch every N operations

//IronPDF- reuse a single renderer across operations
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
}
Imports PuppeteerSharp
Imports IronPdf

' PuppeteerSharp - memory growth typically requires periodic recycling
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()
Next
' Recommended: Await browser.CloseAsync() and re-launch every N operations

' IronPDF - reuse a single renderer across operations
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
$vbLabelText   $csharpLabel

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

關鍵遷移注意事項

異步到同步轉換

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

邊距單位轉換

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;
' PuppeteerSharp - string units
MarginOptions = New MarginOptions With {
    .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
$vbLabelText   $csharpLabel

標頭/頁腳佔位符轉換

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

水印

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

密碼保護

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

數位簽名

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

PDF/A合規性

pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b)
$vbLabelText   $csharpLabel

性能比較摘要

指標 PuppeteerSharp IronPDF 改進
第一個PDF(冷啟動) 45秒+ 約20秒 快55%+
隨後的PDFs 可變 一致 可預測
記憶體使用 500MB+(增長) 約50MB(穩定) 減少90%的記憶體
磁碟空間(Chromium) 300MB+ 0 消除下載
瀏覽器下載 必需的 不需要 零設定
執行緒安全 有限 全面 可靠的並發性
PDF生成時間 45秒 20秒 快55%

遷移檢查表

遷移前

  • 識別程式碼庫中的所有PuppeteerSharp用法
  • 文件邊距值(將字串轉換為毫米)
  • 注意標頭/頁腳佔位符語法轉換
  • 刪除瀏覽器池/回收基礎設施
  • 獲取IronPDF授權金鑰來自ironpdf.com

套件變更

  • 移除PuppeteerSharp NuGet包
  • 刪除.local-chromium資料夾以回收約300MB磁碟空間
  • 安裝IronPdf NuGet包:dotnet add package IronPdf

程式碼變更

  • 更新命名空間導入
  • 移除BrowserFetcher.DownloadAsync()調用
  • 移除Puppeteer.LaunchAsync()和瀏覽器管理
  • page.SetContentAsync() + RenderHtmlAsPdf()
  • page.GoToAsync() + RenderUrlAsPdf()
  • 將邊距字串轉換為毫米值
  • 轉換標頭/頁腳佔位符語法
  • 移除所有的瀏覽器/頁面釋放程式碼
  • 刪除瀏覽器池基礎設施
  • 在應用程式啟動時新增授權初始化

遷移後

  • PDF輸出的視覺比較
  • 載入測試以確保記憶體穩定性(應無需回收仍保持穩定)
  • 驗證標頭/頁腳渲染與頁碼的精確性
  • 根據需要新增新功能(安全性、水印、合併)

請注意PuppeteerSharp是其各自所有者的註冊商標。 本網站不隸屬於、由其認可或贊助的PuppeteerSharp。所有產品名稱、標誌和品牌是其各自所有者的財產。 比較僅供參考,反映撰寫時公開可用的資訊。

Curtis Chau
技術作家

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

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

Iron 支援團隊

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