Ir para o conteúdo do rodapé
GUIAS DE MIGRAçãO

Como migrar do PuppeteerSharp para o IronPDF em C#

A migração do MarionetistaAfiado para o IronPDF transforma seu fluxo de trabalho de geração de PDFs, passando de uma ferramenta de automação de navegador com dependências de mais de 300 MB para uma biblioteca de PDFs desenvolvida especificamente para essa finalidade, com gerenciamento automático de memória. Este guia fornece um caminho de migração completo, passo a passo, que elimina os downloads do Chromium, resolve problemas de vazamento de memória e oferece recursos abrangentes de manipulação de PDFs.

Por que migrar do MarionetistaAfiado para o IronPDF?

Entendendo o PuppeteerSharp

PuppeteerSharp é uma versão .NET do Puppeteer do Google, que traz recursos de automação de navegador para C#. Ele gera PDFs usando a funcionalidade integrada de impressão para PDF do Chrome — o mesmo que pressionar Ctrl+P em um navegador. Isso produz um resultado pronto para impressão, otimizado para papel, que difere do que você vê na tela.

O MarionetistaAfiado foi projetado para testes e extração de dados da web, não para geração de documentos. Embora seja uma ferramenta capaz, o uso do MarionetistaAfiado para geração de PDFs apresenta desafios significativos de produção.

O problema da automação do navegador

O MarionetistaAfiado foi projetado para automação de navegadores, não para geração de documentos. Isso cria problemas fundamentais ao usá-lo com PDFs:

  1. É necessário fazer o download do Chromium (mais de 300 MB) antes do primeiro uso. Uma desvantagem significativa do MarionetistaAfiado é o seu tamanho de implantação considerável, principalmente devido ao binário do Chromium que ele inclui. Esse tamanho considerável pode inflar as imagens do Docker e causar problemas de inicialização a frio em ambientes sem servidor.

  2. Vazamentos de memória sob carga que exigem reinicialização manual do navegador. Sob carga pesada, o MarionetistaAfiado é conhecido por apresentar vazamentos de memória. O acúmulo de memória pelas instâncias do navegador exige intervenção manual para o gerenciamento e a reciclagem do processo.

  3. Padrões assíncronos complexos com gerenciamento do ciclo de vida do navegador.

  4. Impressão em PDF (equivalente a Ctrl+P, não captura de tela). Os layouts podem ser redimensionados, os planos de fundo podem ser omitidos por padrão e a saída é paginada para impressão em vez de corresponder à área visível do navegador.

  5. Não há suporte para PDF/A ou PDF/UA para atender aos requisitos de conformidade. O MarionetistaAfiado não consegue gerar documentos compatíveis com PDF/A (arquivísticos) ou PDF/UA (acessíveis).

  6. Sem manipulação de PDF - apenas geração, sem mesclagem/divisão/edição. Embora o MarionetistaAfiado seja eficiente na geração de PDFs, ele carece de recursos para manipulação adicional, como mesclagem, divisão, proteção ou edição de PDFs.

Comparação entre MarionetistaAfiado e IronPDF

Aspecto MarionetistaAfiado IronPDF
Objetivo principal Automação do navegador Geração de PDF
Dependência do Chromium Download separado de mais de 300 MB Motor otimizado integrado
Complexidade da API Ciclo de vida assíncrono do navegador/página Frases curtas síncronas
Inicialização BrowserFetcher.DownloadAsync() + LaunchAsync new ChromePdfRenderer()
Gerenciamento de memória Reciclagem manual do navegador necessária Automático
Memória sob carga Mais de 500 MB com vazamentos ~50MB estável
Partida a frio 45+ segundos ~20 segundos
Suporte PDF/A Não disponível Apoiado
Acessibilidade PDF/UA Não disponível Apoiado
Edição de PDF Não disponível Mesclar, dividir, carimbar, editar
Assinaturas digitais Não disponível Apoiado
Segurança da rosca Limitado Completo
Suporte profissional Comunidade Comercial com SLA

Suporte da plataforma

