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

Como migrar do wkhtmltopdf para o IronPDF em C#

O wkhtmltopdf tem sido uma ferramenta amplamente utilizada para converter documentos HTML em PDF usando o Qt WebKit. 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. A biblioteca foi oficialmente abandonada em 2016-2017, e uma vulnerabilidade de gravidade CRÍTICA (CVE-2022-35583) permanece permanentemente 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 Gravidade Status
CVE-2022-35583 CRÍTICO (9,8/10) SEM CORREÇÃO
Vulnerabilidade SSRF risco de aquisição de infraestrutura SEM CORREÇÃO
Última atualização 2016-2017 ABANDONADO
Versão WebKit 2015 (Qt WebKit) OBSOLETO
Suporte a CSS Grid Nenhum Quebrado
Suporte a Flexbox Parcial Quebrado
JavaScript ES6+ Nenhum 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

Todos os wrappers .NET para wkhtmltopdf herdam estas vulnerabilidades:

Biblioteca Wrapper Status Risco de segurança
DinkToPdf Abandonado ⚠️ CRÍTICO
Rotativa Abandonado ⚠️ CRÍTICO
Terça-feira Pechkin Abandonado ⚠️ CRÍTICO
WkHtmlToPdf-DotNet Abandonado ⚠️ CRÍTICO
NReco.PdfGenerator Utiliza wkhtmltopdf ⚠️ CRÍTICO

Se você utiliza alguma dessas bibliotecas, está vulnerável ao CVE-2022-35583.

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 WebKit (2015) Motor Chromium atual
Vulnerabilidades de segurança CVE-2022-35583, problemas graves não corrigidos Nenhuma CVE conhecida
Manutenção ativa Abandonado, sem atualizações significativas desde 2017. 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 WkHtmlToPdf-DotNet
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 WkHtmlToPdf-DotNet
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

Substitua os namespaces wkhtmltopdf pelo namespace IronPDF :

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

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

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

' After (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 WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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 WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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 WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter = New SynchronizedConverter(New PdfTools())
        Dim doc = New HtmlToPdfDocument() With {
            .GlobalSettings = New GlobalSettings() With {
                .ColorMode = ColorMode.Color,
                .Orientation = Orientation.Portrait,
                .PaperSize = PaperKind.A4
            },
            .Objects = {
                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 Class
$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, a construção de um HtmlToPdfDocument com GlobalSettings e Objects, a definição de propriedades como ColorMode, Orientation e PaperSize, a chamada de converter.Convert() para obter bytes brutos e a escrita manual em um arquivo com File.WriteAllBytes().

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

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 WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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 WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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 WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports 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 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 uma URL, exigindo o mesmo padrão de construção de documento. O 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 WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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 WkHtmlToPdf-DotNet
using WkHtmlToPdfDotNet;
using 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 WkHtmlToPdf-DotNet
Imports WkHtmlToPdfDotNet
Imports WkHtmlToPdfDotNet.Contracts
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter As New SynchronizedConverter(New PdfTools())
        Dim doc As 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 Class
$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. O 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} espaço reservado
--footer-center "[toPage]" {total-pages} espaço reservado
--enable-javascript Ativado por padrão
--javascript-delay 500 RenderingOptions.WaitFor.RenderDelay = 500
--dpi 300 RenderingOptions.Dpi = 300
--grayscale RenderingOptions.GrayScale = true

Mapeamento da API Wrapper em 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 a 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 "WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
# Find all wkhtmltopdf references
grep -r "WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa" --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 IronPDF
  4. Atualizar as importações de namespace de WkHtmlToPdfDotNet para IronPdf
  5. Substitua SynchronizedConverter por ChromePdfRenderer
  6. Converter padrões HtmlToPdfDocument em métodos de renderização direta
  7. Atualize as configurações de GlobalSettings para RenderingOptions
  8. Converter configurações de margem de MarginSettings para propriedades individuais
  9. Atualizar a sintaxe do marcador de posição ([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. Os métodos integrados SaveAs() 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: À medida que a adoção do .NET 10 e do C# 14 aumenta até 2026, as atualizações regulares do IronPDF garantem a compatibilidade com as versões atuais e futuras do .NET .

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

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