ASP.NET Core: Criar PDF Dinamicamente com IronPDF
Gere documentos PDF profissionais dinamicamente em ASP.NET Core , convertendo conteúdo HTML em PDFs refinados e transmitindo-os diretamente para o navegador — sem necessidade de armazenamento em disco, sem arquivos temporários para gerenciar.
Ao desenvolver aplicações web modernas em ASP.NET Core, a capacidade de gerar documentos PDF sob demanda é um requisito recorrente. As faturas precisam ser baixadas assim que o pagamento for confirmado. Os relatórios de conformidade devem aparecer instantaneamente quando um auditor clicar em "Exportar". Os certificados devem estar prontos antes que o usuário tenha tempo de se perguntar se algo deu errado. O IronPDF lida com todos esses cenários por meio de sua biblioteca PDF baseada no Chromium, que converte HTML — incluindo CSS, JavaScript e fontes da web — em saída PDF com precisão de pixel, sem gravar nada no disco.
Este guia abrange tudo o que você precisa saber: como instalar a biblioteca, gerar faturas a partir de strings HTML, transmitir relatórios a partir de dados do Entity Framework, aplicar cabeçalhos de página e configurações de segurança e adotar as melhores práticas para manter o bom desempenho de aplicativos ASP.NET de alto tráfego.
O que significa criar PDFs instantaneamente?
"On the fly" significa que o documento é construído na memória no momento da solicitação HTTP e enviado diretamente para o solicitante. Nenhum arquivo PDF é gravado no sistema de arquivos, nenhuma tarefa em segundo plano enfileira o trabalho e nenhum cache armazena o resultado entre as solicitações.
Essa abordagem é importante por diversos motivos. Em primeiro lugar, os destinos de implantação na nuvem -- Azure App Service, AWS Lambda, contêineres Docker -- geralmente são executados em ambientes onde o sistema de arquivos local é efêmero ou somente leitura. Gerar um PDF em uma pasta temporária e depois lê-lo novamente é uma prática frágil nesses ambientes. Em segundo lugar, evitar gravações em disco reduz a superfície de ataque: não há arquivo residual que uma solicitação subsequente possa servir acidentalmente ao usuário errado. Em terceiro lugar, a geração somente em memória é normalmente mais rápida porque elimina duas operações de E/S (gravação e leitura) no caminho crítico.
O ChromePdfRenderer do IronPDF expõe uma propriedade .BinaryData e uma propriedade .Stream em cada documento gerado. Qualquer um deles pode ser passado diretamente para um ASP.NET Core FileResult, tornando o streaming uma tarefa de apenas uma linha na prática.
Comece a usar IronPDF no seu projeto hoje mesmo com um teste gratuito.
Como instalar o IronPDF em um projeto ASP.NET Core ?
Adicione o pacote NuGet através do Console do Gerenciador de Pacotes ou da CLI do .NET :
Install-Package IronPdf
dotnet add package IronPdf
Install-Package IronPdf
dotnet add package IronPdf
Após a instalação do pacote, defina sua chave de licença na inicialização do aplicativo -- normalmente em Program.cs antes da criação do primeiro renderizador:
using IronPdf;
// Place license activation before any IronPDF call
License.LicenseKey = "YOUR-LICENSE-KEY";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
// Register ChromePdfRenderer as a singleton so the Chromium engine
// is initialised once and reused across all requests.
builder.Services.AddSingleton<ChromePdfRenderer>();
var app = builder.Build();
app.MapDefaultControllerRoute();
app.Run();
using IronPdf;
// Place license activation before any IronPDF call
License.LicenseKey = "YOUR-LICENSE-KEY";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
// Register ChromePdfRenderer as a singleton so the Chromium engine
// is initialised once and reused across all requests.
builder.Services.AddSingleton<ChromePdfRenderer>();
var app = builder.Build();
app.MapDefaultControllerRoute();
app.Run();
Imports IronPdf
' Place license activation before any IronPDF call
License.LicenseKey = "YOUR-LICENSE-KEY"
Dim builder = WebApplication.CreateBuilder(args)
builder.Services.AddControllersWithViews()
' Register ChromePdfRenderer as a singleton so the Chromium engine
' is initialised once and reused across all requests.
builder.Services.AddSingleton(Of ChromePdfRenderer)()
Dim app = builder.Build()
app.MapDefaultControllerRoute()
app.Run()
É importante registrar ChromePdfRenderer como um singleton. O renderizador inicia um subprocesso interno do Chromium na primeira vez que é utilizado. Se você criar uma nova instância por solicitação, pagará esse custo de inicialização em cada chamada, o que adiciona centenas de milissegundos de latência sob carga. Uma instância singleton é thread-safe e lida com solicitações de renderização simultâneas sem configuração adicional.
Para uma visão mais abrangente das opções de instalação, incluindo configurações NuGet.config para feeds privados, visite a visão geral da instalação .
Como gerar um PDF de fatura a partir de uma string HTML?
O caso de uso mais comum para geração instantânea de documentos é a criação de documentos transacionais — faturas, recibos, confirmações de pedidos — em que o conteúdo muda conforme a solicitação, mas o layout permanece constante.
O padrão é: construir uma string HTML com dados interpolados, passá-la para RenderHtmlAsPdf e retornar o resultado binário como um arquivo para download.
using IronPdf;
using Microsoft.AspNetCore.Mvc;
public class DocumentController : Controller
{
private readonly ChromePdfRenderer _renderer;
public DocumentController(ChromePdfRenderer renderer)
{
_renderer = renderer;
}
[HttpGet("invoice/{orderId:int}")]
public IActionResult GetInvoice(int orderId)
{
// In a real application, fetch this from your database or order service.
var order = GetOrderData(orderId);
string html = $"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; color: #333; }}
h1 {{ color: #1a56db; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 24px; }}
th, td {{ padding: 10px 14px; border: 1px solid #d1d5db; text-align: left; }}
th {{ background: #f3f4f6; }}
tfoot td {{ font-weight: bold; }}
</style>
</head>
<body>
<h1>Invoice #{order.InvoiceNumber}</h1>
<p>Date: {DateTime.UtcNow:yyyy-MM-dd} | Customer: {order.CustomerName}</p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Subtotal</th></tr></thead>
<tbody>
{string.Join("", order.Items.Select(i =>
$"<tr><td>{i.Name}</td><td>{i.Quantity}</td>" +
$"<td>${i.UnitPrice:F2}</td><td>${i.Quantity * i.UnitPrice:F2}</td></tr>"))}
</tbody>
<tfoot>
<tr><td colspan="3">Total</td><td>${order.Items.Sum(i => i.Quantity * i.UnitPrice):F2}</td></tr>
</tfoot>
</table>
</body>
</html>
""";
var pdf = _renderer.RenderHtmlAsPdf(html);
return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf");
}
}
using IronPdf;
using Microsoft.AspNetCore.Mvc;
public class DocumentController : Controller
{
private readonly ChromePdfRenderer _renderer;
public DocumentController(ChromePdfRenderer renderer)
{
_renderer = renderer;
}
[HttpGet("invoice/{orderId:int}")]
public IActionResult GetInvoice(int orderId)
{
// In a real application, fetch this from your database or order service.
var order = GetOrderData(orderId);
string html = $"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; color: #333; }}
h1 {{ color: #1a56db; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 24px; }}
th, td {{ padding: 10px 14px; border: 1px solid #d1d5db; text-align: left; }}
th {{ background: #f3f4f6; }}
tfoot td {{ font-weight: bold; }}
</style>
</head>
<body>
<h1>Invoice #{order.InvoiceNumber}</h1>
<p>Date: {DateTime.UtcNow:yyyy-MM-dd} | Customer: {order.CustomerName}</p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Subtotal</th></tr></thead>
<tbody>
{string.Join("", order.Items.Select(i =>
$"<tr><td>{i.Name}</td><td>{i.Quantity}</td>" +
$"<td>${i.UnitPrice:F2}</td><td>${i.Quantity * i.UnitPrice:F2}</td></tr>"))}
</tbody>
<tfoot>
<tr><td colspan="3">Total</td><td>${order.Items.Sum(i => i.Quantity * i.UnitPrice):F2}</td></tr>
</tfoot>
</table>
</body>
</html>
""";
var pdf = _renderer.RenderHtmlAsPdf(html);
return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf");
}
}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc
Public Class DocumentController
Inherits Controller
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New(renderer As ChromePdfRenderer)
_renderer = renderer
End Sub
<HttpGet("invoice/{orderId:int}")>
Public Function GetInvoice(orderId As Integer) As IActionResult
' In a real application, fetch this from your database or order service.
Dim order = GetOrderData(orderId)
Dim html As String = $"
<!DOCTYPE html>
<html lang=""en"">
<head>
<meta charset=""utf-8"">
<style>
body {{ font-family: Arial, sans-serif; margin: 40px; color: #333; }}
h1 {{ color: #1a56db; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 24px; }}
th, td {{ padding: 10px 14px; border: 1px solid #d1d5db; text-align: left; }}
th {{ background: #f3f4f6; }}
tfoot td {{ font-weight: bold; }}
</style>
</head>
<body>
<h1>Invoice #{order.InvoiceNumber}</h1>
<p>Date: {DateTime.UtcNow:yyyy-MM-dd} | Customer: {order.CustomerName}</p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Subtotal</th></tr></thead>
<tbody>
{String.Join("", order.Items.Select(Function(i) $"<tr><td>{i.Name}</td><td>{i.Quantity}</td>" +
$"<td>${i.UnitPrice:F2}</td><td>${i.Quantity * i.UnitPrice:F2}</td></tr>"))}
</tbody>
<tfoot>
<tr><td colspan=""3"">Total</td><td>${order.Items.Sum(Function(i) i.Quantity * i.UnitPrice):F2}</td></tr>
</tfoot>
</table>
</body>
</html>
"
Dim pdf = _renderer.RenderHtmlAsPdf(html)
Return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf")
End Function
End Class
RenderHtmlAsPdf processa o documento HTML completo -- CSS grid, Flexbox, fontes da web e até mesmo SVG embutido -- usando o mesmo mecanismo Chromium que alimenta o Google Chrome. O código retornado PdfDocument expõe BinaryData (um byte[]) e Stream (um MemoryStream). Passar BinaryData para File() com "application/pdf" e um nome de arquivo inicia um download no navegador.
Para layouts que exigem fidelidade perfeita em pixels, consulte o guia de renderização de HTML para PDF , que aborda CSS responsivo, fontes personalizadas e renderização em JavaScript .
Qual é a aparência do PDF da fatura gerada?

Como transmitir um PDF diretamente para o navegador sem abrir uma caixa de diálogo de download?
Para exibir um PDF embutido -- abrindo-o no visualizador integrado do navegador em vez de baixá-lo -- são necessárias duas pequenas alterações: defina Content-Disposition como inline e omita o nome do arquivo da chamada File().
[HttpPost("report/preview")]
public async Task<IActionResult> PreviewReport([FromBody] ReportRequest request)
{
string html = BuildReportHtml(request);
var pdfDocument = await _renderer.RenderHtmlAsPdfAsync(html);
// "inline" tells the browser to display rather than download.
Response.Headers["Content-Disposition"] = "inline; filename=report.pdf";
return new FileContentResult(pdfDocument.BinaryData, "application/pdf");
}
[HttpPost("report/preview")]
public async Task<IActionResult> PreviewReport([FromBody] ReportRequest request)
{
string html = BuildReportHtml(request);
var pdfDocument = await _renderer.RenderHtmlAsPdfAsync(html);
// "inline" tells the browser to display rather than download.
Response.Headers["Content-Disposition"] = "inline; filename=report.pdf";
return new FileContentResult(pdfDocument.BinaryData, "application/pdf");
}
Imports Microsoft.AspNetCore.Mvc
<HttpPost("report/preview")>
Public Async Function PreviewReport(<FromBody> request As ReportRequest) As Task(Of IActionResult)
Dim html As String = BuildReportHtml(request)
Dim pdfDocument = Await _renderer.RenderHtmlAsPdfAsync(html)
' "inline" tells the browser to display rather than download.
Response.Headers("Content-Disposition") = "inline; filename=report.pdf"
Return New FileContentResult(pdfDocument.BinaryData, "application/pdf")
End Function
Recomenda-se o uso da sobrecarga assíncrona RenderHtmlAsPdfAsync para controladores ASP.NET Core , pois ela libera a thread do pool de threads enquanto o Chromium renderiza, mantendo o servidor responsivo sob carga simultânea.
Como funciona a geração de PDFs baseada em memória?

O array de bytes pdfDocument.BinaryData reside inteiramente na memória gerenciada. Não há nenhum caminho de arquivo intermediário envolvido. O cabeçalho Content-Disposition controla se o PDF é exibido diretamente na página ou oferecido para download — um comportamento do navegador definido pela especificação HTTP. Para uma análise mais aprofundada da abordagem MemoryStream, incluindo o streaming para o Armazenamento de Blobs do Azure, consulte a documentação em PDF do MemoryStream .
Como gerar PDFs a partir dos resultados de uma consulta do Entity Framework Core?
A maioria das aplicações empresariais extrai dados de relatórios de um banco de dados em vez de criá-los no momento da chamada. O padrão abaixo consulta o Entity Framework Core , constrói uma tabela HTML e retorna um PDF — tudo dentro de uma única ação do controlador.
[HttpGet("report/monthly")]
public async Task<IActionResult> MonthlyReport(int year, int month)
{
// Pull aggregated transaction data from EF Core.
var rows = await _dbContext.Transactions
.Where(t => t.Date.Year == year && t.Date.Month == month)
.GroupBy(t => t.Category)
.Select(g => new { Category = g.Key, Count = g.Count(), Total = g.Sum(t => t.Amount) })
.OrderByDescending(g => g.Total)
.ToListAsync();
string tableRows = string.Join("", rows.Select(r =>
$"<tr><td>{r.Category}</td><td>{r.Count}</td><td>${r.Total:F2}</td></tr>"));
string html = $"""
<html><body style="font-family:Arial,sans-serif;padding:32px">
<h1>Monthly Report -- {month:D2}/{year}</h1>
<table style="width:100%;border-collapse:collapse">
<thead>
<tr style="background:#e5e7eb">
<th style="padding:8px;border:1px solid #d1d5db">Category</th>
<th style="padding:8px;border:1px solid #d1d5db">Transactions</th>
<th style="padding:8px;border:1px solid #d1d5db">Total</th>
</tr>
</thead>
<tbody>{tableRows}</tbody>
</table>
</body></html>
""";
var pdf = _renderer.RenderHtmlAsPdf(html);
pdf.MetaData.Title = $"Monthly Report {month:D2}/{year}";
pdf.MetaData.Author = "Reporting System";
return File(pdf.BinaryData, "application/pdf", $"report-{year}-{month:D2}.pdf");
}
[HttpGet("report/monthly")]
public async Task<IActionResult> MonthlyReport(int year, int month)
{
// Pull aggregated transaction data from EF Core.
var rows = await _dbContext.Transactions
.Where(t => t.Date.Year == year && t.Date.Month == month)
.GroupBy(t => t.Category)
.Select(g => new { Category = g.Key, Count = g.Count(), Total = g.Sum(t => t.Amount) })
.OrderByDescending(g => g.Total)
.ToListAsync();
string tableRows = string.Join("", rows.Select(r =>
$"<tr><td>{r.Category}</td><td>{r.Count}</td><td>${r.Total:F2}</td></tr>"));
string html = $"""
<html><body style="font-family:Arial,sans-serif;padding:32px">
<h1>Monthly Report -- {month:D2}/{year}</h1>
<table style="width:100%;border-collapse:collapse">
<thead>
<tr style="background:#e5e7eb">
<th style="padding:8px;border:1px solid #d1d5db">Category</th>
<th style="padding:8px;border:1px solid #d1d5db">Transactions</th>
<th style="padding:8px;border:1px solid #d1d5db">Total</th>
</tr>
</thead>
<tbody>{tableRows}</tbody>
</table>
</body></html>
""";
var pdf = _renderer.RenderHtmlAsPdf(html);
pdf.MetaData.Title = $"Monthly Report {month:D2}/{year}";
pdf.MetaData.Author = "Reporting System";
return File(pdf.BinaryData, "application/pdf", $"report-{year}-{month:D2}.pdf");
}
Imports Microsoft.AspNetCore.Mvc
Imports System.Threading.Tasks
Imports System.Linq
<HttpGet("report/monthly")>
Public Async Function MonthlyReport(year As Integer, month As Integer) As Task(Of IActionResult)
' Pull aggregated transaction data from EF Core.
Dim rows = Await _dbContext.Transactions _
.Where(Function(t) t.Date.Year = year AndAlso t.Date.Month = month) _
.GroupBy(Function(t) t.Category) _
.Select(Function(g) New With {Key .Category = g.Key, Key .Count = g.Count(), Key .Total = g.Sum(Function(t) t.Amount)}) _
.OrderByDescending(Function(g) g.Total) _
.ToListAsync()
Dim tableRows As String = String.Join("", rows.Select(Function(r) $"<tr><td>{r.Category}</td><td>{r.Count}</td><td>${r.Total:F2}</td></tr>"))
Dim html As String = $"
<html><body style='font-family:Arial,sans-serif;padding:32px'>
<h1>Monthly Report -- {month:D2}/{year}</h1>
<table style='width:100%;border-collapse:collapse'>
<thead>
<tr style='background:#e5e7eb'>
<th style='padding:8px;border:1px solid #d1d5db'>Category</th>
<th style='padding:8px;border:1px solid #d1d5db'>Transactions</th>
<th style='padding:8px;border:1px solid #d1d5db'>Total</th>
</tr>
</thead>
<tbody>{tableRows}</tbody>
</table>
</body></html>
"
Dim pdf = _renderer.RenderHtmlAsPdf(html)
pdf.MetaData.Title = $"Monthly Report {month:D2}/{year}"
pdf.MetaData.Author = "Reporting System"
Return File(pdf.BinaryData, "application/pdf", $"report-{year}-{month:D2}.pdf")
End Function
A configuração pdf.MetaData.Title e pdf.MetaData.Author incorpora essas informações nas propriedades do documento PDF, o que é útil para o rastreamento de conformidade e sistemas de gerenciamento de documentos. Para layouts de relatório mais sofisticados, considere estilos de impressão CSS , quebras de página explícitas e imagens de gráficos incorporadas .
Como aplicar cabeçalhos, rodapés e segurança a PDFs gerados?
Documentos de produção frequentemente exigem cabeçalhos com o título do documento, rodapés com números de página e controles de acesso que impeçam a impressão ou cópia não autorizada. O ChromePdfRenderOptions do IronPDF atende a todos esses requisitos.
[HttpPost("document/secured")]
public async Task<IActionResult> GenerateSecuredDocument([FromBody] SecuredDocRequest request)
{
var renderOptions = new ChromePdfRenderOptions
{
Tamanho do papel = Tamanho do papel PDF.A4,
MarginTop = 45,
MarginBottom = 45,
MarginLeft = 25,
MarginRight = 25,
Habilitar JavaScript = true,
WaitFor = new WaitFor { RenderDelay = 500 }
};
renderOptions.TextHeader = new CabeçalhoRodapé
{
CenterText = request.DocumentTitle,
DrawDividerLine = true,
FontSize = 11
};
renderOptions.TextFooter = new CabeçalhoRodapé
{
LeftText = "{date} {time}",
RightText = "Page {page} of {total-pages}",
FontSize = 9
};
_renderer.RenderingOptions = renderOptions;
var pdf = await _renderer.RenderHtmlAsPdfAsync(request.HtmlContent);
if (request.RequirePassword)
{
pdf.SecuritySettings.OwnerPassword = request.OwnerPassword;
pdf.SecuritySettings.UserPassword = request.UserPassword;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
}
return File(pdf.BinaryData, "application/pdf", $"{request.FileName}.pdf");
}
[HttpPost("document/secured")]
public async Task<IActionResult> GenerateSecuredDocument([FromBody] SecuredDocRequest request)
{
var renderOptions = new ChromePdfRenderOptions
{
Tamanho do papel = Tamanho do papel PDF.A4,
MarginTop = 45,
MarginBottom = 45,
MarginLeft = 25,
MarginRight = 25,
Habilitar JavaScript = true,
WaitFor = new WaitFor { RenderDelay = 500 }
};
renderOptions.TextHeader = new CabeçalhoRodapé
{
CenterText = request.DocumentTitle,
DrawDividerLine = true,
FontSize = 11
};
renderOptions.TextFooter = new CabeçalhoRodapé
{
LeftText = "{date} {time}",
RightText = "Page {page} of {total-pages}",
FontSize = 9
};
_renderer.RenderingOptions = renderOptions;
var pdf = await _renderer.RenderHtmlAsPdfAsync(request.HtmlContent);
if (request.RequirePassword)
{
pdf.SecuritySettings.OwnerPassword = request.OwnerPassword;
pdf.SecuritySettings.UserPassword = request.UserPassword;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
}
return File(pdf.BinaryData, "application/pdf", $"{request.FileName}.pdf");
}
Imports Microsoft.AspNetCore.Mvc
<HttpPost("document/secured")>
Public Async Function GenerateSecuredDocument(<FromBody> request As SecuredDocRequest) As Task(Of IActionResult)
Dim renderOptions As New ChromePdfRenderOptions With {
.PaperSize = PdfPaperSize.A4,
.MarginTop = 45,
.MarginBottom = 45,
.MarginLeft = 25,
.MarginRight = 25,
.EnableJavaScript = True,
.WaitFor = New WaitFor With {.RenderDelay = 500}
}
renderOptions.TextHeader = New HeaderFooter With {
.CenterText = request.DocumentTitle,
.DrawDividerLine = True,
.FontSize = 11
}
renderOptions.TextFooter = New HeaderFooter With {
.LeftText = "{date} {time}",
.RightText = "Page {page} of {total-pages}",
.FontSize = 9
}
_renderer.RenderingOptions = renderOptions
Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(request.HtmlContent)
If request.RequirePassword Then
pdf.SecuritySettings.OwnerPassword = request.OwnerPassword
pdf.SecuritySettings.UserPassword = request.UserPassword
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint
pdf.SecuritySettings.AllowUserCopyPasteContent = False
End If
Return File(pdf.BinaryData, "application/pdf", $"{request.FileName}.pdf")
End Function
A configuração WaitFor.RenderDelay é particularmente útil quando seu HTML inclui bibliotecas de gráficos como Chart.js ou ApexCharts, que terminam de desenhar de forma assíncrona. Definir um atraso de 300 a 500 ms garante que o Chromium capture o estado final renderizado. Para documentos que precisam atender aos padrões de arquivamento, combine a abordagem acima com a conformidade com PDF/A e assinaturas digitais .
Os tokens {page} e {total-pages} no texto do rodapé são resolvidos automaticamente pelo IronPDF durante a renderização. Opções adicionais de cabeçalho e rodapé incluem cabeçalhos baseados em HTML para posicionamento de logotipo e recursos de personalização por seção.
Quais opções de renderização estão disponíveis?
A tabela abaixo resume as propriedades ChromePdfRenderOptions mais úteis para geração em tempo real:
| Propriedade | Tipo | Propósito |
|---|---|---|
| Tamanho do papel | Tamanho do papel PDF | Define as dimensões da página (A4, Carta, Ofício, personalizadas) |
| MargemSuperior / MargemInferior | int (mm) | Controla o espaçamento da área imprimível. |
| Habilitar JavaScript | booleano | Permite a execução de JS antes da captura. |
| WaitFor.RenderDelay | int (ms) | Captura de atrasos para renderização assíncrona |
| Cabeçalho de texto / Rodapé de texto | CabeçalhoRodapé | Cabeçalhos e rodapés de página em execução |
| Cabeçalho HTML / Rodapé HTML | CabeçalhoHtmlRodapé | Cabeçalhos/rodapés formatados em HTML com imagens |
| Escala de cinza | booleano | Gera PDF monocromático |
| Ajustar à largura do papel | booleano | Dimensiona o conteúdo amplo para caber na página. |
Quais são as melhores práticas de desempenho para geração de PDFs em grande volume?
Quando um único servidor lida com centenas de solicitações simultâneas de PDFs, algumas decisões arquitetônicas têm um impacto desproporcional na taxa de transferência e na latência.
Registro de renderizador singleton. Conforme mostrado na seção de instalação, registrar ChromePdfRenderer como um singleton no contêiner de injeção de dependência evita o custo de iniciar um novo subprocesso do Chromium por solicitação. De acordo com as diretrizes de desempenho do ASP.NET Core da Microsoft , minimizar a alocação de objetos e reutilizar recursos dispendiosos são as duas otimizações de maior impacto disponíveis.
Use sempre async. RenderHtmlAsPdfAsync retorna um Task<PdfDocument> e suspende a thread do controlador enquanto o Chromium está em execução. Isso libera o pool de threads para lidar com outras solicitações recebidas em paralelo, e é por isso que a documentação do async recomenda essa sobrecarga para servidores web. A sobrecarga síncrona é apropriada apenas para ferramentas de console ou serviços em segundo plano onde o bloqueio de threads é aceitável.
Transmita diretamente, ignorando o array intermediário sempre que possível. Para PDFs grandes, .Stream pode ser escrito diretamente no corpo da resposta sem materializar o array de bytes completo:
[HttpGet("document/large")]
public IActionResult StreamLargeDocument(int documentId)
{
string html = BuildLargeDocumentHtml(documentId);
var pdf = _renderer.RenderHtmlAsPdf(html);
// Stream.Position is already at 0; no seek needed.
return File(pdf.Stream, "application/pdf", $"document-{documentId}.pdf");
}
[HttpGet("document/large")]
public IActionResult StreamLargeDocument(int documentId)
{
string html = BuildLargeDocumentHtml(documentId);
var pdf = _renderer.RenderHtmlAsPdf(html);
// Stream.Position is already at 0; no seek needed.
return File(pdf.Stream, "application/pdf", $"document-{documentId}.pdf");
}
Imports Microsoft.AspNetCore.Mvc
<HttpGet("document/large")>
Public Function StreamLargeDocument(documentId As Integer) As IActionResult
Dim html As String = BuildLargeDocumentHtml(documentId)
Dim pdf = _renderer.RenderHtmlAsPdf(html)
' Stream.Position is already at 0; no seek needed.
Return File(pdf.Stream, "application/pdf", $"document-{documentId}.pdf")
End Function
Descartar após o uso. PdfDocument implementa IDisposable. Envolvê-lo em uma instrução using libera o buffer de memória subjacente imediatamente, o que é importante ao gerar muitos PDFs grandes em sequência:
using var pdf = _renderer.RenderHtmlAsPdf(html);
byte[] data = pdf.BinaryData;
// pdf is disposed here; data is safely copied to the local array.
return File(data, "application/pdf", "output.pdf");
using var pdf = _renderer.RenderHtmlAsPdf(html);
byte[] data = pdf.BinaryData;
// pdf is disposed here; data is safely copied to the local array.
return File(data, "application/pdf", "output.pdf");
Imports System.IO
Using pdf = _renderer.RenderHtmlAsPdf(html)
Dim data As Byte() = pdf.BinaryData
' pdf is disposed here; data is safely copied to the local array.
Return File(data, "application/pdf", "output.pdf")
End Using
Para orientações sobre implantação em nuvem abrangendo ambientes Azure , AWS, Docker e Linux, a documentação do IronPDF fornece notas de configuração específicas para cada ambiente. Se a primeira renderização após a inicialização for lenta, consulte o guia de aquecimento e cache para obter estratégias de pré-inicialização do renderizador antes da chegada da primeira solicitação do usuário.
Como adicionar uma marca d'água a um PDF gerado?
Uma marca d'água de texto ou imagem pode ser adicionada a todas as páginas do documento gerado antes da transmissão:
[HttpGet("document/draft/{id:int}")]
public IActionResult GetDraftDocument(int id)
{
string html = BuildDocumentHtml(id);
var pdf = _renderer.RenderHtmlAsPdf(html);
// Stamp "DRAFT" diagonally across every page.
pdf.ApplyWatermark(
"<h1 style='color:rgba(200,0,0,0.25);transform:rotate(-45deg)'>DRAFT</h1>",
rotation: 45,
opacity: 30
);
return File(pdf.BinaryData, "application/pdf", $"draft-{id}.pdf");
}
[HttpGet("document/draft/{id:int}")]
public IActionResult GetDraftDocument(int id)
{
string html = BuildDocumentHtml(id);
var pdf = _renderer.RenderHtmlAsPdf(html);
// Stamp "DRAFT" diagonally across every page.
pdf.ApplyWatermark(
"<h1 style='color:rgba(200,0,0,0.25);transform:rotate(-45deg)'>DRAFT</h1>",
rotation: 45,
opacity: 30
);
return File(pdf.BinaryData, "application/pdf", $"draft-{id}.pdf");
}
<AttributeUsage(AttributeTargets.Method, Inherited:=True, AllowMultiple:=False)>
Public Class HttpGetAttribute
Inherits Attribute
Public Sub New(route As String)
End Sub
End Class
<HttpGet("document/draft/{id:int}")>
Public Function GetDraftDocument(id As Integer) As IActionResult
Dim html As String = BuildDocumentHtml(id)
Dim pdf = _renderer.RenderHtmlAsPdf(html)
' Stamp "DRAFT" diagonally across every page.
pdf.ApplyWatermark(
"<h1 style='color:rgba(200,0,0,0.25);transform:rotate(-45deg)'>DRAFT</h1>",
rotation:=45,
opacity:=30
)
Return File(pdf.BinaryData, "application/pdf", $"draft-{id}.pdf")
End Function
Para obter informações completas sobre as opções de configuração de marcas d'água, incluindo marcas d'água em imagens e controle por página, consulte a documentação de marcas d'água .
Quais são os seus próximos passos?
A geração dinâmica de PDF no ASP.NET Core segue um padrão consistente: construa seu HTML, chame RenderHtmlAsPdf ou sua sobrecarga assíncrona e retorne o resultado por meio de um FileResult. O IronPDF lida com tudo o que acontece entre esses dois pontos — renderização do Chromium, aplicação de CSS, execução de JavaScript — sem exigir operações de entrada/saída de disco em nenhuma etapa.
A partir daqui, você pode explorar diversas direções, dependendo dos requisitos da sua aplicação. Se seus PDFs precisarem combinar vários documentos de origem, o guia de mesclagem e divisão aborda a união de PDFs existentes com páginas recém-renderizadas. Se você precisar que os usuários preencham e enviem formulários incorporados em um PDF, a documentação de formulários interativos mostra como criar e ler valores de campos. Para setores regulamentados, a conformidade com o padrão PDF/A e a acessibilidade PDF/UA garantem que os documentos atendam aos padrões de arquivamento e acessibilidade.
Se você está avaliando o IronPDF em comparação com outras alternativas, a comparação entre iText e IronPDF oferece uma análise técnica lado a lado. Quando estiver pronto para iniciar a produção, adquira uma licença para desbloquear todos os recursos e obter acesso a suporte técnico prioritário. A documentação completa de referência da API apresenta todas as classes e métodos discutidos neste guia.
Para dúvidas ou problemas durante a implementação, a equipe de suporte de engenharia está disponível para ajudar. Para informações específicas sobre o Blazor Server ou o MAUI, os guias dedicados abordam as diferenças de configuração para cada modelo de host.
Perguntas frequentes
Como posso gerar PDFs dinamicamente no ASP.NET Core?
Você pode usar o IronPDF para gerar PDFs dinamicamente no ASP.NET Core sem precisar salvar os arquivos em disco. Ele permite transmitir PDFs diretamente para os navegadores.
Quais são os benefícios de usar o IronPDF para geração de PDFs?
O IronPDF oferece um poderoso mecanismo de renderização que permite a criação dinâmica de PDFs diretamente em seus projetos .NET Core, garantindo a geração instantânea de PDFs sem a necessidade de armazenamento no servidor.
O IronPDF pode ser usado para criar faturas e relatórios?
Sim, o IronPDF é adequado para criar diversos tipos de documentos, como faturas, relatórios e certificados, todos gerados dinamicamente em aplicações ASP.NET Core.
É necessário armazenamento no servidor ao usar o IronPDF?
Não, o IronPDF permite gerar e transmitir PDFs diretamente para navegadores sem a necessidade de armazenamento no servidor, tornando-o eficiente e rápido.
Que tipo de aplicações podem se beneficiar da geração de PDFs em tempo real?
Aplicações web modernas, especialmente aquelas que exigem a criação de documentos em tempo real, como sistemas de faturamento e ferramentas de geração de relatórios, podem se beneficiar muito da geração de PDFs instantânea oferecida pelo IronPDF.
O IronPDF é compatível com projetos .NET Core?
Sim, o IronPDF é totalmente compatível com projetos .NET Core, permitindo que os desenvolvedores integrem recursos de geração de PDF perfeitamente em seus aplicativos.


