Ir para o conteúdo do rodapé
FERRAMENTAS DE PDF

Descubra o melhor software de redação de PDFs para 2025

Escolher uma biblioteca C# para converter HTML em PDF em 2026 se resume a uma decisão: qual mecanismo de renderização se adapta aos documentos que você realmente produz. Não .NET 10, o campo se divide em três grupos. Motores baseados em navegador (Chromium através de PuppeteerSharp, Dramaturgo ou uma compilação incorporada) renderizam CSS eJavaScriptmodernos com precisão. Bibliotecas programáticas (iText, PdfSharp) desenham PDFs a partir de analisadores personalizados e trocam a fidelidade da web moderna por uma pegada pequena. Ferramentas de layout baseadas em código (QuestPDF) ignoram completamente o HTML. Esta comparação passa por cada opção com código C# funcionando, uma rubrica de avaliação, benchmarks originais e os termos de licença que decidem o que você pode distribuir.

Em resumo: a resposta rápida e o código que funciona mais rápido

Para renderizar CSS eJavaScriptatuais com precisão, use um mecanismo de nível de navegador. A rota gratuita é o PuppeteerSharp ou o Playwright, que entregam saída ao nível do Chrome, mas fazem você gerenciar um processo de navegador separado e um binário grande. A rota comercial incorpora o Chromium no pacote, não deixando nada separado para instalar ou iniciar. Para documentos estáticos simples, uma biblioteca leve como o PdfSharp é suficiente. Para layouts definidos por código sem fonte HTML, oQuestPDFé o caminho mais curto.

O caminho mais rápido para um PDF usando um mecanismo incorporado é uma única chamada de renderização:

using IronPdf;

// The embedded Chromium engine ships inside the package, so no browser is launched or downloaded
var renderer = new ChromePdfRenderer();
// One synchronous call parses the HTML string and produces an in-memory PDF document
var pdf = renderer.RenderHtmlAsPdf("<h1>Invoice</h1><p>Generated from HTML.</p>");
// Write the rendered document to disk
pdf.SaveAs("output.pdf");
using IronPdf;

// The embedded Chromium engine ships inside the package, so no browser is launched or downloaded
var renderer = new ChromePdfRenderer();
// One synchronous call parses the HTML string and produces an in-memory PDF document
var pdf = renderer.RenderHtmlAsPdf("<h1>Invoice</h1><p>Generated from HTML.</p>");
// Write the rendered document to disk
pdf.SaveAs("output.pdf");
Imports IronPdf

' The embedded Chromium engine ships inside the package, so no browser is launched or downloaded
Dim renderer As New ChromePdfRenderer()
' One synchronous call parses the HTML string and produces an in-memory PDF document
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Invoice</h1><p>Generated from HTML.</p>")
' Write the rendered document to disk
pdf.SaveAs("output.pdf")
$vbLabelText   $csharpLabel

A comparação completa, benchmarks e detalhes de licença seguem abaixo.

Tabela de recomendação rápida por cenário

Combine sua restrição com uma escolha antes de ler o mergulho profundo.

Se você precisar Escolha recomendada Por quê
CSS moderno, Flexbox, Grid, fontes da web em escala IronPDF (Chromium incorporado) Renderização precisa, renderizações rápidas, nenhum navegador externo para implantar
Renderização de nível de navegador gratuita, disposto a gerenciar operações PuppeteerSharp ou Playwright Chromium real, licença MIT, pegada de implantação mais pesada
HTML estático simples, sem JavaScript PdfSharp com HtmlRenderer Leve, gratuito, limitado ao CSS legado
Layouts fixos programáticos, sem fonte HTML QuestPDF API C# fluente, muito rápido, não é um renderizador HTML
Zero infraestrutura, processamento hospedado Uma API de HTML para PDF Nenhum mecanismo de renderização para manter em seu aplicativo
Projeto legado em wkhtmltopdf Migre para um mecanismo Chromium wkhtmltopdf está arquivado, falha no CSS atual e carrega uma CVE SSRF crítica

O que torna difícil converter HTML para PDF em C

Navegadores renderizam conteúdo fluido para telas; O PDF exige páginas fixas, dimensões exatas e paginação rigorosa. A lacuna entre esses dois modelos é onde as bibliotecas têm sucesso ou falham. Cinco critérios os separam, e eles se aplicam a todas as ferramentas, independentemente do fornecedor.

  1. Mecanismo de renderização e CSS moderno: o mecanismo que analisa HTML e CSS é o principal diferencial. Os modelos atuais dependem do CSS Flexbox para alinhamento, CSS Grid para layout bidimensional, @font-face para tipografia e SVG para ativos vetoriais. Motores baseados em forks antigos do WebKit ou analisadores personalizados tendem a falhar silenciosamente nisso e colapsar layouts estilizados em uma pilha vertical. O manuseio correto das regras @media print importa tanto quanto na conversão de um layout de tela para papel.

  2. Execução deJavaScripte esperas de renderização: muito do conteúdo de hoje é construído no lado do cliente. Bibliotecas de gráficos como Chart.js e frameworks de página única como Blazor WebAssembly constroem o DOM comJavaScriptantes que a página esteja completa. Uma biblioteca sem um mecanismo deJavaScriptproduz gráficos em branco ou páginas parcialmente carregadas, o que torna a capacidade de executar scripts e esperar por um sinal de prontidão para renderização decisiva para documentos dinâmicos.

  3. Peso de implantação e início a frio: ferramentas que dirigem um navegador headless externo fazem o download de centenas de megabytes de binários, inflando imagens de contêiner e retardando inícios a frio. Em ambientes sem servidor como AWS Lambda ou Azure Functions, onde armazenamento e memória são limitados, o peso do contêiner pode decidir se uma biblioteca é viável.

  4. Licença e seu alcance legal: uma licença dita mais do que o custo. O campo de PDF do .NET abrange termos permissivos (MIT, Apache 2.0), termos copyleft (AGPLv3) que podem exigir a divulgação do seu código-fonte para aplicativos voltados para rede, níveis de comunidade limitados por receita e licenças comerciais perpétuas. A escolha errada pode criar uma obrigação que surge apenas na hora da auditoria.

  5. Desempenho e memória em escala: uma biblioteca que é boa em um teste de console pode travar em uma API web concorrente. Algumas transmitem o trabalho; outras carregam todo o documento na memória de uma vez e acionam pausas de coleta de lixo durante trabalhos em lote. Início a frio, renderização rápida e memória por renderização são três medições separadas que precisam de atenção.

