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"/>
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.
Passo 2: Instale o IronPDF
# Add IronPDF (secure, modern alternative)
dotnet add package IronPdf
# Add IronPDF (secure, modern alternative)
dotnet add package IronPdf
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
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"
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
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
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
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
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
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
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
}
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")
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)
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
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" .
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
- Remova todos os pacotes NuGet que envolvem o wkhtmltopdf.
- Remova os binários do wkhtmltopdf (wkhtmltopdf.exe, wkhtmltox.dll)
- Instale o pacote NuGet IronPDF
- Atualizar as importações de namespace de
WkHtmlToPdfDotNetparaIronPdf - Substitua
SynchronizedConverterporChromePdfRenderer - Converter padrões
HtmlToPdfDocumentem métodos de renderização direta - Atualize as configurações de
GlobalSettingsparaRenderingOptions - Converter configurações de margem de
MarginSettingspara propriedades individuais - Atualizar a sintaxe do marcador de posição (
[page]→{page},[toPage]→{total-pages}) - 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
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.

