Przejdź do treści stopki
PRZEWODNIKI MIGRACJI

Jak przejść z PuppeteerSharp na IronPDF w języku C#

Przejście zPuppeteerSharpnaIronPDFzmienia proces generowania plików PDF z narzędzia do automatyzacji przeglądarki z ponad 300 MB zależności w specjalnie zaprojektowaną bibliotekę PDF z automatycznym zarządzaniem pamięcią. Niniejszy przewodnik zawiera kompletną, szczegółową ścieżkę migracji, która eliminuje konieczność pobierania Chromium, rozwiązuje problemy związane z wyciekami pamięci oraz zapewnia kompleksowe możliwości edycji plików PDF.

Dlaczego warto przejść zPuppeteerSharpna IronPDF

Zrozumienie PuppeteerSharp

PuppeteerSharp to port biblioteki Puppeteer firmy Google na platformę .NET, zapewniający funkcje automatyzacji przeglądarki w języku C#. Generuje pliki PDF przy użyciu wbudowanej w przeglądarce Chrome funkcji drukowania do pliku PDF — tak samo jak po naciśnięciu klawiszy Ctrl+P w przeglądarce. Wynikiem tego jest gotowy do druku plik zoptymalizowany pod kątem papieru, który różni się od tego, co widzisz na ekranie.

PuppeteerSharp został zaprojektowany do testowania stron internetowych i scrapingu, a nie do generowania dokumentów. Chociaż jest to możliwe, użyciePuppeteerSharpdo generowania plików PDF stwarza poważne wyzwania produkcyjne.

Problem automatyzacji przeglądarki

PuppeteerSharp został zaprojektowany do automatyzacji przeglądarek, a nie do generowania dokumentów. Powoduje to zasadnicze problemy podczas korzystania z niego w przypadku plików PDF:

  1. Przed pierwszym użyciem wymagane jest pobranie ponad 300 MB pakietu Chromium. Znaczącą wadąPuppeteerSharpjest jego spory rozmiar po wdrożeniu, głównie z powodu dołączonego pliku binarnego Chromium. Ten znaczny rozmiar może powodować nadmierne powiększenie obrazów Docker i powodować problemy z zimnym startem w środowiskach bezserwerowych.

  2. Wycieki pamięci pod obciążeniem wymagające ręcznego odświeżania przeglądarki. Wiadomo, że przy dużym obciążeniuPuppeteerSharpdoświadcza wycieków pamięci. Gromadzenie pamięci przez instancje przeglądarek wymaga ręcznej interwencji w celu zarządzania procesami i recyklingu.

  3. Złożone wzorce asynchroniczne z zarządzaniem cyklem życia przeglądarki.

  4. Wydruk do pliku PDF (odpowiednik skrótu klawiszowego Ctrl+P, a nie zrzut ekranu). Układ strony może ulec zmianie, tła mogą być domyślnie pominięte, a wynik jest paginowany pod kątem drukowania, a nie dopasowany do okna przeglądarki.

  5. Brak obsługi formatów PDF/A lub PDF/UA w celu spełnienia wymagań zgodności.PuppeteerSharpnie może generować dokumentów zgodnych ze standardami PDF/A (archiwizacja) ani PDF/UA (dostępność).

  6. Brak manipulacji plikami PDF – wyłącznie generowanie, bez scalania/dzielenia/edycji. ChociażPuppeteerSharpskutecznie generuje pliki PDF, brakuje mu możliwości dalszej obróbki, takich jak scalanie, dzielenie, zabezpieczanie lub edycja plików PDF.

PorównaniePuppeteerSharpi IronPDF

Aspekt PuppeteerSharp IronPDF
Główny cel Automatyzacja przeglądarki Generowanie plików PDF
Zależność od Chromium Pobieranie osobnego pliku o rozmiarze ponad 300 MB Wbudowany, zoptymalizowany silnik
Złożoność API Asynchroniczny cykl życia przeglądarki/strony Synchroniczne jednozdaniowe
Inicjalizacja BrowserFetcher.DownloadAsync() + LaunchAsync new ChromePdfRenderer()
Zarządzanie pamięcią Wymagane ręczne odświeżanie przeglądarki Automatyczne
Pamięć pod obciążeniem Ponad 500 MB z wyciekami ~50 MB stabilna
Uruchomienie na zimno Ponad 45 sekund ~20 sekund
Obsługa formatu PDF/A Niedostępne Obsługiwane
Dostępność PDF/UA Niedostępne Obsługiwane
Edycja plików PDF Niedostępne Łączenie, dzielenie, stemplowanie, edycja
Podpisy cyfrowe Niedostępne Obsługiwane
Bezpieczeństwo wątków Ograniczone Pełna
Profesjonalne wsparcie Społeczność Reklama z umową SLA

