Cómo migrar de PuppeteerSharp a IronPDF en C#
La migración de PuppeteerSharpaIronPDFtransforma su flujo de trabajo de generación de PDF de una herramienta de automatización del navegador con dependencias de más de 300 MB a una biblioteca PDF creada específicamente con gestión automática de memoria. Esta guía proporciona una ruta de migración completa, paso a paso, que elimina las descargas de Chromium, resuelve los problemas de fugas de memoria y proporciona capacidades completas de manipulación de PDF.
Por qué migrar de PuppeteerSharpa IronPDF
Entendiendo PuppeteerSharp
PuppeteerSharp es una adaptación a .NET de Puppeteer de Google, que lleva las capacidades de automatización del navegador a C#. Genera archivos PDF utilizando la función integrada de impresión a PDF de Chrome, igual que si pulsaras Ctrl+P en un navegador. El resultado es un documento listo para imprimir y optimizado para el papel, que difiere de lo que se ve en pantalla.
PuppeteerSharp se diseñó para pruebas web y scraping, no para la generación de documentos. Aunque es capaz, el uso de PuppeteerSharppara la generación de PDF crea importantes retos de producción.
El problema de la automatización del navegador
PuppeteerSharp se diseñó para la automatización de navegadores, no para la generación de documentos. Esto plantea problemas fundamentales cuando se utiliza para PDF:
-
se requieren 300MB+ de descargas de Chromium antes del primer uso. Una desventaja significativa de PuppeteerSharpes su gran tamaño de despliegue, debido principalmente al binario Chromium que incluye. Este tamaño considerable puede inflar las imágenes de Docker y causar problemas de arranque en frío en entornos sin servidor.
-
Fugas de memoria bajo carga que requieren el reciclaje manual del navegador. Bajo carga pesada, PuppeteerSharpes conocido por experimentar fugas de memoria. La acumulación de memoria por parte de las instancias del navegador hace necesaria la intervención manual para la gestión y el reciclaje del proceso.
-
Patrones async complejos con gestión del ciclo de vida del navegador.
-
Print-to-PDF output (equivalente a Ctrl+P, no captura de pantalla). Los diseños pueden refluir, los fondos pueden omitirse por defecto y el resultado se pagina para la impresión en lugar de ajustarse a la ventana del navegador.
-
No es compatible con PDF/A ni PDF/UA por requisitos de conformidad. PuppeteerSharpno puede producir documentos PDF/A (archivo) o PDF/UA (accesibilidad).
- Sin manipulación de PDF - sólo generación, sin fusión/división/edición. Aunque PuppeteerSharpes eficiente a la hora de generar archivos PDF, carece de capacidades para su manipulación posterior, como combinar, dividir, proteger o editar archivos PDF.
Comparación entre PuppeteerSharpy IronPDF
| Aspecto | PuppeteerSharp | IronPDF |
|---|---|---|
| Finalidad principal | Automatización de navegadores | Generación de PDF |
| Dependencia de Chromium | descarga separada de más de 300 MB | Motor integrado optimizado |
| Complejidad de la API | Ciclo de vida asíncrono de navegador/página | Sincronización de frases |
| Inicialización | BrowserFetcher.DownloadAsync() + Lanzamiento asíncrono |
new ChromePdfRenderer() |
| Gestión de memoria | Se requiere reciclaje manual del navegador | Automático |
| Memoria bajo carga | más de 500 MB con filtraciones | ~50 MB estables |
| Inicio en frío | más de 45 segundos | ~20 segundos |
| Soporte PDF/A | No disponible | Se admite |
| Accesibilidad PDF/UA | No disponible | Se admite |
| Edición de PDF | No disponible | Combinar, dividir, sellar, editar |
| Firmas digitales | No disponible | Se admite |
| Seguridad de hilos | Limitado | Completo |
| Soporte profesional | Comunidad | Comercial con SLA |
Soporte de plataforma
| Biblioteca | .NET Framework 4.7.2| .NET Core 3.1| .NET 6-8| .NET 10| | --------- | :---: | :---: | :---: | :---: ||IronPDF| Completo | Completo | Completo | Completo || PuppeteerSharp| Limitado | Completo | Completo | Pendiente | La amplia compatibilidad deIronPDFcon todas las plataformas .NET garantiza que los desarrolladores puedan utilizarlo en varios entornos sin encontrar problemas de compatibilidad, lo que proporciona una opción flexible para las aplicaciones .NET modernas hasta 2025 y 2026.
Antes de empezar
Prerrequisitos
- Entorno .NET : .NET Framework 4.6.2+ o .NET Core 3.1+ / .NET 5/6/7/8/9+
- Acceso a NuGet : Capacidad para instalar paquetes NuGet
- Licencia deIronPDF: Obtenga su clave de licencia en IronPDF
Cambios en el paquete 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
No se requiere BrowserFetcher.DownloadAsync() con IronPDF : el motor de renderizado se incluye automáticamente.
Configuración de licencias
// 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"
Referencia completa de la API
Cambios en el espacio de nombres
// 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
Mapeos de API principales
| API de PuppeteerSharp | API de IronPDF | Notas |
|---|---|---|
new BrowserFetcher().DownloadAsync() |
No es necesario | Sin descarga de navegador |
Puppeteer.LaunchAsync(options) |
No es necesario | Sin gestión de navegador |
browser.NewPageAsync() |
No es necesario | Sin contexto de página |
page.GoToAsync(url) |
renderer.RenderUrlAsPdf(url) |
Traducción directa |
page.SetContentAsync(html) |
renderer.RenderHtmlAsPdf(html) |
Traducción directa |
page.PdfAsync(path) |
pdf.SaveAs(path) |
Después de la traducción |
await page.CloseAsync() |
No es necesario | Limpieza automática |
await browser.CloseAsync() |
No es necesario | Limpieza automática |
PdfOptions.Format |
RenderingOptions.PaperSize |
Tamaño del papel |
PdfOptions.Landscape |
RenderingOptions.PaperOrientation |
Orientación |
PdfOptions.MarginOptions |
RenderingOptions.MarginTop/Bottom/Left/Right |
Márgenes individuales |
PdfOptions.PrintBackground |
RenderingOptions.PrintHtmlBackgrounds |
Impresión de fondo |
PdfOptions.HeaderTemplate |
RenderingOptions.HtmlHeader |
Encabezados HTML |
PdfOptions.FooterTemplate |
RenderingOptions.HtmlFooter |
Pies de página HTML |
page.WaitForSelectorAsync() |
RenderingOptions.WaitFor.HtmlElementId |
Esperar elemento |
Ejemplos de migración de código
Ejemplo 1: Conversión básica de HTML a PDF
Antes (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
Después (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
Este ejemplo demuestra la diferencia arquitectónica fundamental. PuppeteerSharprequiere seis operaciones asincrónicas: BrowserFetcher.DownloadAsync() (descarga de Chromium de más de 300 MB), Puppeteer.LaunchAsync(), browser.NewPageAsync(), page.SetContentAsync() y page.PdfAsync(), además de la eliminación adecuada con await using.
IronPDF elimina toda esta complejidad: crea un ChromePdfRenderer, llama a RenderHtmlAsPdf() y SaveAs(). Ni patrones asíncronos, ni ciclo de vida del navegador, ni descargas de Chromium. El enfoque deIronPDFofrece una sintaxis más limpia y una mejor integración con las aplicaciones .NET modernas. Consulte la documentación HTML a PDF para ver ejemplos completos.
Ejemplo 2: Conversión de URL a PDF
Antes (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
Después (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 usa GoToAsync() para navegar a una URL seguida de PdfAsync().IronPDFproporciona un único método RenderUrlAsPdf() que maneja la navegación y la generación de PDF en una sola llamada. Más información en nuestros tutoriales.
Ejemplo 3: Configuración de página personalizada con márgenes
Antes (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
Después (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
Este ejemplo muestra la correspondencia entre las opciones PDF de las dos bibliotecas. PuppeteerSharpusa PdfOptions con Format, Landscape y MarginOptions que contienen valores de cadena ("20mm").IronPDFutiliza propiedades RenderingOptions con enumeraciones directas de tamaño de papel, enumeraciones de orientación y valores de márgenes numéricos en milímetros.
Asignaciones clave:
Format = PaperFormat.A4→PaperSize = PdfPaperSize.A4Landscape = true→PaperOrientation = PdfPaperOrientation.LandscapeMarginOptions.Top = "20mm"→MarginTop = 20(milímetros numéricos)
El problema de las fugas de memoria
PuppeteerSharp es notorio por la acumulación de memoria bajo carga sostenida:
// ❌ 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 elimina la necesidad de la infraestructura de agrupación de navegadores que requiere 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
Notas de migración críticas
Conversión de Async a Sync
PuppeteerSharp requiere async/await en todo momento;IronPDFadmite operaciones síncronas:
// 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
Conversión de unidades de margen
PuppeteerSharp utiliza unidades de cadena;IronPDFutiliza milímetros numéricos:
// 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
Conversión de marcadores de posición de encabezado/pie
| Clase PuppeteerSharp | Marcador de posición IronPDF |
|---|---|
<span class='pageNumber'> |
{page} |
<span class='totalPages'> |
{total-pages} |
<span class='date'> |
{date} |
<span class='title'> |
{html-title} |
Nuevas capacidades tras la migración
Después de migrar a IronPDF, obtendrá capacidades que PuppeteerSharpno puede proporcionar:
Fusión de 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")
Marcas de agua
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)
Protección con contraseña
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
Firmas digitales
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)
Cumplimiento de PDF/A
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b);
pdf.SaveAsPdfA("archive.pdf", PdfAVersions.PdfA3b)
Resumen comparativo de prestaciones
| Métrica | PuppeteerSharp | IronPDF | Mejora |
|---|---|---|---|
| Primer PDF (Cold Start) | 45s+ | ~20s | 55%+ más rápido |
| PDF posteriores | Variable | Consistente | Predecible |
| Uso de memoria | 500MB+ (crece) | ~50 MB (estable) | 90% menos de memoria |
| Espacio en disco (Chromium) | mÁS DE 300 MB | 0 | Eliminar descargas |
| Navegador Descargar | Requerido | No es necesario | Cero configuración |
| Seguridad de los hilos | Limitado | Completo | Concurrencia fiable |
| Tiempo de generación de PDF | 45s | 20s | 55% más rápido |
Lista de comprobación de la migración
Pre-Migración
- Identificar todos los usos de PuppeteerSharpen el código base
- Valores de márgenes del documento (convertir cadenas a milímetros)
- Nota sobre la sintaxis de marcador de posición de encabezado/pie de página para la conversión
- Eliminar la infraestructura de agrupación/reciclaje del navegador
- Obtenga la clave de licencia deIronPDFen IronPDF
Cambios en el paquete
- Eliminar el paquete NuGet
PuppeteerSharp - Eliminar la carpeta
.local-chromiumpara recuperar ~300 MB de espacio en disco - Instalar
IronPdfel paquete NuGet :dotnet add package IronPdf
Cambios de código
- Actualizar las importaciones de espacios de nombres
- Eliminar llamadas
BrowserFetcher.DownloadAsync() - Eliminar
Puppeteer.LaunchAsync()y la administración del navegador - Reemplace
page.SetContentAsync()+page.PdfAsync()conRenderHtmlAsPdf() - Reemplace
page.GoToAsync()+page.PdfAsync()conRenderUrlAsPdf() - Convertir cadenas de margen a valores milimétricos
- Convertir la sintaxis de marcador de posición de encabezado/pie de página
- Eliminar todo el código de eliminación de páginas/navegadores
- Eliminar la infraestructura de agrupación de navegadores
- Agregar inicialización de licencia al iniciar la aplicación
Posmigración
- Comparación visual de la salida PDF
- Prueba de carga para la estabilidad de la memoria (debe permanecer estable sin reciclar)
- Verificar la representación del encabezado/pie de página con números de página
- Agregue nuevas capacidades (seguridad, marcas de agua, fusión) según sea necesario