| Biblioteca | .NET Framework 4.7.2 | .NET Core 3.1 | .NET 6-8 | .NET 10 | | --------- | :---: | :---: | :---: | :---: || IronPDF | Completo | Completo | Completo | Completo || MarionetistaAfiado | Limitado | Completo | Completo | Pendente | O amplo suporte do IronPDF em plataformas .NET garante que os desenvolvedores possam utilizá-lo em diversos ambientes sem encontrar problemas de compatibilidade, oferecendo uma opção flexível para aplicações .NET modernas até 2025 e 2026.


Antes de começar

Pré-requisitos

  1. Ambiente .NET : .NET Framework 4.6.2+ ou .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. Acesso ao NuGet : Capacidade de instalar pacotes NuGet.
  3. Licença do IronPDF : Obtenha sua chave de licença em IronPDF

Alterações no pacote 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

Não é necessário nenhum BrowserFetcher.DownloadAsync() com o IronPDF - o mecanismo de renderização já está incluído automaticamente.

Configuração de licença

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

Referência completa da API

Alterações de namespace

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

Mapeamentos da API principal

API MarionetistaAfiado API IronPDF Notas
new BrowserFetcher().DownloadAsync() Não é necessário Sem download no navegador
Puppeteer.LaunchAsync(options) Não é necessário Sem gerenciamento de navegador
browser.NewPageAsync() Não é necessário Sem contexto de página
page.GoToAsync(url) renderer.RenderUrlAsPdf(url) Renderização direta
page.SetContentAsync(html) renderer.RenderHtmlAsPdf(html) Renderização direta
page.PdfAsync(path) pdf.SaveAs(path) Após a renderização
await page.CloseAsync() Não é necessário Limpeza automática
await browser.CloseAsync() Não é necessário Limpeza automática
PdfOptions.Format RenderingOptions.PaperSize Tamanho do papel
PdfOptions.Landscape RenderingOptions.PaperOrientation Orientação
PdfOptions.MarginOptions RenderingOptions.MarginTop/Bottom/Left/Right margens individuais
PdfOptions.PrintBackground RenderingOptions.PrintHtmlBackgrounds Impressão de fundo
PdfOptions.HeaderTemplate RenderingOptions.HtmlHeader Cabeçalhos HTML
PdfOptions.FooterTemplate RenderingOptions.HtmlFooter Rodapés HTML
page.WaitForSelectorAsync() RenderingOptions.WaitFor.HtmlElementId Aguarde o elemento

Exemplos de migração de código

Exemplo 1: Conversão básica de HTML para 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
$vbLabelText   $csharpLabel

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

Este exemplo demonstra a diferença arquitetônica fundamental. O MarionetistaAfiado requer seis operações assíncronas: BrowserFetcher.DownloadAsync() (download do Chromium de mais de 300 MB), Puppeteer.LaunchAsync(), browser.NewPageAsync(), page.SetContentAsync() e page.PdfAsync(), além do descarte adequado com await using.

IronPDF elimina toda essa complexidade: crie um ChromePdfRenderer, chame RenderHtmlAsPdf() e SaveAs(). Sem padrões assíncronos, sem ciclo de vida do navegador, sem downloads do Chromium. A abordagem do IronPDF oferece uma sintaxe mais limpa e melhor integração com aplicativos .NET modernos. Consulte a documentação de conversão de HTML para PDF para obter exemplos completos.

Exemplo 2: Conversão de URL para 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
$vbLabelText   $csharpLabel

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

O MarionetistaAfiado usa GoToAsync() para navegar até um URL seguido por PdfAsync(). IronPDF fornece um único método RenderUrlAsPdf() que lida com a navegação e a geração de PDF em uma única chamada. Saiba mais em nossos tutoriais .

Exemplo 3: Configurações de página personalizadas com margens

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

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

Este exemplo mostra como as opções de PDF são mapeadas entre as duas bibliotecas. MarionetistaAfiado usa PdfOptions com Format, Landscape e MarginOptions contendo valores de string ("20mm"). O IronPDF usa propriedades RenderingOptions com enumerações diretas de tamanho de papel, enumerações de orientação e valores numéricos de margem em milímetros.

