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

Como migrar do wkhtmltopdf para o IronPDF em C#

wkhtmltopdf tem sido uma ferramenta amplamente usada para converter documentos HTML em PDF usando Qt 4.8 + QtWebKit. Apesar de sua popularidade entre os desenvolvedores devido às suas funcionalidades de linha de comando e licenciamento gratuito, o projeto agora apresenta riscos críticos de segurança que não podem mais ser ignorados. O repositório GitHub foi arquivado em 2 de janeiro de 2023; a última versão upstream é 0.12.6 de 11 de junho de 2020; e CVE-2022-35583 (CVSS 9.8, SSRF) permanece sem correção.

Este guia fornece um caminho completo de migração do wkhtmltopdf para o IronPDF, com instruções passo a passo, comparações de código e exemplos práticos para desenvolvedores .NET profissionais que precisam eliminar esse risco de segurança de seus aplicativos.

Aviso de segurança crítico: CVE-2022-35583

A biblioteca wkhtmltopdf contém uma vulnerabilidade de segurança crítica que nunca será corrigida:

Emitir Detalhe Status
CVE-2022-35583 (SSRF, CWE-918) CRÍTICO (CVSS 9.8) NÃO CORRIGIDO — disputado pelos mantenedores
Repositório GitHub arquivado Somente leitura 2 de janeiro de 2023
Última versão upstream 0.12.6 11 de junho de 2020
Motor subjacente Qt 4.8 + QtWebKit (Qt 4.8 EOL 2015) OBSOLETO
Suporte a CSS Grid None Quebrado
Suporte a Flexbox Parcial Quebrado
JavaScript ES6+ Limitado Quebrado

Como funciona o ataque SSRF

A vulnerabilidade Server-Side Request Forgery permite que invasores acessem serviços internos, roubem credenciais, examinem sua rede interna e extraiam dados confidenciais por meio de HTML manipulado.


<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>

<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>
HTML

Quando o wkhtmltopdf renderiza esse HTML, ele busca esses URLs no contexto de rede do seu servidor, ignorando firewalls e controles de segurança.

Bibliotecas Wrapper afetadas

Cada wrapper .NET integra ou utiliza o mesmo binário nativo wkhtmltopdf, então todos herdam sua exposição CVE, independentemente de quão ativo o próprio wrapper seja:

Biblioteca Wrapper Último NuGet Risco de segurança
DinkToPdf 1.0.8 (abril de 2017) — abandonado Herdou o CVE-2022-35583
Rotativa.AspNetCore (webgio fork) 1.4.0 (novembro de 2023) — wrapper atualizado, binário congelado Herdou o CVE-2022-35583
Terça-feira Pechkin 2.1.1 (janeiro de 2015) — abandonado Herdou o CVE-2022-35583
Haukcode.WkHtmlToPdfDotNet (formerly WkHtmlToPdf-DotNet) 1.5.95 (outubro de 2024) — wrapper atualizado, binário congelado Herdou o CVE-2022-35583
NReco.PdfGenerator wrapper atualizado, integra wkhtmltopdf Herdou o CVE-2022-35583

Se você usar qualquer uma dessas bibliotecas, sua aplicação está exposta ao CVE-2022-35583 a menos que você higienize toda a entrada HTML.

IronPDF vs wkhtmltopdf: Comparação de Recursos

Compreender as diferenças arquitetônicas ajuda os responsáveis ​​pelas decisões técnicas a avaliar o investimento em migração:

Recurso wkhtmltopdf IronPDF
Licenciamento LGPLv3 (Gratuito) Comercial
Motor de renderização Qt 4.8 + QtWebKit (Qt 4.8 EOL 2015) Motor Chromium atual
Vulnerabilidades de segurança CVE-2022-35583 (CVSS 9.8) não corrigido, disputado Nenhum CVE crítico relatado
Manutenção ativa Repositório GitHub arquivado em 2 de janeiro de 2023; última versão em junho de 2020 Mantido ativamente com lançamentos regulares.
Suporte para padrões modernos da Web Limitado (Flexbox quebrado, sem CSS Grid) Apoiado
Integração e suporte Limitado a fóruns da comunidade Documentação completa e suporte dedicado.
Grade CSS ❌ Não suportado ✅ Compatível
Flexbox ⚠ Quebrado ✅ Compatível
JavaScript ES6+ ❌ Não suportado ✅ Compatível
Assíncrono/Aguardar ❌ Não suportado ✅ Compatível
Manipulação de PDF ❌ Não suportado ✅ Compatível
Assinaturas digitais ❌ Não suportado ✅ Compatível
Conformidade com PDF/A ❌ Não suportado ✅ Compatível

Guia rápido: Migração do wkhtmltopdf para o IronPDF

A migração pode começar imediatamente com esses passos fundamentais.

Passo 1: Remova os pacotes e binários do wkhtmltopdf

Remova todos os pacotes wrapper do wkhtmltopdf:

# Remove wkhtmltopdf wrapper (whichever you're using)
dotnet remove package Haukcode.WkHtmlToPdfDotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

# Remove wkhtmltopdf binary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
# Remove wkhtmltopdf wrapper (whichever you're using)
dotnet remove package Haukcode.WkHtmlToPdfDotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator

# Remove wkhtmltopdf binary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
SHELL

Passo 2: Instale o IronPDF

# Add IronPDF(secure, modern alternative)
dotnet add package IronPdf
# Add IronPDF(secure, modern alternative)
dotnet add package IronPdf
SHELL

Etapa 3: Atualizar Namespaces

Substituir namespaces wkhtmltopdf pelo namespace IronPDF:

// Before (wkhtmltopdf)
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;

// After (IronPDF)
using IronPdf;
// Before (wkhtmltopdf)
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;

// After (IronPDF)
using IronPdf;
Imports IronPdf
$vbLabelText   $csharpLabel

Etapa 4: Inicializar a licença

Adicionar inicialização de licença na inicialização do aplicativo:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

Exemplos de migração de código

Converter HTML para PDF

A operação mais fundamental revela a diferença de complexidade entre essas abordagens de PDF em .NET .

Abordagem wkhtmltopdf:

// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("output.pdf", pdf);
    }
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.WkHtmlToPdfDotNet.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = New List(Of ObjectSettings) From {
                New ObjectSettings() With {
                    .HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("output.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

Abordagem IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
        pdf.SaveAs("output.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

wkhtmltopdf requer a criação de um SynchronizedConverter com PdfTools, construindo um HtmlToPdfDocument com GlobalSettings e Objects, configurando propriedades como ColorMode, Orientation e PaperSize, chamando converter.Convert() para obter bytes brutos e escrevendo manualmente em um arquivo com File.WriteAllBytes().

IronPDF elimina completamente essa cerimônia — crie um ChromePdfRenderer, chame RenderHtmlAsPdf() e use o método SaveAs() embutido.

Para cenários avançados de conversão de HTML para PDF, consulte o guia de conversão de HTML para PDF .

Converter URLs em PDF

A conversão de URL para PDF apresenta padrões de complexidade semelhantes.

Abordagem wkhtmltopdf:

// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "https://www.example.com"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Portrait,
                PaperSize = PaperKind.A4
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "https://www.example.com"
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("webpage.pdf", pdf);
    }
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.WkHtmlToPdfDotNet.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = New List(Of ObjectSettings) From {
                New ObjectSettings() With {
                    .Page = "https://www.example.com"
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("webpage.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

Abordagem IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
        pdf.SaveAs("webpage.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

wkhtmltopdf usa a propriedade Page em ObjectSettings para especificar um URL, requerendo o mesmo padrão de construção de documento.IronPDF fornece um método RenderUrlAsPdf() dedicado que expressa claramente a intenção.

Consulte a documentação sobre URLs para PDF para obter informações sobre autenticação e opções de cabeçalho personalizadas.

Configurações personalizadas: Arquivos HTML com configuração de página

Configurar a orientação, as margens e o tamanho do papel requer abordagens diferentes.

Abordagem wkhtmltopdf:

// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "input.html",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom-output.pdf", pdf);
    }
}
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new SynchronizedConverter(new PdfTools());
        var doc = new HtmlToPdfDocument()
        {
            GlobalSettings = {
                ColorMode = ColorMode.Color,
                Orientation = Orientation.Landscape,
                PaperSize = PaperKind.A4,
                Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
            },
            Objects = {
                new ObjectSettings()
                {
                    Page = "input.html",
                    WebSettings = { DefaultEncoding = "utf-8" }
                }
            }
        };
        byte[] pdf = converter.Convert(doc);
        File.WriteAllBytes("custom-output.pdf", pdf);
    }
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.WkHtmlToPdfDotNet.Contracts
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Landscape,
                .PaperSize = PaperKind.A4,
                .Margins = New MarginSettings() With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
            },
            .Objects = {
                New ObjectSettings() With {
                    .Page = "input.html",
                    .WebSettings = New WebSettings() With {.DefaultEncoding = "utf-8"}
                }
            }
        }
        Dim pdf As Byte() = converter.Convert(doc)
        File.WriteAllBytes("custom-output.pdf", pdf)
    End Sub
End Module
$vbLabelText   $csharpLabel

Abordagem IronPDF:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

        var pdf = renderer.RenderHtmlFileAsPdf("input.html");
        pdf.SaveAs("custom-output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

        var pdf = renderer.RenderHtmlFileAsPdf("input.html");
        pdf.SaveAs("custom-output.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System

Class Program
    Shared Sub Main()
        Dim renderer As New ChromePdfRenderer()
        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
        renderer.RenderingOptions.MarginTop = 10
        renderer.RenderingOptions.MarginBottom = 10
        renderer.RenderingOptions.MarginLeft = 10
        renderer.RenderingOptions.MarginRight = 10
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4

        Dim pdf = renderer.RenderHtmlFileAsPdf("input.html")
        pdf.SaveAs("custom-output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

wkhtmltopdf aninha configurações dentro de GlobalSettings e Objects, com MarginSettings como um objeto separado.IronPDF fornece propriedades RenderingOptions diretas com nomes claros como PaperOrientation, MarginTop e PaperSize.

Referência de mapeamento da API wkhtmltopdf para IronPDF

Este mapeamento acelera a migração ao mostrar equivalentes diretos da API:

Mapeamento de CLI para IronPDF

Opção de linha de comando wkhtmltopdf Equivalente ao IronPDF
wkhtmltopdf input.html output.pdf renderer.RenderHtmlFileAsPdf()
wkhtmltopdf URL output.pdf renderer.RenderUrlAsPdf()
--page-size A4 RenderingOptions.PaperSize = PdfPaperSize.A4
--page-size Letter RenderingOptions.PaperSize = PdfPaperSize.Letter
--orientation Landscape RenderingOptions.PaperOrientation = Landscape
--margin-top 10mm RenderingOptions.MarginTop = 10
--margin-bottom 10mm RenderingOptions.MarginBottom = 10
--margin-left 10mm RenderingOptions.MarginLeft = 10
--margin-right 10mm RenderingOptions.MarginRight = 10
--header-html header.html RenderingOptions.HtmlHeader
--footer-center "[page]" {page} placeholder
--footer-center "[toPage]" {total-pages} placeholder
--enable-javascript Ativado por padrão
--javascript-delay 500 RenderingOptions.WaitFor.RenderDelay = 500
--dpi 300 RenderingOptions.Dpi = 300
--grayscale RenderingOptions.GrayScale = true

Mapeamento de API do Wrapper C

Wrapper wkhtmltopdf IronPDF
SynchronizedConverter ChromePdfRenderer
HtmlToPdfDocument RenderingOptions
GlobalSettings.Out pdf.SaveAs()
GlobalSettings.PaperSize RenderingOptions.PaperSize
GlobalSettings.Orientation RenderingOptions.PaperOrientation
GlobalSettings.Margins RenderingOptions.Margin*
ObjectSettings.Page RenderHtmlFileAsPdf()
ObjectSettings.HtmlContent RenderHtmlAsPdf()
converter.Convert(doc) renderer.RenderHtmlAsPdf()

Migração de sintaxe de espaço reservado

wkhtmltopdf Espaço reservado Espaço reservado para IronPDF
[page] {page}
[toPage] {total-pages}
[date] {date}
[time] {time}
[title] {html-title}
[url] {url}

Problemas e soluções comuns em migrações

Problema 1: Sintaxe de espaço reservado para cabeçalho/rodapé

wkhtmltopdf: Usa sintaxe de colchetes como [page] e [toPage].

Solução: Atualize os marcadores de posição para chaves do IronPDF:

// Before (wkhtmltopdf)
FooterSettings = { Left = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
    MaxHeight = 25
};
// Before (wkhtmltopdf)
FooterSettings = { Left = "Page [page] of [toPage]" }

// After (IronPDF)
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
    MaxHeight = 25
};
' Before (wkhtmltopdf)
FooterSettings = New With {.Left = "Page [page] of [toPage]"}

' After (IronPDF)
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
    .HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
    .MaxHeight = 25
}
$vbLabelText   $csharpLabel

Problema 2: Configuração de atraso em JavaScript

wkhtmltopdf: Usa a propriedade JavaScriptDelay com confiabilidade limitada.

Solução: O IronPDF oferece várias opções:

renderer.RenderingOptions.EnableJavaScript = true;

// Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500);

// Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");

// Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true");
renderer.RenderingOptions.EnableJavaScript = true;

// Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500);

// Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");

// Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true");
renderer.RenderingOptions.EnableJavaScript = True

' Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500)

' Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded")

' Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true")
$vbLabelText   $csharpLabel

Problema 3: CSS moderno não está sendo renderizado

Sintoma: Os layouts CSS Grid e Flexbox são renderizados incorretamente no wkhtmltopdf.

Solução: O mecanismo Chromium do IronPDF lida corretamente com o CSS moderno:

// This CSS now works with IronPDF
var html = @"
<style>
    .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
    .flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
    <div>Column 1</div>
    <div>Column 2</div>
    <div>Column 3</div>
</div>";

var pdf = renderer.RenderHtmlAsPdf(html);
// This CSS now works with IronPDF
var html = @"
<style>
    .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
    .flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
    <div>Column 1</div>
    <div>Column 2</div>
    <div>Column 3</div>
</div>";

var pdf = renderer.RenderHtmlAsPdf(html);
Dim html As String = "
<style>
    .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
    .flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
    <div>Column 1</div>
    <div>Column 2</div>
    <div>Column 3</div>
</div>"

Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

Edição 4: Renderização Síncrona vs. Assíncrona

wkhtmltopdf: Os wrappers são síncronos e bloqueiam threads.

Solução: O IronPDF suporta renderização assíncrona:

public async Task<byte[]> GeneratePdfAsync(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
    var renderer = new ChromePdfRenderer();
    var pdf = await renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}
Imports System.Threading.Tasks

Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
    Dim renderer As New ChromePdfRenderer()
    Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
    Return pdf.BinaryData
End Function
$vbLabelText   $csharpLabel

Lista de verificação de migração wkhtmltopdf

Tarefas pré-migração

Faça uma auditoria no seu código-fonte para identificar todas as utilizações de wkhtmltopdf:

# Find all wkhtmltopdf references
grep -r "Haukcode.WkHtmlToPdfDotNet\|WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa\|NReco.PdfGenerator" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
# Find all wkhtmltopdf references
grep -r "Haukcode.WkHtmlToPdfDotNet\|WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa\|NReco.PdfGenerator" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
SHELL

Localize e documente os arquivos binários do wkhtmltopdf para remoção. Documente as configurações atuais (tamanho do papel, margens, cabeçalhos/rodapés).

Tarefas de atualização de código

  1. Remova todos os pacotes NuGet que envolvem o wkhtmltopdf.
  2. Remova os binários do wkhtmltopdf (wkhtmltopdf.exe, wkhtmltox.dll)
  3. Instale o pacote NuGet do IronPDF
  4. Atualize as importações de namespace de Haukcode.WkHtmlToPdfDotNet (ou o wrapper que você usou) para IronPdf
  5. Substitua SynchronizedConverter por ChromePdfRenderer
  6. Converta padrões HtmlToPdfDocument para métodos de renderização direta
  7. Atualize configurações GlobalSettings para RenderingOptions
  8. Converta configurações de margem de MarginSettings para propriedades individuais
  9. Atualize a sintaxe do placeholder ([page]{page}, [toPage]{total-pages})
  10. Adicionar inicialização da licença do IronPDF na inicialização do sistema.

Testes pós-migração

Após a migração, verifique os seguintes aspectos:

  • Comparação visual da saída em PDF (deve melhorar com o suporte a CSS moderno)
  • Verificar renderização CSS moderna (CSS Grid e Flexbox agora funcionam)
  • Testar páginas com uso intensivo de JavaScript
  • Verificação de segurança para confirmar que não restam binários do wkhtmltopdf
  • Teste de carga para comparação de desempenho

Verificação de segurança

# Scan for any remaining wkhtmltopdf artifacts
find /var/www/ -name "*wkhtmlto*" 2>/dev/null
find /usr/local/bin/ -name "*wkhtmlto*" 2>/dev/null
docker images | grep wkhtmltopdf

# Check if any process is still using it
ps aux | grep wkhtmltopdf
# Scan for any remaining wkhtmltopdf artifacts
find /var/www/ -name "*wkhtmlto*" 2>/dev/null
find /usr/local/bin/ -name "*wkhtmlto*" 2>/dev/null
docker images | grep wkhtmltopdf

# Check if any process is still using it
ps aux | grep wkhtmltopdf
SHELL

Principais benefícios da migração para o IronPDF

A migração do wkhtmltopdf para o IronPDF oferece diversas vantagens importantes:

Segurança: As vulnerabilidades CVE-2022-35583 e todas as vulnerabilidades do wkhtmltopdf foram eliminadas. O IronPDF não possui vulnerabilidades CVE conhecidas e recebe atualizações de segurança regularmente.

Mecanismo de renderização moderno: O IronPDF utiliza o mecanismo Chromium atual, garantindo suporte completo a CSS3, CSS Grid, Flexbox e JavaScript ES6+. Os frameworks modernos renderizam corretamente.

API simplificada: Métodos de renderização direta substituem os padrões de construção de documentos. Métodos SaveAs() embutidos eliminam o manuseio manual de bytes.

Funcionalidades avançadas: manipulação de PDFs, assinaturas digitais, conformidade com PDF/A, marcas d'água e operações de mesclagem/divisão são recursos integrados que o wkhtmltopdf não oferecia.

Desenvolvimento Ativo: As atualizações regulares do IronPDF acompanham as versões atuais do .NET, para que as versões modernas do .NET e da linguagem C# sejam suportadas conforme são lançadas.

Suporte a assincronismo: Evite o bloqueio de threads em aplicações web de alta carga com suporte nativo a async/await.

ObserveDinkToPdf, NReco, Rotativa, TuesPechkin e wkhtmltopdf são marcas registradas de seus respectivos proprietários. Este site não é afiliado, endossado ou patrocinado por DinkToPdf, NReco, Rotativa, TuesPechkin ou wkhtmltopdf. Todos os nomes de produtos, logotipos e marcas são propriedade de seus respectivos proprietários. As comparações são apenas para fins informativos e refletem informações disponíveis publicamente no momento da redação.

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 Iron

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