Obsługa platform

| Biblioteka |.NET Framework 4.7.2|.NET Core 3.1|.NET 6-8|.NET 10| | --------- | :---: | :---: | :---: | :---: ||IronPDF| Pełna | Pełna | Pełna | Pełna ||PuppeteerSharp| Ograniczone | Pełna | Pełna | W toku | Szerokie wsparcieIronPDFfor .NET gwarantuje, że programiści mogą z niego korzystać w różnych środowiskach bez problemów z kompatybilnością, co zapewnia elastyczny wybór dla nowoczesnych aplikacji .NET w latach 2025 i 2026.


Zanim zaczniesz

Wymagania wstępne

  1. Środowisko .NET: .NET Framework 4.6.2+ lub .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. Dostęp do NuGet: Możliwość instalowania pakietów NuGet
  3. Licencja IronPDF: Uzyskaj klucz licencyjny na stronie ironpdf.com

Zmiany w pakiecie 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

W przypadkuIronPDFnie jest wymagany BrowserFetcher.DownloadAsync() — silnik renderujący jest dołączany automatycznie.

Konfiguracja licencji

// 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

Kompletna dokumentacija API

Zmiany w przestrzeni nazw

// 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

Mapowania podstawowych interfejsów API

PuppeteerSharp API IronPDF API Uwagi
new BrowserFetcher().DownloadAsync() Nie jest potrzebne Nie wymaga pobierania przeglądarki
Puppeteer.LaunchAsync(options) Nie jest potrzebne Brak zarządzania przeglądarką
browser.NewPageAsync() Nie jest potrzebne Brak kontekstu strony
page.GoToAsync(url) renderer.RenderUrlAsPdf(url) Bezpośrednie tłumaczenie
page.SetContentAsync(html) renderer.RenderHtmlAsPdf(html) Bezpośrednie tłumaczenie
page.PdfAsync(path) pdf.SaveAs(path) Po renderowaniu
await page.CloseAsync() Nie jest potrzebne Automatyczne czyszczenie
await browser.CloseAsync() Nie jest potrzebne Automatyczne czyszczenie
PdfOptions.Format RenderingOptions.PaperSize Rozmiar papieru
PdfOptions.Landscape RenderingOptions.PaperOrientation Orientacja
PdfOptions.MarginOptions RenderingOptions.MarginTop/Bottom/Left/Right Indywidualne marginesy
PdfOptions.PrintBackground RenderingOptions.PrintHtmlBackgrounds Drukowanie w tle
PdfOptions.HeaderTemplate RenderingOptions.HtmlHeader Nagłówki HTML
PdfOptions.FooterTemplate RenderingOptions.HtmlFooter Stopki HTML
page.WaitForSelectorAsync() RenderingOptions.WaitFor.HtmlElementId Poczekaj na element

Przykłady migracji kodu

Przykład 1: Podstawowa konwersja HTML do PDF