Mapeamentos de teclas:

  • Format = PaperFormat.A4PaperSize = PdfPaperSize.A4
  • Landscape = truePaperOrientation = PdfPaperOrientation.Landscape
  • MarginOptions.Top = "20mm"MarginTop = 20 (milímetros numéricos)

O problema do vazamento de memória

O MarionetistaAfiado é conhecido por acumular memória sob carga contínua:

// ❌ MarionetistaAfiado - 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
}
// ❌ MarionetistaAfiado - 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
}
' ❌ MarionetistaAfiado - 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

O IronPDF elimina a necessidade da infraestrutura de agrupamento de navegadores exigida pelo 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

Notas críticas sobre migração

Conversão de assíncrono para síncrono

O MarionetistaAfiado requer async/await em todas as suas etapas; O IronPDF suporta operações 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
$vbLabelText   $csharpLabel

Conversão de Unidades de Margem

PuppeteerSharp usa unidades de corda; O IronPDF usa milímetros numéricos:

// MarionetistaAfiado - 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;
// MarionetistaAfiado - 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;
' MarionetistaAfiado - 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

Conversão de espaços reservados para cabeçalho/rodapé

Marionetista Classe Afiada Espaço reservado para IronPDF
<span class='pageNumber'> {page}
<span class='totalPages'> {total-pages}
<span class='date'> {date}
<span class='title'> {html-title}

Novas funcionalidades após a migração

Após migrar para o IronPDF, você obtém recursos que o MarionetistaAfiado não pode fornecer:

Fusão de PDFs

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

Marcas d'água

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

Proteção por senha

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

Assinaturas digitais

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

Conformidade com PDF/A

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

Resumo da comparação de desempenho

Métrica MarionetistaAfiado IronPDF Melhoria
Primeiro PDF (Inicialização a frio) 45s+ ~20s 55% mais rápido
PDFs subsequentes Variável Consistente Previsível
Uso de memória Mais de 500 MB (e continua crescendo) ~50 MB (estável) 90% menos memória
Espaço em disco (Chromium) 300 MB ou mais 0 Eliminar downloads
Download do navegador Obrigatório Não é necessário Configuração zero
Segurança da rosca Limitado Completo Concorrência confiável
Tempo de geração do PDF 45s anos 20 55% mais rápido

Lista de verificação para migração

Pré-migração

  • Identificar todas as utilizações do MarionetistaAfiado na base de código.
  • Valores de margem do documento (converter strings em milímetros)
  • Observe a sintaxe dos espaços reservados para cabeçalho/rodapé para conversão.
  • Eliminar a infraestrutura de agrupamento/reciclagem de navegadores
  • Obtenha a chave de licença do IronPDF em IronPDF

Alterações no pacote

  • Remover o pacote NuGet PuppeteerSharp
  • Exclua a pasta .local-chromium para recuperar aproximadamente 300 MB de espaço em disco.
  • Instale o pacote NuGet IronPdf: dotnet add package IronPdf

Alterações no código

  • Atualizar importações de namespace
  • Remover chamadas BrowserFetcher.DownloadAsync()
  • Remover Puppeteer.LaunchAsync() e gerenciamento do navegador
  • Substitua page.SetContentAsync() + page.PdfAsync() por RenderHtmlAsPdf()
  • Substitua page.GoToAsync() + page.PdfAsync() por RenderUrlAsPdf()
  • Converter strings de margem em valores em milímetros
  • Converter sintaxe de espaço reservado de cabeçalho/rodapé
  • Remover todos os códigos de descarte de navegador/página
  • Excluir a infraestrutura de agrupamento de navegadores
  • Adicionar inicialização de licença na inicialização do aplicativo

Pós-migração

  • Comparação visual da saída em PDF
  • Teste de carga para estabilidade da memória (deve permanecer estável sem reinicialização)
  • Verificar a renderização do cabeçalho/rodapé com os números de página
  • Adicionar novas funcionalidades (segurança, marcas d'água, mesclagem) conforme necessário.

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais ...

Leia mais

Equipe de suporte de ferro

Estamos online 24 horas por dia, 5 dias por semana.
Bater papo
E-mail
Liga para mim