As bibliotecas, cada uma com código de trabalho

As opções gratuitas e de código aberto vêm primeiro. Cada trecho abaixo foi compilado e executado no .NET 10, e os motores Chromium mostram tanto a entrada de string HTML quanto a URL, já que oferecem suporte a ambos.

PuppeteerSharp

PuppeteerSharp é uma porta .NET do Puppeteer Node.js do Google, lançado pela primeira vez em 2017. Ele dirige uma instância headless do Chromium sobre o Protocolo de Ferramentas de Desenvolvimento do Chrome. É um orquestrador de processos em vez de uma biblioteca em processo: o aplicativo faz o download de uma compilação do Chromium com BrowserFetcher, inicia o navegador, define o conteúdo da página e captura o PDF.

using PuppeteerSharp;
using System.Threading.Tasks;

public class PuppeteerExample
{
    public async Task GeneratePdfAsync()
    {
        // Download a matching Chromium build if it is not already present (the 100-300 MB fetch)
        await new BrowserFetcher().DownloadAsync();

        // Start a headless browser process; await using disposes it to avoid orphaned processes
        await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
        // Open a fresh tab to work in
        await using var page = await browser.NewPageAsync();

        // Load the HTML directly into the page instead of navigating to a URL
        await page.SetContentAsync("<h1>Invoice Report</h1><p>Rendered with PuppeteerSharp.</p>");
        // Drive Chrome's print pipeline to emit the PDF file
        await page.PdfAsync("puppeteer_output.pdf");
    }
}
using PuppeteerSharp;
using System.Threading.Tasks;

public class PuppeteerExample
{
    public async Task GeneratePdfAsync()
    {
        // Download a matching Chromium build if it is not already present (the 100-300 MB fetch)
        await new BrowserFetcher().DownloadAsync();

        // Start a headless browser process; await using disposes it to avoid orphaned processes
        await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });
        // Open a fresh tab to work in
        await using var page = await browser.NewPageAsync();

        // Load the HTML directly into the page instead of navigating to a URL
        await page.SetContentAsync("<h1>Invoice Report</h1><p>Rendered with PuppeteerSharp.</p>");
        // Drive Chrome's print pipeline to emit the PDF file
        await page.PdfAsync("puppeteer_output.pdf");
    }
}
Imports PuppeteerSharp
Imports System.Threading.Tasks

Public Class PuppeteerExample
    Public Async Function GeneratePdfAsync() As Task
        ' Download a matching Chromium build if it is not already present (the 100-300 MB fetch)
        Await New BrowserFetcher().DownloadAsync()

        ' Start a headless browser process; using disposes it to avoid orphaned processes
        Using browser = Await Puppeteer.LaunchAsync(New LaunchOptions With {.Headless = True})
            ' Open a fresh tab to work in
            Using page = Await browser.NewPageAsync()
                ' Load the HTML directly into the page instead of navigating to a URL
                Await page.SetContentAsync("<h1>Invoice Report</h1><p>Rendered with PuppeteerSharp.</p>")
                ' Drive Chrome's print pipeline to emit the PDF file
                Await page.PdfAsync("puppeteer_output.pdf")
            End Using
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

Para capturar uma URL ao vivo em vez de uma string, navegue até ela antes da chamada:

// Navigate the tab to a live URL so the loaded page becomes the render source
await page.GoToAsync("https://example.com");
// Capture whatever is currently displayed as a PDF
await page.PdfAsync("from_url.pdf");
// Navigate the tab to a live URL so the loaded page becomes the render source
await page.GoToAsync("https://example.com");
// Capture whatever is currently displayed as a PDF
await page.PdfAsync("from_url.pdf");
Imports System.Threading.Tasks

' Navigate the tab to a live URL so the loaded page becomes the render source
Await page.GoToAsync("https://example.com")
' Capture whatever is currently displayed as a PDF
Await page.PdfAsync("from_url.pdf")
$vbLabelText   $csharpLabel

Pontos fortes:

  • A renderização corresponde ao Google Chrome, com suporte completo a Flexbox, Grid e fontes da web.
  • ExecutaJavaScripte pode esperar até que a rede esteja ociosa antes de capturar.
  • Licenciado sob MIT, portanto, o uso comercial não acarreta obrigação copyleft.

Limitações:

  • Uma primeira execução faz o download de uma compilação do Chromium de 100 MB a 300 MB.
  • Cada instância do navegador consome memória significativa, então lotes simultâneos precisam de um pool de navegadores.
  • Sem saída integrada em PDF/A ou PDF/UA.

License: MIT. Procure por ele quando você quiser uma saída de fidelidade de Chrome gratuita e a equipe puder absorver a sobrecarga de operações. Para um comparativo focado sobre essa troca, veja a comparação entre PuppeteerSharp e IronPDF.

Dramaturgo for .NET

Playwright é mantido pela Microsoft como um framework de automação cross-browser para Chromium, WebKit e Firefox. As equipes o reutilizam para HTML para PDF através de Page.PdfAsync, embora a geração de PDF funcione apenas com o Chromium. A configuração busca binários de navegador por meio de uma etapa de instalação única.

using Microsoft.Playwright;
using System.Threading.Tasks;

public class PlaywrightExample
{
    public async Task GeneratePdfAsync()
    {
        // Create the Dramaturgo driver that manages the installed browser binaries
        using var playwright = await Playwright.CreateAsync();
        // PDF output is Chromium-only, so launch the Chromium build specifically
        await using var browser = await playwright.Chromium.LaunchAsync();
        // Open a new page (tab) to render into
        var page = await browser.NewPageAsync();

        // Set the HTML content in place rather than navigating to a URL
        await page.SetContentAsync("<html><body><h1>Sales Dashboard</h1></body></html>");
        // Emit the PDF with an explicit A4 page format
        await page.PdfAsync(new PagePdfOptions { Path = "playwright_output.pdf", Format = "A4" });
    }
}
using Microsoft.Playwright;
using System.Threading.Tasks;

public class PlaywrightExample
{
    public async Task GeneratePdfAsync()
    {
        // Create the Dramaturgo driver that manages the installed browser binaries
        using var playwright = await Playwright.CreateAsync();
        // PDF output is Chromium-only, so launch the Chromium build specifically
        await using var browser = await playwright.Chromium.LaunchAsync();
        // Open a new page (tab) to render into
        var page = await browser.NewPageAsync();

        // Set the HTML content in place rather than navigating to a URL
        await page.SetContentAsync("<html><body><h1>Sales Dashboard</h1></body></html>");
        // Emit the PDF with an explicit A4 page format
        await page.PdfAsync(new PagePdfOptions { Path = "playwright_output.pdf", Format = "A4" });
    }
}
Imports Microsoft.Playwright
Imports System.Threading.Tasks

Public Class PlaywrightExample
    Public Async Function GeneratePdfAsync() As Task
        ' Create the Dramaturgo driver that manages the installed browser binaries
        Using playwright = Await Playwright.CreateAsync()
            ' PDF output is Chromium-only, so launch the Chromium build specifically
            Await Using browser = Await playwright.Chromium.LaunchAsync()
                ' Open a new page (tab) to render into
                Dim page = Await browser.NewPageAsync()

                ' Set the HTML content in place rather than navigating to a URL
                Await page.SetContentAsync("<html><body><h1>Sales Dashboard</h1></body></html>")
                ' Emit the PDF with an explicit A4 page format
                Await page.PdfAsync(New PagePdfOptions With {.Path = "playwright_output.pdf", .Format = "A4"})
            End Using
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

Antes da primeira execução, instale o navegador com pwsh bin/Debug/net10.0/playwright.ps1 install chromium (ou chame o ponto de entrada de instalação equivalente no código).

Para uma URL ao vivo, navegue até a página primeiro:

// Load a live URL so its rendered DOM becomes the PDF source
await page.GotoAsync("https://example.com");
// Export the loaded page as an A4 PDF
await page.PdfAsync(new PagePdfOptions { Path = "from_url.pdf", Format = "A4" });
// Load a live URL so its rendered DOM becomes the PDF source
await page.GotoAsync("https://example.com");
// Export the loaded page as an A4 PDF
await page.PdfAsync(new PagePdfOptions { Path = "from_url.pdf", Format = "A4" });
Imports System.Threading.Tasks

' Load a live URL so its rendered DOM becomes the PDF source
Await page.GotoAsync("https://example.com")
' Export the loaded page as an A4 PDF
Await page.PdfAsync(New PagePdfOptions With {.Path = "from_url.pdf", .Format = "A4"})
$vbLabelText   $csharpLabel

Onde brilha:

  • Apoiado pela Microsoft com um ciclo de lançamentos ativo.
  • Baixa latência de primeiro renderização uma vez que o navegador está ativo.
  • Renderiza padrões modernos da web eJavaScriptdo lado do cliente com precisão.

O problema:

  • Mesmo peso pesado de binário e gerenciamento de navegador como o PuppeteerSharp.
  • A memória aumenta sem manuseio cuidadoso do contexto do navegador.
  • A saída de PDF é um recurso secundário do pipeline de impressão do Chrome, por isso carece de recursos de manipulação de documentos.

License: MIT. Ideal quando um projeto já está executando o Dramaturgo para testes e deseja renderização gratuita junto a ele.

wkhtmltopdf (via DinkToPdf)

Por mais de uma década, o wkhtmltopdf foi a ferramenta padrão para converter HTML em PDF. Não .NET, geralmente é consumido através do DinkToPdf, um wrapper C# sobre a biblioteca nativa libwkhtmltox. A API do wrapper é limpa, mas o motor subjacente é o problema.

using DinkToPdf;

public class DinkToPdfExample
{
    public void GeneratePdf()
    {
        // SynchronizedConverter serializes calls into the non-thread-safe native libwkhtmltox library
        var converter = new SynchronizedConverter(new PdfTools());

        // Describe the document: global page settings plus one or more HTML content objects
        var doc = new HtmlToPdfDocument
        {
            // Set the paper size and the output file path for the whole document
            GlobalSettings = { PaperSize = PaperKind.A4, Out = "legacy_output.pdf" },
            // Each object is a chunk of HTML to render into the PDF
            Objects = { new ObjectSettings { HtmlContent = "<h1>Legacy Report</h1>" } }
        };

        // Hand the descriptor to the native engine, which writes the file defined in Out
        converter.Convert(doc);
    }
}
using DinkToPdf;

public class DinkToPdfExample
{
    public void GeneratePdf()
    {
        // SynchronizedConverter serializes calls into the non-thread-safe native libwkhtmltox library
        var converter = new SynchronizedConverter(new PdfTools());

        // Describe the document: global page settings plus one or more HTML content objects
        var doc = new HtmlToPdfDocument
        {
            // Set the paper size and the output file path for the whole document
            GlobalSettings = { PaperSize = PaperKind.A4, Out = "legacy_output.pdf" },
            // Each object is a chunk of HTML to render into the PDF
            Objects = { new ObjectSettings { HtmlContent = "<h1>Legacy Report</h1>" } }
        };

        // Hand the descriptor to the native engine, which writes the file defined in Out
        converter.Convert(doc);
    }
}
Imports DinkToPdf

Public Class DinkToPdfExample
    Public Sub GeneratePdf()
        ' SynchronizedConverter serializes calls into the non-thread-safe native libwkhtmltox library
        Dim converter = New SynchronizedConverter(New PdfTools())

        ' Describe the document: global page settings plus one or more HTML content objects
        Dim doc = New HtmlToPdfDocument With {
            ' Set the paper size and the output file path for the whole document
            .GlobalSettings = New GlobalSettings With {.PaperSize = PaperKind.A4, .Out = "legacy_output.pdf"},
            ' Each object is a chunk of HTML to render into the PDF
            .Objects = {New ObjectSettings With {.HtmlContent = "<h1>Legacy Report</h1>"}}
        }

        ' Hand the descriptor to the native engine, which writes the file defined in Out
        converter.Convert(doc)
    End Sub
End Class
$vbLabelText   $csharpLabel

Este código compila, mas executá-lo em uma máquina limpa lança System.DllNotFoundException: Unable to load DLL 'libwkhtmltox' até que os binários nativos sejam copiados para o diretório de saída. Esse passo de dependência nativa é o primeiro sinal do atrito de implantação que esse mecanismo traz.

Vantagens:

  • Início a frio rápido, sem navegador moderno para inicializar.
  • Baixa memória, aproximadamente 50 MB por renderização.

Desvantagens:

  • O motor QtWebKit que ele fornece (aproximadamente um instantâneo do WebKit de 2012-2013, que o próprio Qt depreciou em 2015 e removeu em 2016) não pode renderizar Flexbox, Grid ouJavaScriptmoderno.
  • O repositório wkhtmltopdf foi arquivado em 2 de janeiro de 2023, e o último lançamento, 0.12.6, data de junho de 2020.
  • Ele carrega CVE-2022-35583, uma falha de Server-Side Request Forgery classificada como CVSS 9.8 (crítica) que não está corrigida porque o projeto não é mais mantido.

Licença: O próprio DinkToPdf é MIT, mas ele vincula os binários LGPLv3 do wkhtmltopdf, então a obrigação efetiva vem do wkhtmltopdf. Adequado para fluxos de trabalho legados pendentes de migração, com o risco de segurança mantido à vista. Veja a comparação entre wkhtmltopdf e IronPDF para a imagem completa da migração.

PdfSharp and HtmlRenderer

PdfSharp é uma biblioteca de código aberto amplamente usada, mas um equívoco comum é que ela converte HTML por conta própria. Não. PdfSharp fornece uma API de desenho de baixo nível baseada em coordenadas. Para converter HTML, você a emparelha com a ponte comunitária HtmlRenderer.PdfSharp, que analisa HTML e emite comandos de desenho PdfSharp.

using PdfSharp;
using TheArtOfDev.HtmlRenderer.PdfSharp;

public class PdfSharpExample
{
    public void GeneratePdf()
    {
        string html = "<h1>Simple Title</h1><p>Statically rendered text.</p>";

        // The HtmlRenderer bridge parses the HTML and emits PdfSharp drawing commands onto an A4 page
        var pdf = PdfGenerator.GeneratePdf(html, PageSize.A4);
        // Persist the resulting PdfSharp document to disk
        pdf.Save("simple_document.pdf");
    }
}
using PdfSharp;
using TheArtOfDev.HtmlRenderer.PdfSharp;

public class PdfSharpExample
{
    public void GeneratePdf()
    {
        string html = "<h1>Simple Title</h1><p>Statically rendered text.</p>";

        // The HtmlRenderer bridge parses the HTML and emits PdfSharp drawing commands onto an A4 page
        var pdf = PdfGenerator.GeneratePdf(html, PageSize.A4);
        // Persist the resulting PdfSharp document to disk
        pdf.Save("simple_document.pdf");
    }
}
Imports PdfSharp
Imports TheArtOfDev.HtmlRenderer.PdfSharp

Public Class PdfSharpExample
    Public Sub GeneratePdf()
        Dim html As String = "<h1>Simple Title</h1><p>Statically rendered text.</p>"

        ' The HtmlRenderer bridge parses the HTML and emits PdfSharp drawing commands onto an A4 page
        Dim pdf = PdfGenerator.GeneratePdf(html, PageSize.A4)
        ' Persist the resulting PdfSharp document to disk
        pdf.Save("simple_document.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Dois detalhes de configuração são importantes no .NET 10. A ponte espera a página de código Windows-1252, que está ausente por padrão no .NET moderno, então registre-a uma vez na inicialização com Encoding.RegisterProvider(CodePagesEncodingProvider.Instance). Emparelha a ponte com um pacote PdfSharp 6.x mais recente também quebra em tempo de execução com um MissingMethodException, então deixe o HtmlRenderer puxar seu próprio PdfSharp compatível em vez de fixar o mais recente.

O que funciona:

  • LicençaMITgenuinamente permissiva sem limites de receita.
  • Leve, sem binários nativos ou capturadores de navegador.
  • C# puro, então a implantação em sistemas operacionais é direta.

O que quebra:

  • A ponte HTML é limitada a aproximadamente HTML 4.01 e CSS Nível 2, e teve apenas um conjunto de lançamentos no final de 2025 após nove anos de dormência.
  • Nenhuma execução de JavaScript.
  • Regras de impressão como page-break-inside: avoid não são suportadas, então linhas de tabela se dividem entre páginas.

License: PdfSharp MIT, HtmlRenderer BSD-3-Clause. A escolha certa para documentos estáticos simples sem layout complexo. Para uma análise detalhada dos recursos, veja a comparação entre PdfSharp e IronPDF.

QuestPDF

QuestPDF segue um caminho diferente: ele descarta HTML e define layouts em C# através de uma API fluente. Para dados que se originam como objetos em vez de marcação, isso remove a etapa de geração de HTML apenas para analisá-lo de volta.

using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

public class QuestPdfExample
{
    public void GeneratePdf()
    {
        // The revenue-gated license tier must be declared before any document is built
        QuestPDF.Settings.License = LicenseType.Community;

        // Compose the layout in C# through the fluent API; no HTML anywhere
        var document = Document.Create(container =>
        {
            container.Page(page =>
            {
                // Define the physical page size and margins
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                // Place content into named page regions (header and body)
                page.Header().Text("Programmatic Invoice").FontSize(24);
                page.Content().Text("This document is generated without HTML.");
            });
        });

        // Run the layout engine and write the composed document to a file
        document.GeneratePdf("fluent_layout.pdf");
    }
}
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

public class QuestPdfExample
{
    public void GeneratePdf()
    {
        // The revenue-gated license tier must be declared before any document is built
        QuestPDF.Settings.License = LicenseType.Community;

        // Compose the layout in C# through the fluent API; no HTML anywhere
        var document = Document.Create(container =>
        {
            container.Page(page =>
            {
                // Define the physical page size and margins
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                // Place content into named page regions (header and body)
                page.Header().Text("Programmatic Invoice").FontSize(24);
                page.Content().Text("This document is generated without HTML.");
            });
        });

        // Run the layout engine and write the composed document to a file
        document.GeneratePdf("fluent_layout.pdf");
    }
}
Imports QuestPDF.Fluent
Imports QuestPDF.Helpers
Imports QuestPDF.Infrastructure

Public Class QuestPdfExample
    Public Sub GeneratePdf()
        ' The revenue-gated license tier must be declared before any document is built
        QuestPDF.Settings.License = LicenseType.Community

        ' Compose the layout in VB.NET through the fluent API; no HTML anywhere
        Dim document = Document.Create(Sub(container)
                                           container.Page(Sub(page)
                                                              ' Define the physical page size and margins
                                                              page.Size(PageSizes.A4)
                                                              page.Margin(2, Unit.Centimetre)
                                                              ' Place content into named page regions (header and body)
                                                              page.Header().Text("Programmatic Invoice").FontSize(24)
                                                              page.Content().Text("This document is generated without HTML.")
                                                          End Sub)
                                       End Sub)

        ' Run the layout engine and write the composed document to a file
        document.GeneratePdf("fluent_layout.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Pontos fortes:

  • Muito rápido, já que ignora a análise de DOM e layout de navegador.
  • Memória previsível e linear que se adapta a trabalhos em lote de alto rendimento.
  • Um aplicativo complementar oferece visualização ao vivo e atualização instantânea durante o design.

Pontos fracos:

  • É um motor de layout, não um renderizador de HTML, então não pode converter uma URL ou um modelo HTML existente.
  • Documentos HTML ou Razor existentes precisariam de uma reescrita completa na API fluente.
  • A licença passou deMITpara um modelo limitado por receita.

Licença: Licença Comunitária (gratuita para empresas com receita anual inferior a USD 1.000.000) ou um nível pago Professional e Enterprise. Encaixa-se em documentos de layout fixo definidos por código dirigidos por dados estruturados. Veja a comparação entreQuestPDFe IronPDF para a troca HTML versus layout fluente.

iText (pdfHTML)

iText 7 e 8 são reconhecidos pela manipulação programática de PDF, e o add-on pdfHTML converte HTML. Ao contrário das ferramentas Chromium, pdfHTML usa um analisador personalizado que mapeia tags HTML para objetos iText em vez de executar um navegador.

using iText.Html2pdf;
using System.IO;

public class iTextExample
{
    public void GeneratePdf()
    {
        string html = "<h1>Report</h1><p>Converted with pdfHTML.</p>";

        // Open the destination stream; using ensures the file handle is released after writing
        using var dest = File.Create("output.pdf");
        // pdfHTML maps the HTML tags to iText objects and writes them to the stream (no browser involved)
        HtmlConverter.ConvertToPdf(html, dest);
    }
}
using iText.Html2pdf;
using System.IO;

public class iTextExample
{
    public void GeneratePdf()
    {
        string html = "<h1>Report</h1><p>Converted with pdfHTML.</p>";

        // Open the destination stream; using ensures the file handle is released after writing
        using var dest = File.Create("output.pdf");
        // pdfHTML maps the HTML tags to iText objects and writes them to the stream (no browser involved)
        HtmlConverter.ConvertToPdf(html, dest);
    }
}
Imports iText.Html2pdf
Imports System.IO

Public Class iTextExample
    Public Sub GeneratePdf()
        Dim html As String = "<h1>Report</h1><p>Converted with pdfHTML.</p>"

        ' Open the destination stream; using ensures the file handle is released after writing
        Using dest As FileStream = File.Create("output.pdf")
            ' pdfHTML maps the HTML tags to iText objects and writes them to the stream (no browser involved)
            HtmlConverter.ConvertToPdf(html, dest)
        End Using
    End Sub
End Class
$vbLabelText   $csharpLabel

Em um projeto novo, isso lança erros até você adicionar o pacote itext7.bouncy-castle-adapter, que o iText requer para seu caminho de criptografia. Essa dependência extra é fácil de perder e produz um erro opaco sem ela.

Vantagens:

  • Manipulação profunda de PDF, assinatura e redação em todo o ecossistema iText.
  • Produz PDF/A e PDF/UA a partir de HTML semântico, o que se adapta ao trabalho de conformidade.
  • Tempo de inicialização rápido, já que não lança navegador.

Desvantagens:

  • Sem execução de script, então o conteúdo dinâmico não é renderizado.
  • Recursos CSS3, como Grid não são compatíveis e falham silenciosamente.
  • A licença AGPLv3 exige uma licença comercial para aplicativos de código fechado, e arquivos grandes são armazenados em buffer em vez de transmitidos.

License: AGPLv3 or Commercial. Escolha-o para manipulação pesada de PDF e fluxos de trabalho de conformidade com HTML estático e controlado. Para os detalhes de licenciamento e manipulação, veja a comparação entre iText 7 e IronPDF.

IronPDF

IronPDF incorpora um mecanismo Chromium dentro de seu pacote NuGet e o expõe por meio de uma API C#, portanto, nada externo precisa ser iniciado ou agrupado. Ele fica entre as ferramentas de navegador gratuitas e as bibliotecas programáticas, trocando um custo de licença por fidelidade de renderização sem o navegador para gerenciar.

using IronPdf;
using System.Threading.Tasks;

public class IronPdfExample
{
    public async Task GeneratePdfAsync()
    {
        // Create the in-process Chromium renderer (no external browser to launch)
        var renderer = new ChromePdfRenderer();
        // Turn on theJavaScriptengine so client-side chart scripts execute before capture
        renderer.RenderingOptions.EnableJavaScript = true;
        // Wait 500 ms after load to let JavaScript-built content settle before rendering
        renderer.RenderingOptions.WaitFor.RenderDelay(500);

        // Render the HTML string asynchronously into an in-memory PDF
        var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Quarterly Report</h1><div class='chart'></div>");
        // Save the finished PDF to disk
        pdf.SaveAs("report.pdf");
    }
}
using IronPdf;
using System.Threading.Tasks;

public class IronPdfExample
{
    public async Task GeneratePdfAsync()
    {
        // Create the in-process Chromium renderer (no external browser to launch)
        var renderer = new ChromePdfRenderer();
        // Turn on theJavaScriptengine so client-side chart scripts execute before capture
        renderer.RenderingOptions.EnableJavaScript = true;
        // Wait 500 ms after load to let JavaScript-built content settle before rendering
        renderer.RenderingOptions.WaitFor.RenderDelay(500);

        // Render the HTML string asynchronously into an in-memory PDF
        var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Quarterly Report</h1><div class='chart'></div>");
        // Save the finished PDF to disk
        pdf.SaveAs("report.pdf");
    }
}
Imports IronPdf
Imports System.Threading.Tasks

Public Class IronPdfExample
    Public Async Function GeneratePdfAsync() As Task
        ' Create the in-process Chromium renderer (no external browser to launch)
        Dim renderer As New ChromePdfRenderer()
        ' Turn on the JavaScript engine so client-side chart scripts execute before capture
        renderer.RenderingOptions.EnableJavaScript = True
        ' Wait 500 ms after load to let JavaScript-built content settle before rendering
        renderer.RenderingOptions.WaitFor.RenderDelay(500)

        ' Render the HTML string asynchronously into an in-memory PDF
        Dim pdf = Await renderer.RenderHtmlAsPdfAsync("<h1>Quarterly Report</h1><div class='chart'></div>")
        ' Save the finished PDF to disk
        pdf.SaveAs("report.pdf")
    End Function
End Class
$vbLabelText   $csharpLabel

O mesmo renderizador converte uma URL para PDF com uma chamada:

// RenderUrlAsPdf fetches and renders the live page in one call, no navigation step needed
var fromUrl = new ChromePdfRenderer().RenderUrlAsPdf("https://example.com");
// Write the captured page to disk
fromUrl.SaveAs("from_url.pdf");
// RenderUrlAsPdf fetches and renders the live page in one call, no navigation step needed
var fromUrl = new ChromePdfRenderer().RenderUrlAsPdf("https://example.com");
// Write the captured page to disk
fromUrl.SaveAs("from_url.pdf");
' RenderUrlAsPdf fetches and renders the live page in one call, no navigation step needed
Dim fromUrl = (New ChromePdfRenderer()).RenderUrlAsPdf("https://example.com")
' Write the captured page to disk
fromUrl.SaveAs("from_url.pdf")
$vbLabelText   $csharpLabel

Ele também renderiza vistas Razor e MVC para PDF e converte arquivos HTML diretamente. O guia completo de recursos está no tutorial HTML para PDF.

Prós:

  • Renderização de grau de navegador que lida com Grid, Flexbox e scripts do lado do cliente.
  • Implantação sem executáveis externos ou pool de navegadores.
  • Gera PDF/A e aplica assinaturas digitais, o que o separa dos frameworks de teste.

Contras:

  • É necessária uma licença comercial, sem nível de produção gratuito.
  • Após uma implantação nova, a primeira renderização carrega um custo de inicialização único, mas renderizações posteriores se estabilizam em um caminho rápido.

License: Commercial, perpetual. Use-o onde o CSS atual em volume importa e as prioridades são cortar a sobrecarga de operações enquanto mantém alta fidelidade.

Tabela de Comparação Completa

Uma linha por biblioteca, com a coluna de licença incluída porque ela direciona diretamente a decisão gratuita versus paga.

Biblioteca Motor JavaScript CSS moderno Peso da implantação Licença Ideal para
IronPDF Chromium incorporado Sim Completo Leve (NuGet) Comercial CSS moderno em escala
PuppeteerSharp Chromium externo Sim Completo Pesado (download binário) MIT Renderização de navegador gratuita
Dramaturgo Chromium externo Sim Completo Pesado (download binário) MIT Renderização gratuita moderna
wkhtmltopdf QtWebKit antigo Limitado Fraco Médio (libs nativas) LGPLv3 (wrapper MIT) Fluxos de trabalho legados
PdfSharp + HtmlRenderer Desenho personalizado Não Limitado Leve MIT / BSD-3 HTML estático simples
QuestPDF Programático N / D N / D Leve Comunidade / Pago Layouts definidos por código
iText pdfHTML Parser customizado Não Limitado Médio AGPLv3 / Comercial Manipulação de PDF

Verifique cada célula em relação ao lançamento atual de cada biblioteca antes da integração, uma vez que as licenças e suporte ao motor mudam.

Grátis vs Pago: quando cada um é a escolha certa

Ferramentas que são 'gratuitas' podem ocultar custos operacionais e legais no campo de PDF do .NET, então nomear os casos em que uma ferramenta gratuita é a escolha certa é o ponto de partida honesto.

Uma biblioteca de código aberto genuinamente gratuita é suficiente para documentos simples, estáticos, de baixo volume ou uma equipe com capacidade de operações para gerenciar processos externos. Um recibo pesado em texto sem estilo complexo renderiza bem com o PdfSharp licenciado pelo MIT. Onde uma equipe já está executando Dramaturgo para testes e resolveu a conteinerização, reutilizá-lo para trabalhos de PDF ocasionais é eficiente.

Software gratuito não significa uma implementação gratuita. O custo oculto dos navegadores headless de código aberto aparece em horas de manutenção: agrupando o ciclo de vida do navegador para que o servidor não trave sob carga, configurando dependências de biblioteca compartilhadas do Linux em imagens de contêiner e absorvendo o custo de infraestrutura de processos de navegador pesados. Para documentos estáticos triviais, um motor de navegador pago é exagero, e uma biblioteca leve e gratuita é a melhor escolha.

Uma biblioteca Chromium comercial torna-se justificada quando o trabalho exige CSS3 preciso em volume, saída de PDF/UA acessível e simplicidade de implantação sobre o custo de aquisição. O licenciamento comercial também remove a exposição copyleft. Adicionar uma biblioteca AGPLv3, como o iText, a uma plataforma SaaS pode obrigar a empresa a liberar seu código-fonte, a menos que uma licença comercial seja comprada. A verdadeira comparação é o custo total de propriedade: tempo de operações e risco legal de um lado, taxas de licença do outro.

Benchmarks

Todos os números abaixo vêm de uma execução prática em uma máquina, então trate-os como direcionais. O documento de teste é uma fatura de 30 linhas usando CSS Grid no cabeçalho e um gráfico de barrasJavaScriptembutido. Os testes foram realizados em uma estação de trabalho Windows padrão no .NET 10. Cada figura quente é a média de oito renderizações após a primeira, e a memória máxima é o conjunto de trabalho máximo do processo .NET mais quaisquer processos filho do navegador que ele gerou.

Biblioteca Início a frio (por processo) Renderização rápida (média de 8) Memória máxima
IronPDF 345 ms 202 ms 406 MB
PuppeteerSharp 746 ms 204 ms 611 MB
Dramaturgo 588 ms 132 ms 515 MB
wkhtmltopdf, iText, PdfSharp sub-second not comparable 50 a 120 MB

Uma vez aquecidos, os três motores de navegador renderizam o mesmo documento em cerca de 130 a 200 ms, com Dramaturgo mais rápido nesta execução e IronPDFe PuppeteerSharp logo atrás. Não início a frio, o motor incorporado começou mais rápido aqui porque ele é executado em processo sem nenhum navegador separado para iniciar, embora a primeira renderização após uma implantação nova absorva um único custo de inicialização do motor que inícios de processo posteriores pulam. As ferramentas de motores arquivados e analisadores personalizados (wkhtmltopdf, iText, PdfSharp) iniciam-se em menos de um segundo e usam a menor memória, mas essa vantagem é nula para o documento de teste, já que eles não podem renderizar corretamente seu layout Grid ou seu gráfico JavaScript. wkhtmltopdf não conseguiu rodar completamente sem que seus binários nativos fossem fornecidos primeiro.

A diferença de fidelidade se mostra na saída. O motor de navegador renderiza o cabeçalho CSS Grid, a tabela estilizada e o gráfico de barras JavaScript:

O fatura de teste renderizado por um motor Chromium, com o cabeçalho CSS Grid, tabela estilizada e gráfico de barrasJavaScripttodos presentes

O mesmo documento através do PdfSharp com HtmlRenderer deixa de lado o cabeçalho do grid, o estilo do cabeçalho da tabela e o gráfico JavaScript:

O mesmo fatura renderizado pelo PdfSharp com HtmlRenderer, faltando o cabeçalho CSS Grid e o gráfico JavaScript

Qual você deve usar?

Um veredito breve para cada cenário comum:

  • Frameworks CSS e saída de página única: apenas um renderizador de nível de navegador acompanha.
  • HTML estático simples ou recibos de texto: o PdfSharp e uma pequena pilha gratuita cobrem isso.
  • Layouts programáticos, orientados por dados, sem marcação: oQuestPDFchega lá rapidamente.
  • Renderização de navegador gratuita com capacidade de operações: PuppeteerSharp ou Playwright.
  • Zero infraestrutura: uma API hospedada de HTML para PDF.
  • Migração wkhtmltopdf legada: mova-se para um motor incorporado para segurança e suporte a CSS.

Quando a saída pesada de framework CSS encontra uma necessidade de baixa operação,IronPDFé a opção incorporada a procurar primeiro, enquanto as ferramentas de navegador gratuitas continuam sendo a escolha certa para equipes que podem possuir as operações em torno de um navegador headless.

Considerações de implantação

A maior fricção na geração de documentos .NET é a lacuna entre uma biblioteca que funciona em um laptop Windows e uma que falha em um contêiner Linux. Selecionar uma biblioteca significa antecipar onde ela será enviada.

No Docker, navegadores orquestrados como PuppeteerSharp e Dramaturgo precisam de uma imagem base carregando as dependências Linux do Chromium, incluindo libnss3, libatk-bridge2.0-0, e libgbm1. A Microsoft publica imagens do Dramaturgo .NET em mcr.microsoft.com/playwright/dotnet (por exemplo, uma tag v1.NN.0-noble) para cobrir essas, e essas imagens rodam perto de um gigabyte. Motores incorporados evitam o inchaço enviando pacotes NuGet por arquitetura, como IronPdf.Linux, que incluem os binários nativos e mantêm uma imagem base padrão aspnet funcionando sem etapas manuais apt-get.

O AWS Lambda levanta uma barreira diferente. Ele impõe um limite rígido de 250 MB no pacote de implantação descompactado, mas uma compilação headless do Chromium sozinha ocupa de 150 MB a 300 MB. Isso torna uma implantação zip padrão do PuppeteerSharp ou Dramaturgo impraticável e empurra as equipes para o Lambda baseado em contêiner, que permite até 10 GB ao custo de um início a frio pior.

O Azure App Service adiciona suas próprias restrições em ambos os sistemas operacionais. O sandbox do Windows App Service bloqueia a maioria das chamadas User32 e GDI32 e, consequentemente, quebra os caminhos de renderização dependentes de GDI. Implantar o DinkToPdf no Linux App Service significa copiar arquivos .so não gerenciados para o resultado e instalar dependências como libfontconfig1 e libxrender1; uma ausente aparece como um System.DllNotFoundException opaco. Esses são os mesmos problemas de dependência nativa e sandbox que a execução de verificação reproduziu.

Conclusão e recomendação

O campo de HTML para PDF do C# no .NET 10 recompensa combinar a ferramenta com o documento. Um motor de navegador completo é a base para frameworks CSS e layouts responsivos e páginas dirigidas por JavaScript, e a divisão entre gratuito e comercial é realmente uma divisão entre esforço de operações e custo de licença. Bibliotecas programáticas permanecem eficientes para layouts fixos e estáticos, e oQuestPDFé a rota mais rápida quando a entrada são dados estruturados em vez de marcação. O wkhtmltopdf pertence apenas aos planos de migração, dado seu motor arquivado e a falha SSRF não corrigida. Para equipes que querem renderização precisa sem muita sobrecarga de operações,IronPDFé a opção incorporada padrão, com URL para PDF, renderização de vistas Razor, saída PDF/A e assinaturas digitais disponíveis na mesma API, enquanto PuppeteerSharp e Dramaturgo continuam sendo escolhas gratuitas robustas onde o ciclo de vida do navegador é algo que a equipe pode possuir.

Tente em seu próprio HTML

Se a renderização precisa com um baixo custo de envio se encaixa em seu projeto, você pode iniciar uma avaliação gratuita do IronPDF e executar essa mesma fatura de teste contra seus próprios modelos antes de se comprometer.IronPDFé desenvolvido por Iron Software, cujas bibliotecas .NET também cobrem OCR, códigos de barras, Word e Excel.

Obrigado por ler. Independentemente da biblioteca que você escolher, combine-a com o documento à sua frente.

ObserveIronPDF is a product of Iron Software. PuppeteerSharp, Playwright, wkhtmltopdf, DinkToPdf, PdfSharp, HtmlRenderer,QuestPDFe iText são projetos ou marcas registradas de seus respectivos proprietários. Este artigo não está afiliado, endossado ou patrocinado por esses projetos. As comparações refletem informações publicamente disponíveis e testes práticos no momento da escrita; verifique os detalhes de licenciamento e lançamento atuais antes de se basear neles.

Perguntas frequentes

What are the main types of C# HTML to PDF libraries available for .NET 10 in 2026?

The main types of C# HTML to PDF libraries for .NET 10 in 2026 include browser-based engines like Chromium using PuppeteerSharp or Playwright, programmatic libraries such as iText and PdfSharp, and code-first layout tools like QuestPDF.

How do browser-based engines compare to programmatic libraries for HTML to PDF conversion?

Browser-based engines render modern CSS and JavaScript accurately, providing high fidelity to web standards, whereas programmatic libraries like iText and PdfSharp trade some web fidelity for a smaller footprint by drawing PDFs from custom parsers.

What advantages do code-first layout tools offer over traditional HTML to PDF methods?

Code-first layout tools like QuestPDF allow developers to skip HTML entirely, often resulting in more efficient and customizable PDF generation tailored to specific application needs.

Why is choosing the right rendering engine important for HTML to PDF conversion?

Choosing the right rendering engine is crucial because it determines how accurately your documents are rendered, especially in terms of modern CSS and JavaScript fidelity, which is important for maintaining the visual integrity of your PDFs.

What role do licensing terms play in selecting a C# HTML to PDF library?

Licensing terms are important as they dictate what you can legally do with the library, such as distributing the software commercially, and can affect the overall cost and feasibility of using the library in your projects.

Are there free options available for C# HTML to PDF conversion?

Yes, there are free options available, though they may come with limitations in terms of features and support compared to paid alternatives. It's important to weigh these against your project needs.

How do benchmarks help in evaluating C# HTML to PDF libraries?

Benchmarks provide a quantitative measure of performance, allowing developers to compare libraries based on speed, resource usage, and output quality, helping in making an informed decision.

What is the significance of runnable code examples in library comparisons?

Runnable code examples are significant as they allow developers to test libraries in real-world scenarios, providing insights into ease of use, integration complexity, and how well a library fits specific project requirements.

Can IronPDF be a suitable option for HTML to PDF conversion in .NET 10?

Yes, IronPDF is a suitable option, known for its ease of use, comprehensive features, and support for modern web standards, making it a strong contender for HTML to PDF conversion in .NET 10.

Curtis Chau
Redator Técnico

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

Leia mais

Equipe de Suporte Iron

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