
IronPDF ou EvoPdf: qual biblioteca PDF for .NET oferece melhor custo-benefício em 2026?
Ao desenvolver aplicações modernas em .NET que exigem funcionalidades de PDF, escolher a biblioteca certa pode impactar significativamente a velocidade de desenvolvimento, o desempenho da aplicação e os custos de manutenção a longo prazo. IronPDF e EvoPdf representam duas abordagens distintas para geração e manipulação de PDFs no ecossistema .NET, cada uma com pontos fortes únicos que atendem a diferentes cenários de desenvolvimento.
Esta comparação examina ambas as bibliotecas em dimensões críticas, incluindo precisão de renderização, design da API, considerações de desempenho, compatibilidade de plataforma e custo total de propriedade. Seja você responsável por um sistema de processamento de documentos em alto volume, assinatura de documentos ou apenas conversão de relatórios HTML para PDF, entender essas diferenças ajudará a tomar uma decisão informada alinhada aos seus requisitos técnicos e restrições orçamentárias.
Como IronPDF e EvoPdf se Comparam em um Relance?
Antes de mergulhar nas comparações detalhadas, aqui está uma visão geral de como essas bibliotecas se comparam nas principais categorias que mais importam para desenvolvedores .NET:
| Categoria | Recurso/Aspecto | IronPDF | EvoPdf | Vantagem Principal |
|---|---|---|---|---|
| Arquitetura Principal | Filosofia de Design | Simplicidade em primeiro lugar, APIs intuitivas | Controle granular sobre configurações de conversão | Depende da preferência da equipe |
| Complexidade da API | Métodos simples como RenderHtmlAsPdf() | Classe Converter com métodos como ConvertHtml() | Ambos: Conversão em chamada única | |
| Suporte a Plataforma | Multiplataforma | Windows, Linux, macOS via pacotes NuGet específicos por plataforma | EvoPdf Next: Windows, Linux, macOS via pacotes NuGet por plataforma; EvoPdf Classic: Windows, além de um cliente multiplataforma que chama um EVO PDF Server hospedado separadamente | Ambos: Renderização local multiplataforma (EvoPdf Next) |
| Versões do .NET | .NET 10, 9, 8, 7, 6, 5, Core 3.1+, Standard 2.0, Framework 4.6.2+ | Next: .NET 10, 9, 8, 7, 6, Standard 2.0, Framework 4.6.2+; Classic: Framework 2.0+ | Ambos: Suporte a frameworks modernos | |
| Sistemas Operacionais | Windows, Linux, macOS, Docker, Azure, AWS | Windows, Linux, macOS, Docker, Azure (EvoPdf Next) | Ambos: Suporte a Docker e nuvem | |
| HTML para PDF | Motor de Renderização | Chromium (CEF 109 no pacote padrão; CEF 131 em IronPdf.UpdatedChrome) | Chromium 142 (EvoPdf Next); motor próprio EVO (EvoPdf Classic) | Ambos: Baseados em Chromium |
| Suporte a CSS3/HTML5 | Depende da versão do Chromium incluída: no Windows, 109 no pacote padrão e 131 em IronPdf.UpdatedChrome (por exemplo, Tailwind CSS v4 requer Chrome 111 ou superior) | Next: flexbox, grid, ES2015+, web fonts | Ambos: Depende da versão do motor | |
| Execução de JavaScript | Suporte a JavaScript com atraso de renderização | Suporte a JavaScript com atraso de conversão | Ambos: Conteúdo dinâmico | |
| Segurança & Criptografia | Níveis de Criptografia | RC4-128, AES-128, AES-256 | RC4-40, RC4-128, AES-128, AES-256 | Ambos: AES-256 disponível |
| Opções de Permissão | Controles granulares de permissão | Permissões granulares (imprimir, copiar, editar, anotar, preencher formulários, montar) | Ambos: Controle granular | |
| Assinaturas Digitais | Assinaturas integradas e visuais | Assinaturas visíveis com suporte a imagem e carimbo de data/hora | Ambos: Assinaturas visuais | |
| Manipulação de Conteúdo | Método de Redação | Remoção real de conteúdo, API de uma linha | Sem recurso de redação documentado | IronPDF: Redação integrada |
| Marca d'água | Baseada em HTML/CSS, estilização completa | Templates HTML para marcas d'água e carimbos | Ambos: Baseados em HTML | |
| Carimbagem | Classes unificadas de carimbo | Carimbos HTML via templates | IronPDF: Classes de carimbo dedicadas | |
| Conversões de Arquivo | DOCX para PDF | Integrado DocxToPdfRenderer | Incluído no EVO PDF Toolkit (a partir de $650), não incluso na licença HTML para PDF | IronPDF: Incluído na licença base |
| Experiência do Desenvolvedor | Exemplos de Código | Mais de 100 exemplos prontos para uso | Exemplos de código no GitHub, demonstração online | IronPDF: Recursos extensos |
| Documentação | Tutoriais, passo a passo, vídeos, referência de API | Documentação, referência de API, FAQ de suporte | IronPDF: Diversos caminhos de aprendizado | |
| Desempenho | Concorrência | Métodos de renderização assíncronos | Métodos assíncronos (EvoPdf Next); renderizador persistente para conversões paralelas | Ambos: Cargas de trabalho concorrentes |
| Licenciamento & Preços | Nível de Entrada | Lite: $999 (1 dev, 1 projeto) | Deployment: $450 (1 aplicação em 1 servidor, desenvolvedores ilimitados, sem redistribuição) | EvoPdf: Custo inicial menor |
| Licença de Equipe | Plus: $1,499 (3 devs, 3 projetos) | Nenhum nível conta desenvolvedores; Company: $1,200 (aplicações e servidores ilimitados) | EvoPdf: Preço não depende do tamanho da equipe | |
| Redistribuição | +$1,999 royalty-free (OEM/SaaS); uma API pública que expõe IronPDF precisa de licença SDK | Apenas na Company License; não como serviço de conversão independente ou SDK | EvoPdf: Incluído na Company License | |
| Opção Suite | Iron Suite Lite: $2,998 (10 produtos; 1 desenvolvedor, 1 local, 1 projeto) | EVO PDF Toolkit Company: $1,400 | Escopo diferente: Iron Suite adiciona OCR, barcode e ferramentas Office | |
| Suporte | Suporte Incluso | Sim: chat ao vivo 24/5; suporte 24/7 com Suporte Premium (incluso durante o trial) | Sim, primeiro ano (standard ou priority, conforme licença) | Ambos: Suporte incluso |
| Melhor Para | Casos de Uso | Apps web modernos, PDFs complexos, redação | HTML, Word e Excel para PDF com licenciamento para toda a empresa | Depende do contexto |
Nota. EvoPdf oferece preços competitivos para grandes equipes. IronPDF inclui redação integrada e conversão DOCX para PDF em sua licença base.
Entendendo IronPDF e EvoPdf: Pontos Fortes e Filosofia
O Que Destaca o IronPDF no Mercado de Bibliotecas PDF para .NET?
IronPDF é uma biblioteca PDF para .NET projetada com foco na produtividade do desenvolvedor. Construída sobre uma base de simplicidade sem sacrificar o poder, IronPDF permite que desenvolvedores .NET criem, editem e manipulem documentos PDF usando APIs intuitivas que espelham padrões familiares do desenvolvimento web. O principal destaque da biblioteca é seu motor de renderização baseado em Chromium, que executa JavaScript e carrega web fonts; o quanto de CSS moderno é suportado depende da versão do Chromium que você distribui. O pacote padrão IronPdf inclui Chromium 109 para compatibilidade com Windows Servers antigos; o pacote exclusivo para Windows IronPdf.UpdatedChrome inclui Chromium 131 e lida corretamente com recursos CSS mais recentes como subgrid, mas não suporta processos 32-bit, Windows Server 2012 ou modo SingleProcess, então os dois pacotes não são intercambiáveis em todos os alvos.
A biblioteca é voltada para aplicações que renderizam documentos HTML, manipulam PDFs existentes e protegem documentos com criptografia, assinaturas e redação. Seu extenso conjunto de recursos inclui não apenas geração básica de PDF, mas também funcionalidades avançadas como assinaturas digitais, preenchimento de formulários, integração com OCR via IronOCR e conversões de formatos de documentos como DOCX para PDF. A compatibilidade multiplataforma do IronPDF vai além do simples suporte a frameworks, rodando em Windows, Linux, macOS, containers Docker e plataformas em nuvem como Azure e AWS.
Como a Abordagem do EvoPdf para Geração de PDF é Diferente?
O EvoPdf foca na conversão de HTML para PDF com ênfase em personalização e controle. A biblioteca oferece aos desenvolvedores controle granular sobre o processo de conversão, permitindo ajustes finos de parâmetros de renderização, layouts de página e configurações de conversão. O EvoPdf é distribuído em duas edições: EvoPdf Next, que usa um motor de renderização baseado em Chromium (Chromium 142, segundo a EVO PDF) e roda em Windows, Linux e macOS, e EvoPdf Classic, que usa o motor próprio da EVO e roda em Windows. O EVO PDF Toolkit adiciona conversão de Word, Excel, RTF e Markdown para PDF, além de componentes de processamento de PDF.
Um destaque do EvoPdf é seu licenciamento: nenhum nível de licença conta desenvolvedores, e a licença Company cobre aplicações e servidores ilimitados e inclui redistribuição dentro de suas próprias aplicações. Para cargas de trabalho de servidor em alto volume, o EvoPdf Next documenta um modo de renderizador persistente que mantém o motor de renderização ativo entre conversões. A biblioteca também suporta cenários ASP.NET como conversão de páginas que exigem cookies de autenticação.
Como as Capacidades Multiplataforma se Comparam Entre as Bibliotecas?
Arquitetura Multiplataforma Moderna do IronPDF
O IronPDF roda em várias versões do .NET, sistemas operacionais e plataformas em nuvem:
- Suporte a Versões do .NET:
- .NET 10, 9, 8, 7, 6, 5 e Core 3.1+
- .NET Standard 2.0+
- .NET Framework 4.6.2+
- Suporte completo para C#, VB.NET e F#
- Compatibilidade com Sistemas Operacionais:
- Windows (x64; x86 apenas com o pacote padrão, pois IronPdf.UpdatedChrome não suporta processos 32-bit)
- Linux (Ubuntu, Debian, CentOS; Alpine via container IronPdfEngine)
- macOS (Intel e Apple Silicon)
- Containers Docker com imagens pré-configuradas
- Integração com Plataformas em Nuvem:
- Azure App Service, Functions e VMs
- AWS Lambda e EC2
- Implantações em Kubernetes
O IronPDF distribui seus binários Chromium em pacotes NuGet específicos por plataforma (IronPdf para Windows, IronPdf.Linux, IronPdf.MacOs e IronPdf.MacOs.ARM). No Linux, o IronPDF tenta instalar dependências de sistema ausentes automaticamente por padrão; isso requer direitos de sudo, caso contrário as dependências são instaladas manualmente. Isso mantém os passos de implantação curtos para a maioria dos ambientes.
Suporte a Plataforma do EvoPdf
O EvoPdf suporta uma gama semelhante de versões do .NET, com suporte de plataforma que depende da edição:
- Suporte ao .NET Framework:
- EvoPdf Next: .NET 10, 9, 8, 7 e 6, .NET Standard 2.0, .NET Framework 4.6.2 a 4.8.1
- EvoPdf Classic: .NET 10 a 6, .NET Standard 2.0, .NET Framework 2.0 e superior
- Considerações de Plataforma:
- EvoPdf Next: Windows (x64, ARM64), Linux (x64, ARM64) e macOS (ARM64), com um pacote NuGet por plataforma
- EvoPdf Next roda em Azure App Service, Azure Functions e Docker; o motor de renderização é hospedado no processo da aplicação, sem navegador para instalar
- EvoPdf Classic: renderiza localmente apenas no Windows
- Cliente EvoPdf Classic: roda em Windows, Linux e macOS e envia conversões para um EVO PDF Server instalado separadamente (instalado como serviço em nuvem Azure, aplicação IIS ou serviço Windows)
O EvoPdf Next fornece renderização local nativa em Windows, Linux e macOS. Uma aplicação baseada em EvoPdf Classic que precisa rodar em Linux ou macOS pode migrar para o EvoPdf Next, para o qual a EVO PDF publica um guia de migração Classic para Next, ou manter a renderização Classic em um EVO PDF Server separado e chamá-lo via biblioteca cliente.
Qual Biblioteca Oferece Melhor Funcionalidade PDF para Tarefas Comuns?
Cada exemplo de código neste artigo é um programa de console .NET 8 completo: crie um projeto com dotnet new console, adicione o pacote NuGet nomeado no primeiro comentário do exemplo e substitua o Program.cs pelo exemplo. Os exemplos declaram seus próprios using, então compilam com ou sem usings implícitos. Eles foram compilados e executados com IronPdf 2026.9.2, EvoPdf.HtmlToPdf 14.0.2 e EvoPdf.PdfSecurity 14.0.2. O IronPDF precisa de uma chave de licença, como uma chave de avaliação gratuita, definida via IronPdf.License.LicenseKey ou uma entrada IronPdf.LicenseKey em appsettings.json. O EvoPdf roda sem chave e adiciona uma marca d'água de avaliação na saída.
Conversão de HTML para PDF: Qualidade de Renderização e Desempenho
O recurso mais fundamental de ambas as bibliotecas é a conversão de HTML para PDF, e suas APIs adotam abordagens diferentes.
Exemplo de HTML para PDF com IronPDF
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using IronPdf.Rendering;
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
EnableJavaScript = true,
// Page margins in millimetres
MarginTop = 20,
MarginBottom = 20,
MarginLeft = 15,
MarginRight = 15,
CssMediaType = PdfCssMediaType.Print,
ViewPortWidth = 1920,
FitToPaperMode = FitToPaperModes.Automatic
}
};
// Render only after the page calls window.ironpdf.notifyRender(), or after 10 seconds at most
renderer.RenderingOptions.WaitFor.JavaScript(10000);
// The page loads Chart.js and a Google Font from their CDNs, so the renderer needs network access
var htmlContent = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'>
<style>
body { font-family: 'Roboto', sans-serif; }
.chart-container { width: 100%; height: 400px; }
@media print {
.no-print { display: none; }
}
</style>
<script src='https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js'></script>
</head>
<body>
<h1>Dynamic Sales Report</h1>
<div class='chart-container'>
<canvas id='salesChart'></canvas>
</div>
<script>
new Chart(document.getElementById('salesChart'), {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales 2025',
data: [65, 78, 90, 81, 96],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
},
// No animation, so the chart is fully drawn when the constructor returns
options: { animation: false }
});
window.ironpdf.notifyRender();
</script>
</body>
</html>";
using var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("sales-report.pdf");' NuGet: Install-Package IronPdf
Imports IronPdf
Imports IronPdf.Engines.Chrome
Imports IronPdf.Rendering
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.EnableJavaScript = True,
' Page margins in millimetres
.MarginTop = 20,
.MarginBottom = 20,
.MarginLeft = 15,
.MarginRight = 15,
.CssMediaType = PdfCssMediaType.Print,
.ViewPortWidth = 1920,
.FitToPaperMode = FitToPaperModes.Automatic
}
}
' Render only after the page calls window.ironpdf.notifyRender(), or after 10 seconds at most
renderer.RenderingOptions.WaitFor.JavaScript(10000)
' The page loads Chart.js and a Google Font from their CDNs, so the renderer needs network access
Dim htmlContent = "
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'>
<style>
body { font-family: 'Roboto', sans-serif; }
.chart-container { width: 100%; height: 400px; }
@media print {
.no-print { display: none; }
}
</style>
<script src='https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js'></script>
</head>
<body>
<h1>Dynamic Sales Report</h1>
<div class='chart-container'>
<canvas id='salesChart'></canvas>
</div>
<script>
new Chart(document.getElementById('salesChart'), {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales 2025',
data: [65, 78, 90, 81, 96],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
},
options: { animation: false }
});
window.ironpdf.notifyRender();
</script>
</body>
</html>"
Using pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("sales-report.pdf")
End UsingEste exemplo do IronPDF mostra:
- Execução de JavaScript: O JavaScript da página (aqui Chart.js) é executado antes da renderização
- Sinal de Renderização Explícito:
WaitFor.JavaScript()espera a página chamarwindow.ironpdf.notifyRender()ao invés de adivinhar com um atraso fixo - Web Fonts: Fontes referenciadas pela página são carregadas e incorporadas
- Consultas de Mídia para Impressão:
CssMediaType.Printaplica as regras@media printda página
Exemplo de HTML para PDF com EvoPdf
// NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
using System.IO;
using EvoPdf;
HtmlToPdfConverter converter = new HtmlToPdfConverter();
// Production use needs a license key. Leave this line out to evaluate:
// the output then carries an evaluation watermark. An invalid key makes the conversion throw.
// converter.LicenseKey = "<your EvoPdf license key>";
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
converter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait;
// EvoPdf margins are in points (1/72 inch): 57 pt is about 20 mm, 43 pt about 15 mm,
// matching the IronPDF example above, whose margins are in millimetres
converter.PdfDocumentOptions.TopMargin = 57;
converter.PdfDocumentOptions.BottomMargin = 57;
converter.PdfDocumentOptions.LeftMargin = 43;
converter.PdfDocumentOptions.RightMargin = 43;
converter.JavaScriptEnabled = true;
converter.ConversionDelay = 2; // seconds
// For pages behind HTTP authentication, also set
// converter.AuthenticationOptions.Username and .Password
// Convert HTML string
string htmlString = @"
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; }
</style>
</head>
<body>
<h1>Invoice</h1>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr>
<td>Product A</td>
<td>5</td>
<td>$50.00</td>
</tr>
</table>
</body>
</html>";
// Perform conversion
byte[] pdfBytes = converter.ConvertHtml(htmlString, "");
// Save to file
File.WriteAllBytes("invoice.pdf", pdfBytes);' NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
Imports System.IO
Imports EvoPdf
Dim converter As New HtmlToPdfConverter()
' Production use needs a license key. Leave this line out to evaluate:
' the output then carries an evaluation watermark. An invalid key makes the conversion throw.
' converter.LicenseKey = "<your EvoPdf license key>"
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
converter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait
' EvoPdf margins are in points (1/72 inch): 57 pt is about 20 mm, 43 pt about 15 mm,
' matching the IronPDF example above, whose margins are in millimetres
converter.PdfDocumentOptions.TopMargin = 57
converter.PdfDocumentOptions.BottomMargin = 57
converter.PdfDocumentOptions.LeftMargin = 43
converter.PdfDocumentOptions.RightMargin = 43
converter.JavaScriptEnabled = True
converter.ConversionDelay = 2 ' seconds
' For pages behind HTTP authentication, also set
' converter.AuthenticationOptions.Username and .Password
' Convert HTML string
Dim htmlString As String = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; }
</style>
</head>
<body>
<h1>Invoice</h1>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr>
<td>Product A</td>
<td>5</td>
<td>$50.00</td>
</tr>
</table>
</body>
</html>"
' Perform conversion
Dim pdfBytes() As Byte = converter.ConvertHtml(htmlString, "")
' Save to file
File.WriteAllBytes("invoice.pdf", pdfBytes)O conversor do EvoPdf segue o padrão configurar-depois-converter: defina PdfDocumentOptions, depois chame ConvertHtml() ou ConvertUrl(). Todo exemplo EvoPdf neste artigo usa a API Classic (EvoPdf.HtmlToPdf), que renderiza no Windows. O EvoPdf Next, edição baseada em Chromium, é um conjunto separado de pacotes NuGet com sua própria API: por exemplo, a chave de licença é definida uma vez por processo na propriedade estática Licensing.LicenseKey. A EVO documenta suporte no Next para flexbox, grid, JavaScript ES2015+ e web fonts.
Segurança e Criptografia PDF: Protegendo Documentos Sensíveis
A segurança é fundamental ao lidar com documentos sensíveis. Ambas as bibliotecas oferecem proteção por senha, controles de permissão e criptografia.
Implementação Avançada de Segurança no IronPDF
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Editing;
using IronPdf.Security;
using IronPdf.Signing;
using IronSoftware.Drawing;
using var pdf = PdfDocument.FromFile("confidential-report.pdf");
// Finish every content change before signing
pdf.ApplyWatermark("<h2 style='color:red; opacity:0.5;'>CONFIDENTIAL</h2>",
45, VerticalAlignment.Middle, HorizontalAlignment.Center);
// Descriptive document properties (these do not restrict access)
pdf.MetaData.Author = "Finance Team";
pdf.MetaData.Title = "Quarterly Report (Internal)";
pdf.MetaData.ModifiedDate = DateTime.UtcNow;
// Owner password: required to change the permissions below
pdf.SecuritySettings.OwnerPassword = "owner-password";
// User password: required to open the document
pdf.SecuritySettings.UserPassword = "user-password";
pdf.SecuritySettings.AllowUserCopyPasteContentForAccessibility = false;
pdf.SecuritySettings.AllowUserAnnotations = false;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserFormData = true;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.PrintLowQuality;
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256;
// Visible digital signature: image file, page index, and position/size on the page
var signature = new PdfSignature("certificate.pfx", "cert-password")
{
SigningReason = "Document Approval",
SigningLocation = "Head Office",
SigningContact = "security@example.com",
SignatureImage = new PdfSignatureImage("signature.png", 0, new Rectangle(100, 100, 200, 50))
};
pdf.Sign(signature);
// The signature is applied when the file is saved
pdf.SaveAs("secured-document.pdf");' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Imports IronPdf.Editing
Imports IronPdf.Security
Imports IronPdf.Signing
Imports IronSoftware.Drawing
Dim pdf = PdfDocument.FromFile("confidential-report.pdf")
' Finish every content change before signing
pdf.ApplyWatermark("<h2 style='color:red; opacity:0.5;'>CONFIDENTIAL</h2>", 45, VerticalAlignment.Middle, HorizontalAlignment.Center)
' Descriptive document properties (these do not restrict access)
pdf.MetaData.Author = "Finance Team"
pdf.MetaData.Title = "Quarterly Report (Internal)"
pdf.MetaData.ModifiedDate = DateTime.UtcNow
' Owner password: required to change the permissions below
pdf.SecuritySettings.OwnerPassword = "owner-password"
' User password: required to open the document
pdf.SecuritySettings.UserPassword = "user-password"
pdf.SecuritySettings.AllowUserCopyPasteContentForAccessibility = False
pdf.SecuritySettings.AllowUserAnnotations = False
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserFormData = True
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.PrintLowQuality
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256
' Visible digital signature: image file, page index, and position/size on the page
Dim signature = New PdfSignature("certificate.pfx", "cert-password") With {
.SigningReason = "Document Approval",
.SigningLocation = "Head Office",
.SigningContact = "security@example.com",
.SignatureImage = New PdfSignatureImage("signature.png", 0, New Rectangle(100, 100, 200, 50))
}
pdf.Sign(signature)
' The signature is applied when the file is saved
pdf.SaveAs("secured-document.pdf")Os recursos de segurança do IronPDF mostrados aqui:
- Permissões Granulares: Controle de qualidade de impressão, cópia, anotações, preenchimento de formulários e edições
- Assinaturas Digitais Visíveis: Uma assinatura com motivo, local e imagem de assinatura
- Propriedades do Documento: Defina autor, título e datas (apenas descritivo)
- Proteção em Camadas: Combine marca d'água, criptografia e assinatura em um documento
Configuração de Segurança no EvoPdf
// NuGet: Install-Package EvoPdf.PdfSecurity
// (licensed with the EVO PDF Toolkit; not included in the standalone HTML to PDF license)
using EvoPdf.PdfSecurity;
PdfSecurityOptions securityOptions = new PdfSecurityOptions();
// Set basic security parameters
securityOptions.UserPassword = "user123";
securityOptions.OwnerPassword = "owner456";
securityOptions.EncryptionAlgorithm = EncryptionAlgorithm.AES;
securityOptions.KeySize = EncryptionKeySize.EncryptKey256Bit;
// Configure permissions
securityOptions.CanPrint = true;
securityOptions.CanCopyContent = false;
securityOptions.CanEditContent = false;
securityOptions.CanEditAnnotations = false;
securityOptions.CanFillFormFields = true;
securityOptions.CanAssembleDocument = false;
// Apply security to existing PDF
PdfSecurityManager securityManager = new PdfSecurityManager(securityOptions);
securityManager.SaveSecuredPdfToFile("input.pdf", "secured-output.pdf");' NuGet: Install-Package EvoPdf.PdfSecurity
' (licensed with the EVO PDF Toolkit; not included in the standalone HTML to PDF license)
Imports EvoPdf.PdfSecurity
Dim securityOptions As New PdfSecurityOptions()
' Set basic security parameters
securityOptions.UserPassword = "user123"
securityOptions.OwnerPassword = "owner456"
securityOptions.EncryptionAlgorithm = EncryptionAlgorithm.AES
securityOptions.KeySize = EncryptionKeySize.EncryptKey256Bit
' Configure permissions
securityOptions.CanPrint = True
securityOptions.CanCopyContent = False
securityOptions.CanEditContent = False
securityOptions.CanEditAnnotations = False
securityOptions.CanFillFormFields = True
securityOptions.CanAssembleDocument = False
' Apply security to existing PDF
Dim securityManager As New PdfSecurityManager(securityOptions)
securityManager.SaveSecuredPdfToFile("input.pdf", "secured-output.pdf")O EvoPdf cobre os mesmos controles principais: senhas de usuário e proprietário, criptografia e permissões para impressão, cópia, edição, anotações, preenchimento de formulários e montagem de documentos. A EVO documenta o algoritmo (RC4 ou AES) e o tamanho da chave (40, 128 ou 256 bits) como configurações separadas; em nossos testes com a versão 14.0.2, RC4 com chaves de 40 ou 128 bits e AES com 128 ou 256 bits produziram a criptografia esperada, então use AES-128 ou AES-256; RC4 é um algoritmo legado. Com a licença HTML para PDF independente, as próprias PdfSecurityOptions do conversor aplicam a mesma proteção enquanto o PDF está sendo gerado, sem o componente PDF Security separado.
Redação de Conteúdo: Removendo Informações Sensíveis
Remover permanentemente texto sensível antes de compartilhar um documento é um requisito comum em aplicações que lidam com dados pessoais. A redação é um dos blocos para esse trabalho; sozinha, não torna uma aplicação compatível com regulamentos como GDPR, HIPAA ou CCPA.
Exemplo de Redação com IronPDF
// NuGet: Install-Package IronPdf
using IronPdf;
using IronSoftware.Drawing;
// This example expects a PDF with at least three pages
using var pdf = PdfDocument.FromFile("customer-records.pdf");
// 1. Redact a specific value on every page
pdf.RedactTextOnAllPages("123-45-6789");
// 2. Redact a word on specific pages (zero-based page indexes)
pdf.RedactTextOnPages(new[] { 0, 1, 2 }, "Confidential", CaseSensitive: false);
// 3. Redact a rectangular region on the first page
pdf.RedactRegionOnPage(0, new RectangleF(100, 200, 300, 50));
// 4. Replace a complete sensitive value with a label instead of drawing a black box
pdf.RedactTextOnAllPages("ACCT-0042-7781", DrawRectangles: false, ReplacementText: "[REDACTED]");
pdf.SaveAs("redacted-records.pdf");' NuGet: Install-Package IronPdf
Imports IronPdf
Imports IronSoftware.Drawing
' This example expects a PDF with at least three pages
Dim pdf = PdfDocument.FromFile("customer-records.pdf")
' 1. Redact a specific value on every page
pdf.RedactTextOnAllPages("123-45-6789")
' 2. Redact a word on specific pages (zero-based page indexes)
pdf.RedactTextOnPages(New Integer() {0, 1, 2}, "Confidential", CaseSensitive:=False)
' 3. Redact a rectangular region on the first page
pdf.RedactRegionOnPage(0, New RectangleF(100, 200, 300, 50))
' 4. Replace a complete sensitive value with a label instead of drawing a black box
pdf.RedactTextOnAllPages("ACCT-0042-7781", DrawRectangles:=False, ReplacementText:="[REDACTED]")
pdf.SaveAs("redacted-records.pdf")As capacidades de redação do IronPDF incluem:
- Remoção de Conteúdo: O texto correspondente é removido do conteúdo da página, não podendo mais ser extraído, não apenas coberto
- Opções de Correspondência: Correspondência sensível a maiúsculas/minúsculas e palavras inteiras
- Aparência da Redação: Desenhe caixas pretas ou insira texto de substituição
- Redação Seletiva: Direcione páginas ou regiões específicas
A redação de texto corresponde ao texto no conteúdo da página. Texto dentro de imagens, como uma página escaneada, não é correspondido; uma redação por região cobre uma área fixa independentemente do que está nela. O EvoPdf não documenta um recurso de redação.
Manipulação de Formulários: Criando PDFs Interativos
Ambas as bibliotecas suportam formulários PDF, mas com abordagens diferentes para criação e manipulação.
Exemplo de Formulários com IronPDF
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
// Create a new PDF with an HTML form
var html = @"
<html>
<body>
<h2>Employee Information Form</h2>
<form>
<label>Full Name:</label>
<input type='text' name='fullName' required />
<label>Email:</label>
<input type='email' name='email' required />
<label>Department:</label>
<select name='department'>
<option value=''>Select Department</option>
<option value='IT'>Information Technology</option>
<option value='HR'>Human Resources</option>
<option value='Sales'>Sales</option>
</select>
<label>Start Date:</label>
<input type='text' name='startDate' placeholder='YYYY-MM-DD' />
<label>
<input type='checkbox' name='agreement' />
I agree to the terms and conditions
</label>
<button type='submit'>Submit</button>
</form>
</body>
</html>";
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
CreatePdfFormsFromHtml = true // Enable form field creation
}
};
using var pdf = renderer.RenderHtmlAsPdf(html);
// Programmatically fill form fields
pdf.Form.FindFormField("fullName").Value = "John Doe";
pdf.Form.FindFormField("email").Value = "john.doe@example.com";
// A dropdown takes one of its displayed choices, not the HTML option value ("IT")
pdf.Form.FindFormField("department").Value = "Information Technology";
pdf.Form.FindFormField("startDate").Value = DateTime.Now.ToString("yyyy-MM-dd");
// "Yes" is the checkbox's checked state
pdf.Form.FindFormField("agreement").Value = "Yes";
// Make specific fields read-only
pdf.Form.FindFormField("email").ReadOnly = true;
// Save as fillable form
pdf.SaveAs("fillable-form.pdf");
// Or flatten the form (convert to static content)
pdf.Flatten();
pdf.SaveAs("completed-form.pdf");' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
' Create a new PDF with an HTML form
Dim html = "
<html>
<body>
<h2>Employee Information Form</h2>
<form>
<label>Full Name:</label>
<input type='text' name='fullName' required />
<label>Email:</label>
<input type='email' name='email' required />
<label>Department:</label>
<select name='department'>
<option value=''>Select Department</option>
<option value='IT'>Information Technology</option>
<option value='HR'>Human Resources</option>
<option value='Sales'>Sales</option>
</select>
<label>Start Date:</label>
<input type='text' name='startDate' placeholder='YYYY-MM-DD' />
<label>
<input type='checkbox' name='agreement' />
I agree to the terms and conditions
</label>
<button type='submit'>Submit</button>
</form>
</body>
</html>"
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.CreatePdfFormsFromHtml = True ' Enable form field creation
}
}
Using pdf = renderer.RenderHtmlAsPdf(html)
' Programmatically fill form fields
pdf.Form.FindFormField("fullName").Value = "John Doe"
pdf.Form.FindFormField("email").Value = "john.doe@example.com"
' A dropdown takes one of its displayed choices, not the HTML option value ("IT")
pdf.Form.FindFormField("department").Value = "Information Technology"
pdf.Form.FindFormField("startDate").Value = DateTime.Now.ToString("yyyy-MM-dd")
' "Yes" is the checkbox's checked state
pdf.Form.FindFormField("agreement").Value = "Yes"
' Make specific fields read-only
pdf.Form.FindFormField("email").ReadOnly = True
' Save as fillable form
pdf.SaveAs("fillable-form.pdf")
' Or flatten the form (convert to static content)
pdf.Flatten()
pdf.SaveAs("completed-form.pdf")
End UsingRecursos de manipulação de formulários do IronPDF:
- Geração Automática de Formulários: Converte formulários HTML em formulários PDF
- Manipulação Programática: Preencha, leia e modifique campos de formulário via API
- Tipos de Campo: Inputs de texto (incluindo email, número e telefone) e áreas de texto viram campos de texto; checkboxes, radio buttons e dropdowns mantêm seu tipo. Inputs HTML de data não são convertidos em campos de formulário, por isso a data inicial acima usa um input de texto.
- Propriedades de Campo: Defina valores e flags de somente leitura
- Achatamento de Formulários: Converta formulários preenchidos em PDFs estáticos
Considerações de Desempenho
As características de desempenho variam significativamente conforme a complexidade do documento e o caso de uso:
Cronometrando um Lote de Documentos
// NuGet: Install-Package IronPdf
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using IronPdf;
// Timing harness for a batch of documents. Replace the generated HTML with your own templates.
const int documentCount = 100;
const int maxConcurrency = 4;
var htmlDocuments = Enumerable.Range(1, documentCount)
.Select(i => $"<html><body><h1>Invoice {i}</h1><p>Amount due: {i * 10} USD</p></body></html>")
.ToList();
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
EnableJavaScript = false // static content only
}
};
// Cap how many renders run at once instead of starting every render immediately
using var gate = new SemaphoreSlim(maxConcurrency);
var stopwatch = Stopwatch.StartNew();
var tasks = htmlDocuments.Select(async (html, index) =>
{
await gate.WaitAsync();
try
{
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
pdf.SaveAs($"invoice-{index + 1}.pdf");
}
finally
{
gate.Release();
}
});
await Task.WhenAll(tasks);
stopwatch.Stop();
Console.WriteLine($"Documents: {documentCount}, at most {maxConcurrency} at a time");
Console.WriteLine($"Total elapsed: {stopwatch.ElapsedMilliseconds} ms");
// Elapsed time divided by the document count: an amortized figure, not the latency of one request
Console.WriteLine($"Amortized time per document: {stopwatch.ElapsedMilliseconds / (double)documentCount:F1} ms");
// Resident memory of this process only, sampled once at the end; the Chromium helper
// processes are not included, and this is not the peak
Console.WriteLine($"Working set of this process at end: {Process.GetCurrentProcess().WorkingSet64 / 1024 / 1024} MB");' NuGet: Install-Package IronPdf
Imports System
Imports System.Diagnostics
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks
Imports IronPdf
' Timing harness for a batch of documents. Replace the generated HTML with your own templates.
Const documentCount As Integer = 100
Const maxConcurrency As Integer = 4
Dim htmlDocuments = Enumerable.Range(1, documentCount) _
.Select(Function(i) $"<html><body><h1>Invoice {i}</h1><p>Amount due: {i * 10} USD</p></body></html>") _
.ToList()
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.EnableJavaScript = False ' static content only
}
}
' Cap how many renders run at once instead of starting every render immediately
Using gate As New SemaphoreSlim(maxConcurrency)
Dim stopwatch = Stopwatch.StartNew()
Dim tasks = htmlDocuments.Select(Async Function(html, index)
Await gate.WaitAsync()
Try
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
pdf.SaveAs($"invoice-{index + 1}.pdf")
End Using
Finally
gate.Release()
End Try
End Function)
Await Task.WhenAll(tasks)
stopwatch.Stop()
Console.WriteLine($"Documents: {documentCount}, at most {maxConcurrency} at a time")
Console.WriteLine($"Total elapsed: {stopwatch.ElapsedMilliseconds} ms")
' Elapsed time divided by the document count: an amortized figure, not the latency of one request
Console.WriteLine($"Amortized time per document: {stopwatch.ElapsedMilliseconds / CDbl(documentCount):F1} ms")
' Resident memory of this process only, sampled once at the end; the Chromium helper
' processes are not included, and this is not the peak
Console.WriteLine($"Working set of this process at end: {Process.GetCurrentProcess().WorkingSet64 / 1024 / 1024} MB")
End UsingEste artigo não apresenta benchmark comparativo: os resultados dependem de templates, hardware e implantação, então meça com os seus próprios. Alavancas documentadas para cada biblioteca:
- Versão do motor IronPDF: Para renderizações lentas de páginas modernas, pesadas em JavaScript ou profundamente aninhadas, incluindo páginas baseadas em Bootstrap ou Tailwind, o IronPDF recomenda o pacote IronPdf.UpdatedChrome, que inclui Chromium 131 em vez do Chromium 109 do pacote padrão
- Concorrência IronPDF: Métodos de renderização assíncronos como
RenderHtmlAsPdfAsync, com seu próprio limite de quantas renderizações rodam simultaneamente - Modos de renderização EvoPdf Next:
GlobalSettings.HtmlRendererModedefinido comoPersistentProcess(padrão) mantém um processo do motor de renderização ativo entre conversões, eProcessPerConversioninicia um por conversão; conversões podem rodar em paralelo, cada uma com seu próprio conversor, eGlobalSettings.MaxParallelConversionslimita quantas rodam ao mesmo tempo - Métodos assíncronos EvoPdf Next:
ConvertHtmlAsynceConvertUrlAsyncpara código async/await
Como os Modelos de Preço se Comparam para Diferentes Tamanhos de Equipe?
Estrutura de Licenciamento do IronPDF
O IronPDF oferece várias opções de preço, incluindo licenças Lite, Plus e Professional, com opção de redistribuição royalty-free. O modelo de licenciamento é projetado para escalar conforme as necessidades da equipe e do projeto (preços de setembro de 2026):
- Licença Lite: $999
- 1 desenvolvedor
- 1 local
- 1 projeto
- Suporte por e-mail
- Ideal para: Desenvolvedores individuais, pequenos projetos
- Licença Plus: $1,499
- 3 desenvolvedores
- 3 locais
- 3 projetos
- Suporte por e-mail (SLA de 48h) e chat ao vivo
- Ideal para: Pequenas equipes, múltiplos projetos
- Licença Professional: $2,399
- 10 desenvolvedores
- 10 locais
- 10 projetos
- Suporte por e-mail (SLA de 24h), chat ao vivo, telefone e compartilhamento de tela
- Ideal para: Equipes médias a grandes
- Opções Adicionais:
- Redistribuição royalty-free (OEM/SaaS): +$1,999, para software comercial e SaaS onde usuários finais não chamam as APIs do IronPDF diretamente
- Licença SDK: necessária quando um produto expõe a funcionalidade do IronPDF para outros desenvolvedores via API pública
- Extensões de suporte e atualizações: 1, 3 ou 5 anos, preço conforme o nível da licença
- Iron Suite: todos os 10 produtos Iron Software, licenciados nos mesmos níveis; Iron Suite Lite (1 desenvolvedor, 1 local, 1 projeto) é $2,998
Opções de Licenciamento do EvoPdf
O EVO PDF Toolkit e o conversor HTML para PDF independente oferecem dois níveis de licença, Deployment e Company (preços de setembro de 2026; verifique preços atuais em evopdf.com/buy). A licença HTML para PDF cobre os conversores Next e Classic; os outros componentes, como PDF Security, só estão incluídos no Toolkit.
- Licença Deployment:
- EVO HTML to PDF: $450
- EVO PDF Toolkit: $650
- Uma aplicação implantada em um servidor, usada por sua própria empresa
- Desenvolvedores ilimitados trabalhando nessa aplicação
- Implantações balanceadas, em containers ou autoscaladas precisam de Company License
- Sem redistribuição
- Suporte padrão no primeiro ano
- Licença Company:
- EVO HTML to PDF: $1,200
- EVO PDF Toolkit: $1,400
- Desenvolvedores, aplicações e servidores ilimitados
- Redistribuição para seus próprios clientes dentro de suas aplicações; o contrato de licença não permite oferecer a funcionalidade de conversão como serviço independente, API hospedada ou SDK sem permissão escrita da EVO
- Suporte prioritário no primeiro ano
Análise do Custo Total de Propriedade
Cada cenário abaixo declara suas premissas de implantação, pois ambos os fornecedores precificam por escopo além do tamanho da equipe:
Cenário 1: Dois Desenvolvedores, Uma Aplicação Interna em Um Servidor
- IronPDF Plus: $1,499 (Lite cobre 1 desenvolvedor, então uma equipe de 2 pessoas precisa do Plus, que cobre até 3)
- EvoPdf Deployment: $450 (uma aplicação em um servidor; desenvolvedores não são contados)
- Se a aplicação rodar em vários servidores, atrás de um balanceador de carga ou em containers autoscalados, o EvoPdf precisa da Company License ($1,200)
- Custo de licença menor: EvoPdf
Cenário 2: Cinco Desenvolvedores, Várias Aplicações Internas
- IronPDF Professional: $2,399 (até 10 desenvolvedores, 10 locais, 10 projetos; Plus cobre apenas 3 desenvolvedores)
- EvoPdf Company: $1,200 (mais de uma aplicação requer a Company License)
- Custo de licença menor: EvoPdf
Cenário 3: Dez Desenvolvedores Precisando de PDF e Outras Ferramentas de Documentos
- Iron Suite Professional: 10 desenvolvedores, 10 locais, 10 projetos, todos os 10 produtos Iron Software (veja a página de licenciamento do Iron Suite para o preço atual)
- EVO PDF Toolkit Company: $1,400 (desenvolvedores, aplicações e servidores ilimitados; foco em PDF, sem ferramentas de OCR ou barcode)
- Escopo diferente: o EVO PDF Toolkit custa menos se você só precisa de ferramentas PDF. O Iron Suite adiciona OCR, barcode, Excel, Word e outras bibliotecas, que o Toolkit não substitui. Compare os dois apenas com escopo de desenvolvedor e implantação equivalentes.
Cenário 4: Produto SaaS Comercial Que Gera PDFs para Seus Clientes
- IronPDF Profissional + redistribuição OEM: $2,399 + $1,999 (cobre SaaS onde os usuários finais não chamam as APIs do IronPDF diretamente)
- EvoPdf Empresa: $1,200 (inclui redistribuição; a geração de PDF deve ser um recurso do seu produto e não um serviço de conversão de uso geral)
- Custo de licença mais baixo: EvoPdf, desde que o produto não exponha a funcionalidade de conversão como um serviço ou API pública; ambos os fornecedores licenciam esse caso separadamente
Como os Frameworks CSS Modernos Afetam Sua Escolha?
Um fator frequentemente subestimado na seleção de bibliotecas PDF é o suporte a frameworks CSS modernos. Com Bootstrap, Tailwind CSS e Foundation amplamente utilizados no desenvolvimento web, a capacidade da sua biblioteca de lidar com esses frameworks impacta diretamente a eficiência do desenvolvimento e a qualidade do resultado.
IronPDF: Suporte a Frameworks Depende da Versão do Chromium
O mecanismo Chromium do IronPDF renderiza frameworks CSS conforme a versão do Chromium incluída, então verifique os requisitos de navegador de um framework em relação ao pacote que você distribui:
- Bootstrap 5: Layouts Flexbox e CSS Grid são suportados
- Tailwind CSS: Tailwind CSS v4 requer Chrome 111 ou superior, que é mais recente que o Chromium 109 do pacote padrão do Windows, então no Windows layouts v4 precisam do pacote IronPdf.UpdatedChrome (Chromium 131). A Tailwind recomenda permanecer na v3.4 onde navegadores antigos precisam ser suportados. Teste seus próprios templates com o pacote que você implanta.
- CSS3 Moderno: Transforms e propriedades customizadas são suportadas
- A versão do engine importa: Alguns CSS mais recentes, como
subgrid, casos extremos deoverflow: hiddene alturas de linha personalizadas, renderizam corretamente apenas com o IronPdf.UpdatedChrome, que o IronPDF também recomenda quando páginas Bootstrap ou Tailwind renderizam lentamente. O IronPdf.UpdatedChrome não suporta processos 32-bit, Windows Server 2012 ou modoSingleProcess, então confirme seus alvos de implantação antes de mudar.
Exemplo de Código: Componente Timeline do Bootstrap
// NuGet: Install-Package IronPdf
using IronPdf;
var renderer = new ChromePdfRenderer();
string bootstrapTimeline = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
<style>
.timeline { position: relative; padding: 20px 0; }
.timeline::before {
content: '';
position: absolute;
left: 50%;
width: 2px;
height: 100%;
background: #dee2e6;
}
.timeline-item { position: relative; margin: 20px 0; }
</style>
</head>
<body>
<div class='container py-5'>
<h2 class='text-center mb-5'>Project Timeline</h2>
<div class='timeline'>
<div class='timeline-item'>
<div class='row'>
<div class='col-md-6'>
<div class='card shadow-sm'>
<div class='card-body'>
<h5 class='card-title'>Phase 1: Planning</h5>
<p class='text-muted'>Q1 2025</p>
<p class='card-text'>Initial project scope and requirements gathering completed.</p>
<span class='badge bg-success'>Completed</span>
</div>
</div>
</div>
</div>
</div>
<!-- Additional timeline items... -->
</div>
</div>
</body>
</html>";
// The page loads Bootstrap from a CDN, so the renderer needs network access
using var pdf = renderer.RenderHtmlAsPdf(bootstrapTimeline);
pdf.SaveAs("project-timeline.pdf");' NuGet: Install-Package IronPdf
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim bootstrapTimeline As String = "
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
<style>
.timeline { position: relative; padding: 20px 0; }
.timeline::before {
content: '';
position: absolute;
left: 50%;
width: 2px;
height: 100%;
background: #dee2e6;
}
.timeline-item { position: relative; margin: 20px 0; }
</style>
</head>
<body>
<div class='container py-5'>
<h2 class='text-center mb-5'>Project Timeline</h2>
<div class='timeline'>
<div class='timeline-item'>
<div class='row'>
<div class='col-md-6'>
<div class='card shadow-sm'>
<div class='card-body'>
<h5 class='card-title'>Phase 1: Planning</h5>
<p class='text-muted'>Q1 2025</p>
<p class='card-text'>Initial project scope and requirements gathering completed.</p>
<span class='badge bg-success'>Completed</span>
</div>
</div>
</div>
</div>
</div>
<!-- Additional timeline items... -->
</div>
</div>
</body>
</html>"
' The page loads Bootstrap from a CDN, so the renderer needs network access
Using pdf = renderer.RenderHtmlAsPdf(bootstrapTimeline)
pdf.SaveAs("project-timeline.pdf")
End UsingEvoPdf: Chromium no Next, Engine Próprio no Classic
As duas edições do EvoPdf lidam com CSS moderno de formas diferentes:
- EvoPdf Next: Engine baseado em Chromium (Chromium 142, segundo a EVO PDF) com suporte documentado a flexbox, grid, JavaScript ES2015+ e web fonts
- EvoPdf Classic: Engine de renderização próprio da EVO, que a EVO descreve como suportando CSS3, SVG, web fonts e JavaScript; a Nova Edição adiciona ECMAScript 6, WOFF 2, HTTP/2 e TLS 1.3
Impacto no Desenvolvimento: Se sua aplicação usa Bootstrap ou Tailwind extensivamente e você precisa de PDFs que correspondam à sua interface web, teste seus templates reais com o trial de cada biblioteca. Com engines baseados em Chromium em ambos os lados (IronPDF e EvoPdf Next), as diferenças provavelmente virão da versão do engine e da configuração, e não do suporte ao framework.
Para mais sobre compatibilidade com frameworks CSS, veja o Guia Bootstrap & Flexbox CSS.
Quais Opções de Documentação e Suporte Melhor Atendem os Desenvolvedores?
Recursos para Desenvolvedores do IronPDF
O IronPDF oferece documentação, chat ao vivo 24/5, suporte de engenharia 24/7 com Suporte Premium, tutoriais em vídeo e atualizações regulares. O ecossistema de suporte inclui:
- Qualidade da Documentação:
- Referência da API
- Tutoriais passo a passo
- Mais de 100 exemplos de código
- Tutoriais em vídeo no YouTube
- Guias de migração de outras bibliotecas
- Canais de Suporte:
- Suporte de engenharia 24/7 com Suporte Premium, disponível para licenças pagas; usuários em avaliação recebem Suporte Premium durante o trial
- SLA de resposta por e-mail: 48 horas (Plus), 24 horas (Professional), 12 horas (Unlimited)
- Chat ao vivo em todos os níveis de licença, 24/5
- Suporte telefônico para licenças Professional e Unlimited
- Compartilhamento de tela nas licenças Professional e Unlimited
- Recursos de Aprendizado:
- Guias de primeiros passos
- Guias de otimização de performance
- Melhores práticas de segurança
- Guias de implantação em nuvem
Estrutura de Suporte do EvoPdf
O EvoPdf oferece documentação e suporte por meio de:
- Documentação:
- Documentação de referência da API
- Exemplos de código para cenários comuns, além de amostras de código no GitHub
- Aplicação de demonstração online
- FAQ de suporte cobrindo licenciamento, implantação e conversão
- Opções de Suporte:
- Suporte técnico incluído no primeiro ano, e gratuito durante a avaliação
- Suporte padrão (licença Deployment) ou suporte prioritário (licença Company)
- Renovações de manutenção disponíveis após o primeiro ano
A principal diferença é a amplitude do conteúdo educacional do IronPDF (tutoriais, guias práticos e vídeos) junto com chat ao vivo 24/5 e suporte 24/7 com Suporte Premium.
Quais São os Melhores Casos de Uso para Cada Biblioteca?
Quando Escolher o IronPDF
O IronPDF se destaca em cenários que exigem:
1. Integração com Aplicações Web Modernas
- Plataformas SaaS gerando relatórios dinâmicos
- Sites de e-commerce criando faturas com gráficos
- Dashboards de business intelligence exportados como PDFs
- Aplicações usando React, Angular ou Vue.js
2. Documentos com Conteúdo Sensível
- Remoção de dados pessoais de documentos antes de serem compartilhados
- Criptografia e proteção por senha de relatórios gerados
- Assinatura de documentos para que alterações posteriores possam ser detectadas
- Gerenciamento de documentos jurídicos com redação
3. Processamento de Documentos Complexos
- Conversão de documentos em múltiplos formatos (DOCX, HTML, Imagens)
- OCR para documentos digitalizados via IronOCR
- Processamento em lote com execução paralela
- Documentos com assinaturas digitais
4. Implantação Multiplataforma
- Aplicações containerizadas em Docker
- Implantações em nuvem baseadas em Linux
- Arquiteturas de microsserviços
- Funções serverless (AWS Lambda, Azure Functions)
Exemplo: Protegendo um Relatório Gerado
// NuGet: Install-Package IronPdf
using System.Net;
using IronPdf;
using IronPdf.Security;
using IronPdf.Signing;
var patient = new PatientRecord("P-10442", "Jane <Q.> Doe & Family", "123-45-6789", "open-sesame");
// HTML-encode text values, so characters such as & and < print as text instead of changing the markup
var html = $@"
<html>
<body>
<h1>Patient Summary</h1>
<p>Patient ID: {WebUtility.HtmlEncode(patient.PatientId)}</p>
<p>Name: {WebUtility.HtmlEncode(patient.Name)}</p>
<p>SSN: {WebUtility.HtmlEncode(patient.Ssn)}</p>
</body>
</html>";
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(html);
// Remove the SSN from the page content wherever it appears
pdf.RedactTextOnAllPages(patient.Ssn);
// Descriptive document properties
pdf.MetaData.Author = "Records System";
pdf.MetaData.Title = $"Patient Summary {patient.PatientId}";
// Require a password to open the file, restrict copying, and encrypt with AES-256
pdf.SecuritySettings.UserPassword = patient.AccessCode;
pdf.SecuritySettings.OwnerPassword = "records-owner-password";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256;
// Sign last, so changes made to the file after signing can be detected
pdf.Sign(new PdfSignature("records-cert.pfx", "password")
{
SigningReason = "Record export",
SigningLocation = "Records Department"
});
pdf.SaveAs("patient-summary.pdf");
record PatientRecord(string PatientId, string Name, string Ssn, string AccessCode);' NuGet: Install-Package IronPdf
Imports System.Net
Imports IronPdf
Imports IronPdf.Security
Imports IronPdf.Signing
Dim patient = New PatientRecord("P-10442", "Jane <Q.> Doe & Family", "123-45-6789", "open-sesame")
' HTML-encode text values, so characters such as & and < print as text instead of changing the markup
Dim html = $"
<html>
<body>
<h1>Patient Summary</h1>
<p>Patient ID: {WebUtility.HtmlEncode(patient.PatientId)}</p>
<p>Name: {WebUtility.HtmlEncode(patient.Name)}</p>
<p>SSN: {WebUtility.HtmlEncode(patient.Ssn)}</p>
</body>
</html>"
Dim renderer = New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(html)
' Remove the SSN from the page content wherever it appears
pdf.RedactTextOnAllPages(patient.Ssn)
' Descriptive document properties
pdf.MetaData.Author = "Records System"
pdf.MetaData.Title = $"Patient Summary {patient.PatientId}"
' Require a password to open the file, restrict copying, and encrypt with AES-256
pdf.SecuritySettings.UserPassword = patient.AccessCode
pdf.SecuritySettings.OwnerPassword = "records-owner-password"
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256
' Sign last, so changes made to the file after signing can be detected
pdf.Sign(New PdfSignature("records-cert.pfx", "password") With {
.SigningReason = "Record export",
.SigningLocation = "Records Department"
})
pdf.SaveAs("patient-summary.pdf")
End Using
Public Record PatientRecord(PatientId As String, Name As String, Ssn As String, AccessCode As String)Estes são blocos de construção para processamento de documentos. Se uma aplicação atende a uma regulamentação como HIPAA também depende de como ela armazena, transmite e controla o acesso aos dados, o que nenhuma configuração de PDF estabelece por si só.
Quando Escolher o EvoPdf
O EvoPdf é adequado para:
1. Conversão de HTML para PDF
- Relatórios construídos a partir de templates HTML
- HTML, CSS e JavaScript modernos com o EvoPdf Next baseado em Chromium
- Faturas e recibos
- Geração em massa de documentos com templates consistentes
2. Equipes com Orçamento Limitado
- Desenvolvedores ilimitados em uma única licença
- Custo de entrada mais baixo (licença Deployment $450)
- Projetos que não precisam de redação embutida
3. Ambientes de Servidor Específicos
- Aplicações legadas em .NET Framework (EvoPdf Classic suporta .NET Framework 2.0 e superior)
- Licenciamento por servidor para uma única aplicação
- Integração com sistemas legados
4. Conversões em Alto Volume
- Geração de relatórios estáticos
- Sistemas de documentação
- Criação de documentos prontos para impressão
Exemplo do Mundo Real: Sistema de Geração de Faturas
// NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
using System;
using System.Globalization;
using System.IO;
using System.Net;
using EvoPdf;
var invoice = new InvoiceData("INV-2026-0042", new DateTime(2026, 9, 1), "Smith & Sons <Ltd>", 1250.00m);
var converter = new HtmlToPdfConverter
{
// LicenseKey = "<your EvoPdf license key>",
JavaScriptEnabled = false, // not needed for static invoices
ConversionDelay = 0
};
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
converter.PdfDocumentOptions.TopMargin = 30; // points
converter.PdfDocumentOptions.BottomMargin = 30; // points
string template =
"<html><body><h1>Invoice {{InvoiceNumber}}</h1>" +
"<p>Date: {{Date}}</p><p>Customer: {{CustomerName}}</p><p>Total: {{Total}}</p></body></html>";
// HTML-encode text values, so characters such as & and < print as text instead of changing the markup
string html = template
.Replace("{{InvoiceNumber}}", WebUtility.HtmlEncode(invoice.InvoiceNumber))
.Replace("{{Date}}", invoice.Date.ToString("yyyy-MM-dd"))
.Replace("{{CustomerName}}", WebUtility.HtmlEncode(invoice.CustomerName))
.Replace("{{Total}}", invoice.Total.ToString("C", CultureInfo.GetCultureInfo("en-US")));
File.WriteAllBytes($"invoice-{invoice.InvoiceNumber}.pdf", converter.ConvertHtml(html, ""));
record InvoiceData(string InvoiceNumber, DateTime Date, string CustomerName, decimal Total);' NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
Imports System
Imports System.Globalization
Imports System.IO
Imports System.Net
Imports EvoPdf
Dim invoice = New InvoiceData("INV-2026-0042", New DateTime(2026, 9, 1), "Smith & Sons <Ltd>", 1250.00D)
Dim converter = New HtmlToPdfConverter With {
' LicenseKey = "<your EvoPdf license key>",
.JavaScriptEnabled = False, ' not needed for static invoices
.ConversionDelay = 0
}
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
converter.PdfDocumentOptions.TopMargin = 30 ' points
converter.PdfDocumentOptions.BottomMargin = 30 ' points
Dim template As String =
"<html><body><h1>Invoice {{InvoiceNumber}}</h1>" +
"<p>Date: {{Date}}</p><p>Customer: {{CustomerName}}</p><p>Total: {{Total}}</p></body></html>"
' HTML-encode text values, so characters such as & and < print as text instead of changing the markup
Dim html As String = template _
.Replace("{{InvoiceNumber}}", WebUtility.HtmlEncode(invoice.InvoiceNumber)) _
.Replace("{{Date}}", invoice.Date.ToString("yyyy-MM-dd")) _
.Replace("{{CustomerName}}", WebUtility.HtmlEncode(invoice.CustomerName)) _
.Replace("{{Total}}", invoice.Total.ToString("C", CultureInfo.GetCultureInfo("en-US")))
File.WriteAllBytes($"invoice-{invoice.InvoiceNumber}.pdf", converter.ConvertHtml(html, ""))
Public Class InvoiceData
Public Property InvoiceNumber As String
Public Property Date As DateTime
Public Property CustomerName As String
Public Property Total As Decimal
Public Sub New(invoiceNumber As String, [date] As DateTime, customerName As String, total As Decimal)
Me.InvoiceNumber = invoiceNumber
Me.Date = [date]
Me.CustomerName = customerName
Me.Total = total
End Sub
End ClassPadrões de Implementação Avançados e Melhores Práticas
Otimizando a Performance em Produção
Ambas as bibliotecas se beneficiam de configuração e padrões de uso adequados:
Otimização de Performance no IronPDF
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using IronPdf;
using IronPdf.Engines.Chrome;
using IronPdf.Rendering;
// Global engine settings: set once at startup, before the first render
Installation.ChromeGpuMode = ChromeGpuModes.Disabled; // servers usually have no GPU
// Set to false only if the Linux dependencies are already installed in your image
Installation.LinuxAndDockerDependenciesAutoConfig = false;
var service = new PdfService(maxConcurrency: 4);
var pages = Enumerable.Range(1, 8).Select(i => $"<h1>Report {i}</h1>");
byte[][] results = await Task.WhenAll(pages.Select(service.GeneratePdfAsync));
for (int i = 0; i < results.Length; i++)
File.WriteAllBytes($"report-{i + 1}.pdf", results[i]);
Console.WriteLine($"Generated {results.Length} PDFs");
public class PdfService
{
private readonly ChromePdfRenderer _renderer;
private readonly SemaphoreSlim _gate;
public PdfService(int maxConcurrency)
{
// Caps how many renders run at once
_gate = new SemaphoreSlim(maxConcurrency);
_renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
EnableJavaScript = false, // only if the pages need no JavaScript
CssMediaType = PdfCssMediaType.Screen,
Timeout = 30 // seconds
}
};
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
await _gate.WaitAsync();
try
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
finally
{
_gate.Release();
}
}
}Imports System
Imports System.IO
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks
Imports IronPdf
Imports IronPdf.Engines.Chrome
Imports IronPdf.Rendering
' Global engine settings: set once at startup, before the first render
Installation.ChromeGpuMode = ChromeGpuModes.Disabled ' servers usually have no GPU
' Set to false only if the Linux dependencies are already installed in your image
Installation.LinuxAndDockerDependenciesAutoConfig = False
Dim service = New PdfService(MaxConcurrency:=4)
Dim pages = Enumerable.Range(1, 8).Select(Function(i) $"<h1>Report {i}</h1>")
Dim results As Byte()() = Await Task.WhenAll(pages.Select(Function(page) service.GeneratePdfAsync(page)))
For i As Integer = 0 To results.Length - 1
File.WriteAllBytes($"report-{i + 1}.pdf", results(i))
Next
Console.WriteLine($"Generated {results.Length} PDFs")
Public Class PdfService
Private ReadOnly _renderer As ChromePdfRenderer
Private ReadOnly _gate As SemaphoreSlim
Public Sub New(maxConcurrency As Integer)
' Caps how many renders run at once
_gate = New SemaphoreSlim(maxConcurrency)
_renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.EnableJavaScript = False, ' only if the pages need no JavaScript
.CssMediaType = PdfCssMediaType.Screen,
.Timeout = 30 ' seconds
}
}
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Await _gate.WaitAsync()
Try
Using pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Using
Finally
_gate.Release()
End Try
End Function
End ClassPadrões de Performance no EvoPdf
// NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using EvoPdf;
var service = new EvoPdfService(maxConcurrency: 4);
var pages = Enumerable.Range(1, 8).Select(i => $"<h1>Report {i}</h1>");
byte[][] results = await Task.WhenAll(pages.Select(service.GeneratePdfAsync));
for (int i = 0; i < results.Length; i++)
File.WriteAllBytes($"evopdf-report-{i + 1}.pdf", results[i]);
Console.WriteLine($"Generated {results.Length} PDFs");
public class EvoPdfService
{
private readonly SemaphoreSlim _gate;
// Caps how many conversions run at once
public EvoPdfService(int maxConcurrency) => _gate = new SemaphoreSlim(maxConcurrency);
public async Task<byte[]> GeneratePdfAsync(string html)
{
await _gate.WaitAsync();
try
{
// A new converter for each conversion, as EVO documents for parallel conversions
var converter = new HtmlToPdfConverter
{
// LicenseKey = "<your EvoPdf license key>",
JavaScriptEnabled = false,
ConversionDelay = 0
};
// The Classic API is synchronous, so run it on a thread-pool thread
return await Task.Run(() => converter.ConvertHtml(html, ""));
}
finally
{
_gate.Release();
}
}
}Imports System
Imports System.IO
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks
Imports EvoPdf
Dim service = New EvoPdfService(maxConcurrency:=4)
Dim pages = Enumerable.Range(1, 8).[Select](Function(i) $"<h1>Report {i}</h1>")
Dim results As Byte()() = Await Task.WhenAll(pages.[Select](Function(page) service.GeneratePdfAsync(page)))
For i As Integer = 0 To results.Length - 1
File.WriteAllBytes($"evopdf-report-{i + 1}.pdf", results(i))
Next
Console.WriteLine($"Generated {results.Length} PDFs")
Public Class EvoPdfService
Private ReadOnly _gate As SemaphoreSlim
' Caps how many conversions run at once
Public Sub New(maxConcurrency As Integer)
_gate = New SemaphoreSlim(maxConcurrency)
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Await _gate.WaitAsync()
Try
' A new converter for each conversion, as EVO documents for parallel conversions
Dim converter = New HtmlToPdfConverter With {
' LicenseKey = "<your EvoPdf license key>",
.JavaScriptEnabled = False,
.ConversionDelay = 0
}
' The Classic API is synchronous, so run it on a thread-pool thread
Return Await Task.Run(Function() converter.ConvertHtml(html, ""))
Finally
_gate.Release()
End Try
End Function
End ClassO semáforo é o que limita a concorrência em ambos os exemplos. No EvoPdf Next, GlobalSettings.MaxParallelConversions define o mesmo tipo de limite dentro da biblioteca, e o renderizador persistente mantém o processo do engine de renderização rodando entre as conversões.
Tratamento de Erros e Depuração
Código de produção precisa lidar com falhas de renderização, como uma página que não pode ser carregada:
Tratamento de Erros no IronPDF
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using System.Threading.Tasks;
using IronPdf;
using IronPdf.Exceptions;
// Write IronPDF's own diagnostics to a log file
IronPdf.Logging.Logger.LogFilePath = "ironpdf.log";
IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.Timeout = 60; // seconds
byte[] page = await TryRenderUrlAsync(renderer, "https://example.com/");
if (page != null)
{
File.WriteAllBytes("example.pdf", page);
Console.WriteLine($"Rendered {page.Length} bytes");
}
// A host that does not resolve makes the render throw, which exercises the error path
byte[] missing = await TryRenderUrlAsync(renderer, "https://nonexistent.invalid/");
Console.WriteLine(missing == null ? "Second render failed and was handled" : "Second render succeeded");
// Returns the PDF bytes, or null if the page could not be rendered
static async Task<byte[]> TryRenderUrlAsync(ChromePdfRenderer renderer, string url)
{
try
{
using var pdf = await renderer.RenderUrlAsPdfAsync(url);
if (pdf.PageCount == 0)
{
Console.Error.WriteLine($"No pages rendered for {url}");
return null;
}
return pdf.BinaryData;
}
catch (IronPdfNativeException ex)
{
// Raised by the rendering engine, for example when the page cannot be loaded
Console.Error.WriteLine($"Rendering failed for {url}: {ex.Message}");
return null;
}
}' NuGet: Install-Package IronPdf
Imports System
Imports System.IO
Imports System.Threading.Tasks
Imports IronPdf
Imports IronPdf.Exceptions
' Write IronPDF's own diagnostics to a log file
IronPdf.Logging.Logger.LogFilePath = "ironpdf.log"
IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.Timeout = 60 ' seconds
Dim page As Byte() = Await TryRenderUrlAsync(renderer, "https://example.com/")
If page IsNot Nothing Then
File.WriteAllBytes("example.pdf", page)
Console.WriteLine($"Rendered {page.Length} bytes")
End If
' A host that does not resolve makes the render throw, which exercises the error path
Dim missing As Byte() = Await TryRenderUrlAsync(renderer, "https://nonexistent.invalid/")
Console.WriteLine(If(missing Is Nothing, "Second render failed and was handled", "Second render succeeded"))
' Returns the PDF bytes, or null if the page could not be rendered
Private Shared Async Function TryRenderUrlAsync(renderer As ChromePdfRenderer, url As String) As Task(Of Byte())
Try
Using pdf = Await renderer.RenderUrlAsPdfAsync(url)
If pdf.PageCount = 0 Then
Console.Error.WriteLine($"No pages rendered for {url}")
Return Nothing
End If
Return pdf.BinaryData
End Using
Catch ex As IronPdfNativeException
' Raised by the rendering engine, for example when the page cannot be loaded
Console.Error.WriteLine($"Rendering failed for {url}: {ex.Message}")
Return Nothing
End Try
End FunctionExemplos de Implementação por Setor
Relatórios Financeiros: Extratos Assinados e Somente Leitura
Um extrato que não deve ser alterado após a aprovação pode combinar marca d'água, permissões restritas e assinatura:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Editing;
using IronPdf.Security;
using IronPdf.Signing;
using IronSoftware.Drawing;
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(
"<h1>Quarterly Statement: Q3 2026</h1>" +
"<table><tr><td>Revenue</td><td>1,250,000</td></tr><tr><td>Expenses</td><td>980,000</td></tr></table>");
// Mark the document as a draft
pdf.ApplyWatermark(@"
<div style='color: rgba(0,0,0,0.1); font-size: 120px; transform: rotate(-45deg); font-family: Arial;'>
DRAFT
</div>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center);
// Descriptive document properties: useful for search and filing, not a record of who changed what
pdf.MetaData.Author = "Financial Reporting System";
pdf.MetaData.Keywords = "Quarterly Statement, Q3 2026";
pdf.MetaData.CustomProperties.Add("ReportPeriod", "2026-Q3");
pdf.MetaData.CustomProperties.Add("GeneratedAt", DateTime.UtcNow.ToString("O"));
// Restrict editing; the owner password is needed to change these permissions
pdf.SecuritySettings.OwnerPassword = "finance-owner-password";
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SecuritySettings.AllowUserCopyPasteContent = true;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256;
// Sign last: readers can then detect changes made after signing
pdf.Sign(new PdfSignature("financial-cert.pfx", "password")
{
SigningReason = "Statement approval",
SigningLocation = "Finance Department",
// Visible signature image on the first page
SignatureImage = new PdfSignatureImage("cfo-signature.png", 0, new Rectangle(50, 50, 200, 60))
});
pdf.SaveAs("quarterly-statement.pdf");' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Imports IronPdf.Editing
Imports IronPdf.Security
Imports IronPdf.Signing
Imports IronSoftware.Drawing
Dim renderer = New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(
"<h1>Quarterly Statement: Q3 2026</h1>" &
"<table><tr><td>Revenue</td><td>1,250,000</td></tr><tr><td>Expenses</td><td>980,000</td></tr></table>")
' Mark the document as a draft
pdf.ApplyWatermark("
<div style='color: rgba(0,0,0,0.1); font-size: 120px; transform: rotate(-45deg); font-family: Arial;'>
DRAFT
</div>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center)
' Descriptive document properties: useful for search and filing, not a record of who changed what
pdf.MetaData.Author = "Financial Reporting System"
pdf.MetaData.Keywords = "Quarterly Statement, Q3 2026"
pdf.MetaData.CustomProperties.Add("ReportPeriod", "2026-Q3")
pdf.MetaData.CustomProperties.Add("GeneratedAt", DateTime.UtcNow.ToString("O"))
' Restrict editing; the owner password is needed to change these permissions
pdf.SecuritySettings.OwnerPassword = "finance-owner-password"
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SecuritySettings.AllowUserCopyPasteContent = True
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256
' Sign last: readers can then detect changes made after signing
pdf.Sign(New PdfSignature("financial-cert.pfx", "password") With {
.SigningReason = "Statement approval",
.SigningLocation = "Finance Department",
' Visible signature image on the first page
.SignatureImage = New PdfSignatureImage("cfo-signature.png", 0, New Rectangle(50, 50, 200, 60))
})
pdf.SaveAs("quarterly-statement.pdf")
End UsingA assinatura torna alterações posteriores detectáveis e as permissões desencorajam a edição; nenhuma delas, sozinha, é um controle de conformidade ou trilha de auditoria de quem fez o quê.
E-Commerce: Geração Dinâmica de Faturas
Plataformas de e-commerce precisam de geração de faturas rápida e confiável:
// NuGet: Install-Package IronPdf
using System;
using System.Globalization;
using System.Linq;
using System.Net;
using IronPdf;
using IronPdf.Rendering;
var order = new Order("INV-1001", new DateTime(2026, 9, 1), new[]
{
new OrderItem("Widget <Deluxe> & Co. edition", 2, 19.99m),
new OrderItem("Gift wrap", 1, 4.50m)
});
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
MarginTop = 10, // millimetres
MarginBottom = 10,
PaperSize = PdfPaperSize.A4
}
};
var usd = CultureInfo.GetCultureInfo("en-US");
// HTML-encode text values, so characters such as & and < print as text instead of changing the markup
string rows = string.Concat(order.Items.Select(item => $@"
<tr>
<td>{WebUtility.HtmlEncode(item.Name)}</td>
<td>{item.Quantity}</td>
<td>{item.Price.ToString("C", usd)}</td>
<td>{item.Total.ToString("C", usd)}</td>
</tr>"));
var html = $@"
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; }}
.invoice-header {{ background: #f0f0f0; padding: 20px; }}
table {{ width: 100%; border-collapse: collapse; }}
th, td {{ padding: 10px; border-bottom: 1px solid #ddd; text-align: left; }}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{WebUtility.HtmlEncode(order.InvoiceNumber)}</h1>
<p>Date: {order.Date:yyyy-MM-dd}</p>
</div>
<table>
<tr><th>Item</th><th>Quantity</th><th>Price</th><th>Total</th></tr>
{rows}
<tr><td colspan='3'><strong>Total</strong></td><td><strong>{order.Total.ToString("C", usd)}</strong></td></tr>
</table>
<p>Thank you for your business!</p>
</body>
</html>";
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
pdf.SaveAs($"invoice-{order.InvoiceNumber}.pdf");
record OrderItem(string Name, int Quantity, decimal Price)
{
public decimal Total => Price * Quantity;
}
record Order(string InvoiceNumber, DateTime Date, OrderItem[] Items)
{
public decimal Total => Items.Sum(item => item.Total);
}' NuGet: Install-Package IronPdf
Imports System
Imports System.Globalization
Imports System.Linq
Imports System.Net
Imports IronPdf
Imports IronPdf.Rendering
Dim order = New Order("INV-1001", New DateTime(2026, 9, 1), {
New OrderItem("Widget <Deluxe> & Co. edition", 2, 19.99D),
New OrderItem("Gift wrap", 1, 4.5D)
})
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.MarginTop = 10, ' millimetres
.MarginBottom = 10,
.PaperSize = PdfPaperSize.A4
}
}
Dim usd = CultureInfo.GetCultureInfo("en-US")
' HTML-encode text values, so characters such as & and < print as text instead of changing the markup
Dim rows As String = String.Concat(order.Items.Select(Function(item) $"
<tr>
<td>{WebUtility.HtmlEncode(item.Name)}</td>
<td>{item.Quantity}</td>
<td>{item.Price.ToString("C", usd)}</td>
<td>{item.Total.ToString("C", usd)}</td>
</tr>"))
Dim html = $"
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; }}
.invoice-header {{ background: #f0f0f0; padding: 20px; }}
table {{ width: 100%; border-collapse: collapse; }}
th, td {{ padding: 10px; border-bottom: 1px solid #ddd; text-align: left; }}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{WebUtility.HtmlEncode(order.InvoiceNumber)}</h1>
<p>Date: {order.Date:yyyy-MM-dd}</p>
</div>
<table>
<tr><th>Item</th><th>Quantity</th><th>Price</th><th>Total</th></tr>
{rows}
<tr><td colspan='3'><strong>Total</strong></td><td><strong>{order.Total.ToString("C", usd)}</strong></td></tr>
</table>
<p>Thank you for your business!</p>
</body>
</html>"
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
pdf.SaveAs($"invoice-{order.InvoiceNumber}.pdf")
End Using
Public Record OrderItem(Name As String, Quantity As Integer, Price As Decimal)
Public ReadOnly Property Total As Decimal
Get
Return Price * Quantity
End Get
End Property
End Record
Public Record Order(InvoiceNumber As String, [Date] As DateTime, Items As OrderItem())
Public ReadOnly Property Total As Decimal
Get
Return Items.Sum(Function(item) item.Total)
End Get
End Property
End RecordEstratégias de Migração: Mudando Entre Bibliotecas
Se você está considerando trocar de biblioteca, aqui está uma abordagem de migração:
Migrando do EvoPdf para o IronPDF
// NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
// NuGet: Install-Package IronPdf
using System.IO;
using EvoPdf;
using IronPdf;
using IronPdf.Rendering;
string url = "https://example.com/";
// EvoPdf pattern
HtmlToPdfConverter evoPdfConverter = new HtmlToPdfConverter();
evoPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
File.WriteAllBytes("evopdf.pdf", evoPdfConverter.ConvertUrl(url));
// Equivalent IronPDF pattern
var ironPdfRenderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
PaperSize = PdfPaperSize.A4
}
};
using (var pdf = ironPdfRenderer.RenderUrlAsPdf(url))
{
File.WriteAllBytes("ironpdf.pdf", pdf.BinaryData);
}
// During a gradual migration, both libraries can sit behind one interface
IPdfConverter converter = new IronPdfAdapter();
File.WriteAllBytes("adapter.pdf", converter.ConvertUrlToPdf(url));
public interface IPdfConverter
{
byte[] ConvertHtmlToPdf(string html);
byte[] ConvertUrlToPdf(string url);
}
public class IronPdfAdapter : IPdfConverter
{
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] ConvertHtmlToPdf(string html)
{
using var pdf = _renderer.RenderHtmlAsPdf(html);
return pdf.BinaryData;
}
public byte[] ConvertUrlToPdf(string url)
{
using var pdf = _renderer.RenderUrlAsPdf(url);
return pdf.BinaryData;
}
}
public class EvoPdfAdapter : IPdfConverter
{
private readonly HtmlToPdfConverter _converter = new HtmlToPdfConverter();
public byte[] ConvertHtmlToPdf(string html)
{
return _converter.ConvertHtml(html, "");
}
public byte[] ConvertUrlToPdf(string url)
{
return _converter.ConvertUrl(url);
}
}Imports System.IO
Imports EvoPdf
Imports IronPdf
Imports IronPdf.Rendering
Dim url As String = "https://example.com/"
' EvoPdf pattern
Dim evoPdfConverter As New HtmlToPdfConverter()
evoPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
File.WriteAllBytes("evopdf.pdf", evoPdfConverter.ConvertUrl(url))
' Equivalent IronPDF pattern
Dim ironPdfRenderer As New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.PaperSize = PdfPaperSize.A4
}
}
Using pdf = ironPdfRenderer.RenderUrlAsPdf(url)
File.WriteAllBytes("ironpdf.pdf", pdf.BinaryData)
End Using
' During a gradual migration, both libraries can sit behind one interface
Dim converter As IPdfConverter = New IronPdfAdapter()
File.WriteAllBytes("adapter.pdf", converter.ConvertUrlToPdf(url))
Public Interface IPdfConverter
Function ConvertHtmlToPdf(html As String) As Byte()
Function ConvertUrlToPdf(url As String) As Byte()
End Interface
Public Class IronPdfAdapter
Implements IPdfConverter
Private ReadOnly _renderer As New ChromePdfRenderer()
Public Function ConvertHtmlToPdf(html As String) As Byte() Implements IPdfConverter.ConvertHtmlToPdf
Using pdf = _renderer.RenderHtmlAsPdf(html)
Return pdf.BinaryData
End Using
End Function
Public Function ConvertUrlToPdf(url As String) As Byte() Implements IPdfConverter.ConvertUrlToPdf
Using pdf = _renderer.RenderUrlAsPdf(url)
Return pdf.BinaryData
End Using
End Function
End Class
Public Class EvoPdfAdapter
Implements IPdfConverter
Private ReadOnly _converter As New HtmlToPdfConverter()
Public Function ConvertHtmlToPdf(html As String) As Byte() Implements IPdfConverter.ConvertHtmlToPdf
Return _converter.ConvertHtml(html, "")
End Function
Public Function ConvertUrlToPdf(url As String) As Byte() Implements IPdfConverter.ConvertUrlToPdf
Return _converter.ConvertUrl(url)
End Function
End ClassConclusão: Fazendo a Escolha Certa para Seu Projeto
Tanto o IronPDF quanto o EvoPdf desempenham papéis importantes no ecossistema de bibliotecas PDF para .NET, mas eles atendem a diferentes casos de uso e filosofias de desenvolvimento.
Escolha o IronPDF quando você precisar de:
- Suporte a padrões web modernos (CSS3, frameworks JavaScript)
- Manipulação de PDF além da geração, como mesclagem, formulários, redação e assinatura
- Recursos de segurança como criptografia, assinaturas e redação
- Flexibilidade de implantação multiplataforma
- Documentação extensa e suporte direto de engenharia
- Integração com outras ferramentas de processamento de documentos
Escolha o EvoPdf quando você precisar de:
- Conversão de HTML para PDF com menor custo de licença
- Licenciamento por aplicação (Deployment) ou por empresa (Company), com redistribuição em seus próprios aplicativos incluída na licença Company
- Licenças que não contam desenvolvedores
- Escolha entre um engine baseado em Chromium (EvoPdf Next) e um engine Windows que suporta .NET Framework 2.0 e superior (EvoPdf Classic)
A decisão depende, em última análise, dos seus requisitos específicos, restrições orçamentárias e necessidades de escalabilidade a longo prazo. Para aplicações modernas que precisam de manipulação de PDF além da geração, como redação embutida e conversão DOCX, o conjunto de recursos e a documentação do IronPDF fazem dele um forte investimento. O EvoPdf também é uma opção viável, especialmente para equipes que valorizam seu licenciamento por empresa e redistribuição incluída.
Considere começar com o teste gratuito de 30 dias do IronPDF para avaliar suas capacidades no seu caso de uso específico. O trial oferece acesso aos recursos do IronPDF, permitindo que você tome uma decisão informada com base no desempenho real em seu ambiente.
Lembre-se de que o verdadeiro custo de uma biblioteca PDF vai além do preço da licença – leve em conta o tempo de desenvolvimento, o custo de manutenção e a possível necessidade de recursos adicionais à medida que sua aplicação cresce. Escolha a biblioteca que não só atenda às suas necessidades atuais, mas que possa escalar conforme seus requisitos futuros.

Jacob Mellor é Diretor de Tecnologia da Iron Software e um engenheiro visionário pioneiro na tecnologia C# PDF. Como desenvolvedor original do código-fonte principal da Iron Software, ele moldou a arquitetura de produtos da empresa desde sua criação, transformando-a, juntamente com o CEO Cameron Rimington, em uma empresa com mais de 50 funcionários que atende à NASA, Tesla e agências governamentais globais.
Artigos relacionados