Przed (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

Po (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

Ten przykład ilustruje podstawową różnicę architektoniczną.PuppeteerSharpwymaga sześciu operacji asynchronicznych: BrowserFetcher.DownloadAsync() (pobieranie Chromium o wielkości ponad 300 MB), Puppeteer.LaunchAsync(), browser.NewPageAsync(), page.SetContentAsync() oraz page.PdfAsync(), a także prawidłowe zamknięcie za pomocą await using.

IronPDF eliminuje całą tę złożoność: utwórz ChromePdfRenderer, wywołaj RenderHtmlAsPdf() i SaveAs(). Bez wzorców asynchronicznych, bez cyklu życia przeglądarki, bez pobierania Chromium. PodejścieIronPDFoferuje bardziej przejrzystą składnię i lepszą integrację z nowoczesnymi aplikacjami .NET. Kompleksowe przykłady można znaleźć w dokumentacji dotyczącej konwersji HTML do PDF.

Przykład 2: Konwersja adresów URL do formatu PDF

Przed (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

Po (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 używa GoToAsync() do przejścia do adresu URL, a następnie PdfAsync().IronPDFudostępnia jedną metodę RenderUrlAsPdf(), która obsługuje nawigację i generowanie plików PDF w jednym wywołaniu. Dowiedz się więcej z naszych samouczków.

Przykład 3: Niestandardowe ustawienia strony z marginesami

Przed (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

Po (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

Ten przykład pokazuje, jak opcje PDF są mapowane między dwiema bibliotekami.PuppeteerSharpużywa PdfOptions wraz z Format, Landscape i MarginOptions zawierającymi wartości łańcuchowe ("20mm").IronPDFwykorzystuje właściwości RenderingOptions z bezpośrednimi wyliczeniami rozmiarów papieru, wyliczeniami orientacji oraz numerycznymi wartościami marginesów w milimetrach.

Kluczowe powiązania:

  • Format = PaperFormat.A4PaperSize = PdfPaperSize.A4
  • Landscape = truePaperOrientation = PdfPaperOrientation.Landscape
  • MarginOptions.Top = "20mm"MarginTop = 20 (milimetry liczbowe)

Problem wycieku pamięci

PuppeteerSharp jest znany z gromadzenia pamięci przy długotrwałym obciążeniu:

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

IronPDF eliminuje potrzebę stosowania infrastruktury puli przeglądarek, której wymaga 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

Ważne uwagi dotyczące migracji

Konwersja z trybu asynchronicznego na synchroniczny

PuppeteerSharp wymaga stosowania async/await w całym tekście;IronPDFobsługuje operacje synchroniczne:

// 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

Konwersja jednostek marginesu

PuppeteerSharp używa jednostek typu string;IronPDFużywa milimetrów:

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

Konwersja symboli zastępczych nagłówków/stopek

KlasaPuppeteerSharp IronPDF Placeholder
<span class='pageNumber'> {page}
<span class='totalPages'> {total-pages}
<span class='date'> {date}
<span class='title'> {html-title}

Nowe możliwości po migracji

Po migracji doIronPDFzyskujesz możliwości, którychPuppeteerSharpnie jest w stanie zapewnić:

Łączenie plików 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

Znaki wodne

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

Ochrona hasłem

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

Podpisy cyfrowe

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

Zgodność z PDF/A

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

Podsumowanie porównania wydajności

Metryka PuppeteerSharp IronPDF Ulepszenie
Pierwszy plik PDF (Cold Start) 45s+ ~20 s O ponad 55% szybciej
Kolejne pliki PDF Zmienna Spójność Przewidywalne
Wykorzystanie pamięci 500 MB+ (wzrasta) ~50 MB (wersja stabilna) O 90% mniej pamięci
Miejsce na dysku (Chromium) Ponad 300 MB 0 Wyeliminuj pliki do pobrania
Pobierz przeglądarkę Wymagane Nie jest potrzebne Zero konfiguracji
Bezpieczeństwo wątków Ograniczone Pełna Niezawodna współbieżność
Czas generowania pliku PDF 45s 20s O 55% szybciej

Lista kontrolna migracji

Przed migracją

  • Zidentyfikuj wszystkie użyciaPuppeteerSharpw kodzie źródłowym
  • Wartości marginesów dokumentu (przelicz ciągi znaków na milimetry)
  • Zwróć uwagę na składnię symboli zastępczych nagłówka/stopki przy konwersji
  • Usuń infrastrukturę pulowania/recyklingu przeglądarek
  • Uzyskaj klucz licencyjnyIronPDFze strony ironpdf.com

Zmiany w pakiecie

  • Usuń pakiet NuGet PuppeteerSharp
  • Usuń folder .local-chromium, aby odzyskać około 300 MB miejsca na dysku
  • Zainstaluj pakiet NuGet IronPdf: dotnet add package IronPdf

Zmiany w kodzie

  • Zaktualizuj importy przestrzeni nazw
  • Usuń wywołania BrowserFetcher.DownloadAsync()
  • Usuń Puppeteer.LaunchAsync() i zarządzanie przeglądarką
  • Zastąp page.SetContentAsync() + page.PdfAsync() przez RenderHtmlAsPdf()
  • Zastąp page.GoToAsync() + page.PdfAsync() przez RenderUrlAsPdf()
  • Zamień wartości marginesów na wartości w milimetrach
  • Przekształć składnię symboli zastępczych nagłówków/stopek
  • Usuń cały kod dotyczący zamykania przeglądarki/strony
  • Usuń infrastrukturę puli przeglądarek
  • Dodaj inicjalizację licencji podczas uruchamiania aplikacji

Po migracji

  • Wizualne porównanie pliku PDF
  • Test obciążeniowy pod kątem stabilności pamięci (powinna pozostać stabilna bez recyklingu)
  • Sprawdź renderowanie nagłówków/stopek wraz z numerami stron
  • W razie potrzeby dodaj nowe funkcje (zabezpieczenia, znaki wodne, scalanie)

Curtis Chau
Autor tekstów technicznych

Curtis Chau posiada tytuł licencjata z informatyki (Uniwersytet Carleton) i specjalizuje się w front-endowym rozwoju, z ekspertką w Node.js, TypeScript, JavaScript i React. Pasjonuje się tworzeniem intuicyjnych i estetycznie przyjemnych interfejsów użytkownika, Curtis cieszy się pracą z nowoczesnymi frameworkami i tworzeniem dobrze zorganizowanych, atrakcyjnych wizualnie podrę...

Czytaj więcej

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie