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:
-
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.
-
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.
-
Złożone wzorce asynchroniczne z zarządzaniem cyklem życia przeglądarki.
-
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.
-
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ść).
- 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
- Środowisko .NET: .NET Framework 4.6.2+ lub .NET Core 3.1+ / .NET 5/6/7/8/9+
- Dostęp do NuGet: Możliwość instalowania pakietów NuGet
- 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
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"
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
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
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
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
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
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
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
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.A4→PaperSize = PdfPaperSize.A4Landscape = true→PaperOrientation = PdfPaperOrientation.LandscapeMarginOptions.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
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
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
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
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")
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)
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
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)
Zgodność z PDF/A
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b)
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()przezRenderHtmlAsPdf() - Zastąp
page.GoToAsync()+page.PdfAsync()przezRenderUrlAsPdf() - 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)

