Gerador de PDF Xamarin: Construa Aplicativos Móveis de PDF com IronPDF
Criar arquivos PDF no Xamarin.Forms pode ser complicado. A maioria das bibliotecas .NET para PDF não oferece suporte direto a aplicativos móveis, e tentar gerar documentos PDF em um dispositivo geralmente resulta em erros ou falta de funcionalidades. É aí que o IronPDF entra em ação.
Embora o IronPDF não seja executado nativamente dentro de um aplicativo Xamarin.Forms, uma abordagem de API do lado do servidor resolve essa questão de forma eficiente. Seu aplicativo móvel envia conteúdo HTML para a API e recebe arquivos PDF finalizados em resposta, dando a você acesso à geração profissional de PDFs, incluindo formulários, cabeçalhos, rodapés, imagens e layouts personalizados.
Nota importante: A Microsoft encerrou o suporte para Xamarin em maio de 2024. Para novos projetos, o .NET MAUI é o sucessor recomendado e oferece suporte mais direto ao IronPDF . Este guia aborda o padrão do lado do servidor para projetos Xamarin legados ainda em manutenção e explica o caminho de migração para o MAUI para equipes que estão começando do zero.
Por que uma abordagem do lado do servidor funciona para a geração de PDFs em dispositivos móveis?
O IronPDF se destaca na conversão de conteúdo HTML em documentos PDF refinados, com suporte completo para CSS, JavaScript e layouts complexos. Executar o IronPDF em um servidor dedicado — em vez de dentro de um aplicativo móvel — contorna as limitações da plataforma que impedem a renderização direta de PDFs em dispositivos iOS e Android.
O padrão de implementação no servidor oferece diversas vantagens concretas:
- Saída consistente: fontes, imagens e CSS são resolvidos no servidor, eliminando as diferenças de renderização entre o hardware Android e iOS.
- Acesso a recursos: Recursos do IronPDF , como criação de formulários PDF, assinaturas digitais, marcas d'água e layouts de várias páginas, estão disponíveis no servidor sem restrições.
- Aplicativo móvel mais leve: o dispositivo apenas envia uma solicitação HTTP e armazena os bytes do PDF retornado — nenhum mecanismo pesado de PDF é executado no telefone.
- Licenciamento centralizado: Uma única licença do IronPDF cobre a implantação do seu servidor, em vez de licenciar cada dispositivo separadamente.
O cliente Xamarin.Forms chama a API, recebe uma matriz de bytes, grava-a no armazenamento local e, opcionalmente, abre um visualizador de PDF. O servidor cuida de todo o resto.
Como configurar uma API de geração de PDFs do IronPDF ?
Comece criando um projeto de API Web ASP.NET Core . Esta é uma API mínima padrão do .NET 10 que você pode hospedar em qualquer lugar: Azure App Service, AWS, um servidor local ou um contêiner Docker.
Instale o IronPDF
Instale o IronPDF a partir do NuGet usando um destes comandos:
Install-Package IronPdf
dotnet add package IronPdf
Install-Package IronPdf
dotnet add package IronPdf
Criar o controlador de PDF
Com o IronPDF instalado, adicione um controlador que aceite HTML e retorne um PDF:
using IronPdf;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
namespace PdfGenerationApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
[HttpPost("generate")]
public async Task<IActionResult> GeneratePdf([FromBody] PdfRequest request)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = await renderer.RenderHtmlAsPdfAsync(request.HtmlContent);
return File(pdf.BinaryData, "application/pdf", "document.pdf");
}
}
public class PdfRequest
{
public string HtmlContent { get; set; } = string.Empty;
}
}
using IronPdf;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();
namespace PdfGenerationApi.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
[HttpPost("generate")]
public async Task<IActionResult> GeneratePdf([FromBody] PdfRequest request)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = await renderer.RenderHtmlAsPdfAsync(request.HtmlContent);
return File(pdf.BinaryData, "application/pdf", "document.pdf");
}
}
public class PdfRequest
{
public string HtmlContent { get; set; } = string.Empty;
}
}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc
Dim builder = WebApplication.CreateBuilder(args)
builder.Services.AddControllers()
Dim app = builder.Build()
app.MapControllers()
app.Run()
Namespace PdfGenerationApi.Controllers
<ApiController>
<Route("api/[controller]")>
Public Class PdfController
Inherits ControllerBase
<HttpPost("generate")>
Public Async Function GeneratePdf(<FromBody> request As PdfRequest) As Task(Of IActionResult)
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 25
renderer.RenderingOptions.MarginBottom = 25
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(request.HtmlContent)
Return File(pdf.BinaryData, "application/pdf", "document.pdf")
End Function
End Class
Public Class PdfRequest
Public Property HtmlContent As String = String.Empty
End Class
End Namespace
ChromePdfRenderer usa um mecanismo baseado no Chromium para renderizar HTML exatamente como um navegador moderno faria. A conversão de HTML para PDF respeita animações CSS, fontes incorporadas, gráficos SVG e conteúdo gerado por JavaScript. As configurações de tamanho do papel e margens são diretamente refletidas no layout final do documento.
Adicionar cabeçalhos e rodapés
Para documentos profissionais, adicione cabeçalhos e rodapés antes de chamar o renderizador:
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:right; font-size:12px; color:#555;'>Confidential -- Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:center; font-size:11px;'>Generated by MyCompany App</div>"
};
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:right; font-size:12px; color:#555;'>Confidential -- Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:center; font-size:11px;'>Generated by MyCompany App</div>"
};
Imports System
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='text-align:right; font-size:12px; color:#555;'>Confidential -- Page {page} of {total-pages}</div>",
.DrawDividerLine = True
}
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='text-align:center; font-size:11px;'>Generated by MyCompany App</div>"
}
Os tokens de número de página, como {page} e {total-pages}, são resolvidos automaticamente no momento da renderização.
Como implementar o cliente Xamarin?
No aplicativo Xamarin.Forms, crie uma classe de serviço que chame a API. Mantenha o serviço enxuto — sua única função é serializar a carga útil HTML, enviá-la e retornar os bytes brutos do PDF para o solicitante.
using System.Net.Http;
using System.Text;
using System.Text.Json;
namespace XamarinPdfApp.Services
{
public class PdfService
{
private readonly HttpClient _httpClient;
private const string ApiUrl = "https://your-api.example.com/api/pdf/generate";
public PdfService()
{
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(60)
};
}
public async Task<byte[]> GeneratePdfAsync(string htmlContent)
{
var payload = new { HtmlContent = htmlContent };
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(ApiUrl, content);
if (response.IsSuccessStatusCode)
return await response.Content.ReadAsByteArrayAsync();
var error = await response.Content.ReadAsStringAsync();
throw new InvalidOperationException($"PDF generation failed ({(int)response.StatusCode}): {error}");
}
}
}
using System.Net.Http;
using System.Text;
using System.Text.Json;
namespace XamarinPdfApp.Services
{
public class PdfService
{
private readonly HttpClient _httpClient;
private const string ApiUrl = "https://your-api.example.com/api/pdf/generate";
public PdfService()
{
_httpClient = new HttpClient
{
Timeout = TimeSpan.FromSeconds(60)
};
}
public async Task<byte[]> GeneratePdfAsync(string htmlContent)
{
var payload = new { HtmlContent = htmlContent };
var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(ApiUrl, content);
if (response.IsSuccessStatusCode)
return await response.Content.ReadAsByteArrayAsync();
var error = await response.Content.ReadAsStringAsync();
throw new InvalidOperationException($"PDF generation failed ({(int)response.StatusCode}): {error}");
}
}
}
Imports System.Net.Http
Imports System.Text
Imports System.Text.Json
Namespace XamarinPdfApp.Services
Public Class PdfService
Private ReadOnly _httpClient As HttpClient
Private Const ApiUrl As String = "https://your-api.example.com/api/pdf/generate"
Public Sub New()
_httpClient = New HttpClient With {
.Timeout = TimeSpan.FromSeconds(60)
}
End Sub
Public Async Function GeneratePdfAsync(htmlContent As String) As Task(Of Byte())
Dim payload = New With {Key .HtmlContent = htmlContent}
Dim json = JsonSerializer.Serialize(payload)
Dim content = New StringContent(json, Encoding.UTF8, "application/json")
Dim response = Await _httpClient.PostAsync(ApiUrl, content)
If response.IsSuccessStatusCode Then
Return Await response.Content.ReadAsByteArrayAsync()
End If
Dim error = Await response.Content.ReadAsStringAsync()
Throw New InvalidOperationException($"PDF generation failed ({CInt(response.StatusCode)}): {error}")
End Function
End Class
End Namespace
Um tempo limite de 60 segundos é adequado para documentos HTML complexos com muitas imagens ou recursos CSS. Para arquivos muito grandes, considere retornar um URL de download pré-assinado da API em vez de transmitir o binário diretamente — isso mantém o uso de memória móvel previsível.
Como salvar e abrir arquivos PDF no dispositivo?
Assim que o serviço retornar a matriz de bytes, grave-a no armazenamento do dispositivo e abra-a no visualizador de PDF da plataforma. O Xamarin.Forms usa o padrão DependencyService para chamar implementações específicas da plataforma.
Defina a interface no código compartilhado:
using System.Threading.Tasks;
namespace XamarinPdfApp.Interfaces
{
public interface ISaveFile
{
Task<string> SavePdfAsync(string filename, byte[] pdfData);
}
}
using System.Threading.Tasks;
namespace XamarinPdfApp.Interfaces
{
public interface ISaveFile
{
Task<string> SavePdfAsync(string filename, byte[] pdfData);
}
}
Imports System.Threading.Tasks
Namespace XamarinPdfApp.Interfaces
Public Interface ISaveFile
Function SavePdfAsync(filename As String, pdfData As Byte()) As Task(Of String)
End Interface
End Namespace
Registre a implementação do iOS usando DependencyService:
using Foundation;
using QuickLook;
using UIKit;
using XamarinPdfApp.Interfaces;
using Xamarin.Forms;
[assembly: Dependency(typeof(XamarinPdfApp.iOS.SaveFileIOS))]
namespace XamarinPdfApp.iOS
{
public class SaveFileIOS : ISaveFile
{
public async Task<string> SavePdfAsync(string filename, byte[] pdfData)
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var filePath = System.IO.Path.Combine(documents, filename);
await System.IO.File.WriteAllBytesAsync(filePath, pdfData);
return filePath;
}
}
}
using Foundation;
using QuickLook;
using UIKit;
using XamarinPdfApp.Interfaces;
using Xamarin.Forms;
[assembly: Dependency(typeof(XamarinPdfApp.iOS.SaveFileIOS))]
namespace XamarinPdfApp.iOS
{
public class SaveFileIOS : ISaveFile
{
public async Task<string> SavePdfAsync(string filename, byte[] pdfData)
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var filePath = System.IO.Path.Combine(documents, filename);
await System.IO.File.WriteAllBytesAsync(filePath, pdfData);
return filePath;
}
}
}
Imports Foundation
Imports QuickLook
Imports UIKit
Imports XamarinPdfApp.Interfaces
Imports Xamarin.Forms
<Assembly: Dependency(GetType(XamarinPdfApp.iOS.SaveFileIOS))>
Namespace XamarinPdfApp.iOS
Public Class SaveFileIOS
Implements ISaveFile
Public Async Function SavePdfAsync(filename As String, pdfData As Byte()) As Task(Of String) Implements ISaveFile.SavePdfAsync
Dim documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Dim filePath = System.IO.Path.Combine(documents, filename)
Await System.IO.File.WriteAllBytesAsync(filePath, pdfData)
Return filePath
End Function
End Class
End Namespace
Para Android, escreva no diretório de arquivos externos do aplicativo e registre um FileProvider no manifesto para que você possa passar o URI para uma intent do visualizador de PDF. A chamada DependencyService.Get<ISaveFile>() no código compartilhado recupera qualquer implementação que esteja registrada para a plataforma atual em tempo de execução.
Conectando tudo
Na sua página Xamarin.Forms ou ViewModel, combine o serviço e o protetor de plataforma:
var htmlContent = BuildInvoiceHtml(invoice);
var pdfBytes = await _pdfService.GeneratePdfAsync(htmlContent);
var saver = DependencyService.Get<ISaveFile>();
var filePath = await saver.SavePdfAsync("invoice.pdf", pdfBytes);
await Launcher.OpenAsync(new OpenFileRequest
{
File = new ReadOnlyFile(filePath, "application/pdf")
});
var htmlContent = BuildInvoiceHtml(invoice);
var pdfBytes = await _pdfService.GeneratePdfAsync(htmlContent);
var saver = DependencyService.Get<ISaveFile>();
var filePath = await saver.SavePdfAsync("invoice.pdf", pdfBytes);
await Launcher.OpenAsync(new OpenFileRequest
{
File = new ReadOnlyFile(filePath, "application/pdf")
});
Dim htmlContent = BuildInvoiceHtml(invoice)
Dim pdfBytes = Await _pdfService.GeneratePdfAsync(htmlContent)
Dim saver = DependencyService.Get(Of ISaveFile)()
Dim filePath = Await saver.SavePdfAsync("invoice.pdf", pdfBytes)
Await Launcher.OpenAsync(New OpenFileRequest With {
.File = New ReadOnlyFile(filePath, "application/pdf")
})
Isso abre o PDF salvo no visualizador que o usuário tiver instalado, que normalmente é um aplicativo nativo de PDF tanto no iOS quanto no Android.
Como gerar PDFs de faturas e relatórios profissionais?
A qualidade de um PDF depende quase inteiramente da qualidade do modelo HTML passado para o renderizador. Utilize a interpolação de strings em C# ou uma biblioteca de templates como o Scriban para criar HTML orientado a dados:
public string BuildInvoiceHtml(Invoice invoice)
{
var rows = string.Join(
"\n",
invoice.Items.Select(i =>
$"<tr><td>{i.Name}</td><td>{i.Quantity}</td><td>${i.UnitPrice:F2}</td><td>${i.Total:F2}</td></tr>"
)
);
return $@"<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<style>
body {{ font-family: Arial, sans-serif; color: #333; margin: 0; padding: 30px; }}
h1 {{ color: #1a73e8; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
th {{ background: #1a73e8; color: #fff; padding: 10px; text-align: left; }}
td {{ padding: 10px; border-bottom: 1px solid #e0e0e0; }}
.total {{ font-weight: bold; font-size: 1.1em; text-align: right; margin-top: 15px; }}
</style>
</head>
<body>
<h1>Invoice #{invoice.Number}</h1>
<p>Date: {invoice.Date:yyyy-MM-dd} | Due: {invoice.DueDate:yyyy-MM-dd}</p>
<p>Bill to: <strong>{invoice.ClientName}</strong></p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Total</th></tr></thead>
<tbody>{rows}</tbody>
</table>
<p class='total'>Grand Total: ${invoice.GrandTotal:F2}</p>
</body>
</html>";
}
public string BuildInvoiceHtml(Invoice invoice)
{
var rows = string.Join(
"\n",
invoice.Items.Select(i =>
$"<tr><td>{i.Name}</td><td>{i.Quantity}</td><td>${i.UnitPrice:F2}</td><td>${i.Total:F2}</td></tr>"
)
);
return $@"<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<style>
body {{ font-family: Arial, sans-serif; color: #333; margin: 0; padding: 30px; }}
h1 {{ color: #1a73e8; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
th {{ background: #1a73e8; color: #fff; padding: 10px; text-align: left; }}
td {{ padding: 10px; border-bottom: 1px solid #e0e0e0; }}
.total {{ font-weight: bold; font-size: 1.1em; text-align: right; margin-top: 15px; }}
</style>
</head>
<body>
<h1>Invoice #{invoice.Number}</h1>
<p>Date: {invoice.Date:yyyy-MM-dd} | Due: {invoice.DueDate:yyyy-MM-dd}</p>
<p>Bill to: <strong>{invoice.ClientName}</strong></p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Total</th></tr></thead>
<tbody>{rows}</tbody>
</table>
<p class='total'>Grand Total: ${invoice.GrandTotal:F2}</p>
</body>
</html>";
}
Imports System
Imports System.Linq
Public Function BuildInvoiceHtml(invoice As Invoice) As String
Dim rows = String.Join(
vbLf,
invoice.Items.Select(Function(i)
$"<tr><td>{i.Name}</td><td>{i.Quantity}</td><td>${i.UnitPrice:F2}</td><td>${i.Total:F2}</td></tr>"
)
)
Return $"
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<style>
body {{ font-family: Arial, sans-serif; color: #333; margin: 0; padding: 30px; }}
h1 {{ color: #1a73e8; }}
table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
th {{ background: #1a73e8; color: #fff; padding: 10px; text-align: left; }}
td {{ padding: 10px; border-bottom: 1px solid #e0e0e0; }}
.total {{ font-weight: bold; font-size: 1.1em; text-align: right; margin-top: 15px; }}
</style>
</head>
<body>
<h1>Invoice #{invoice.Number}</h1>
<p>Date: {invoice.Date:yyyy-MM-dd} | Due: {invoice.DueDate:yyyy-MM-dd}</p>
<p>Bill to: <strong>{invoice.ClientName}</strong></p>
<table>
<thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Total</th></tr></thead>
<tbody>{rows}</tbody>
</table>
<p class='total'>Grand Total: ${invoice.GrandTotal:F2}</p>
</body>
</html>"
End Function
O ChromePdfRenderer renderiza este modelo exatamente como um navegador faria. Você pode adicionar marcas d'água usando a API de marcas d'água do IronPDF ou aplicar designs de marcas d'água personalizados para rascunhos confidenciais. Para documentos que exigem um campo de assinatura, o suporte à assinatura do IronPDF permite incorporar marcadores de assinatura digital no servidor.
Como lidar com formulários PDF em um aplicativo Xamarin?
Formulários em PDF são um requisito comum para aplicativos móveis de negócios — contratos, questionários de integração e listas de verificação de inspeção se beneficiam de campos editáveis pré-preenchidos. A API do servidor pode aceitar dados de campos juntamente com o modelo HTML e incorporar valores de formulário antes de retornar o PDF:
[HttpPost("form")]
public async Task<IActionResult> GenerateForm([FromBody] FormRequest request)
{
var renderer = new ChromePdfRenderer();
// Render an HTML form template to create an interactive PDF form
var pdf = await renderer.RenderHtmlAsPdfAsync(request.HtmlTemplate);
// Fill known values before returning
var form = pdf.Form;
foreach (var field in request.FieldValues)
{
var pdfField = form.Fields.FirstOrDefault(f => f.Name == field.Key);
if (pdfField is IronPdf.Forms.PdfFormTextFieldField textField)
textField.Value = field.Value;
}
return File(pdf.BinaryData, "application/pdf", "form.pdf");
}
[HttpPost("form")]
public async Task<IActionResult> GenerateForm([FromBody] FormRequest request)
{
var renderer = new ChromePdfRenderer();
// Render an HTML form template to create an interactive PDF form
var pdf = await renderer.RenderHtmlAsPdfAsync(request.HtmlTemplate);
// Fill known values before returning
var form = pdf.Form;
foreach (var field in request.FieldValues)
{
var pdfField = form.Fields.FirstOrDefault(f => f.Name == field.Key);
if (pdfField is IronPdf.Forms.PdfFormTextFieldField textField)
textField.Value = field.Value;
}
return File(pdf.BinaryData, "application/pdf", "form.pdf");
}
Imports Microsoft.AspNetCore.Mvc
Imports IronPdf
<HttpPost("form")>
Public Async Function GenerateForm(<FromBody> request As FormRequest) As Task(Of IActionResult)
Dim renderer As New ChromePdfRenderer()
' Render an HTML form template to create an interactive PDF form
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(request.HtmlTemplate)
' Fill known values before returning
Dim form = pdf.Form
For Each field In request.FieldValues
Dim pdfField = form.Fields.FirstOrDefault(Function(f) f.Name = field.Key)
If TypeOf pdfField Is IronPdf.Forms.PdfFormTextFieldField Then
Dim textField = DirectCast(pdfField, IronPdf.Forms.PdfFormTextFieldField)
textField.Value = field.Value
End If
Next
Return File(pdf.BinaryData, "application/pdf", "form.pdf")
End Function
O cliente móvel envia um dicionário com os nomes e valores dos campos. O servidor preenche os campos e retorna um formulário que o usuário pode revisar, completar os campos restantes em um visualizador de PDF e enviar.
Como extrair texto e mesclar PDFs de um aplicativo Xamarin?
Além da geração de documentos, o IronPDF oferece suporte a uma ampla gama de operações que você pode expor como endpoints de API:
- Extrair texto de PDF : Analisar o conteúdo de PDFs para indexar documentos ou preencher previamente formulários de entrada de dados.
- Mesclar ou dividir PDFs : Combine vários relatórios em um único PDF ou divida um documento grande em arquivos por seção.
- Converter PDF em imagem : Renderize páginas de PDF como miniaturas PNG ou JPEG para visualização na interface do usuário móvel.
Cada um deles se torna um endpoint de API separado. O cliente Xamarin os chama como qualquer outro recurso REST, mantendo o código móvel livre da lógica de PDF e o servidor como o processador de documentos autorizado.
Quais são os problemas mais comuns e como resolvê-los?
A arquitetura cliente-servidor é simples, mas vários aspectos relacionados à produção merecem atenção:
| Emitir | Causa | Correção recomendada |
|---|---|---|
| Tempo limite da solicitação | HTML complexo com muitos recursos remotos leva tempo para ser renderizado. | Aumente HttpClient.Timeout e defina o tempo limite de renderização do lado do servidor nas opções de renderização. |
| Pico grande de memória PDF | Transmitindo um PDF de 20 MB através do corpo da resposta. | Faça o upload para o armazenamento de blobs e retorne um URL de download de curta duração. |
| Geração offline | O dispositivo fica sem conectividade quando o usuário solicita um PDF. | Enfileire as solicitações localmente e tente novamente quando a conectividade for restaurada. |
| Acesso não autorizado à API | O endpoint está aberto à internet. | Proteja com JWT ou chave de API; imponha HTTPS em todas as rotas. |
| Fonte não incorporada | O sistema operacional do servidor não tem a fonte instalada. | Incorpore a fonte no HTML como um URI de dados base64 ou como uma regra CSS @font-face . |
| Permissão de armazenamento do iOS | O aplicativo é compatível com iOS 14+ e possui um sistema de isolamento mais rigoroso. | Escreva em Environment.SpecialFolder.MyDocuments dentro do sandbox do aplicativo. |
Para limitar a taxa de requisições, adicione um middleware no lado do ASP.NET Core usando uma biblioteca como o AspNetCoreRateLimit . Registre cada solicitação de geração com dados de tempo para que você possa identificar modelos lentos antes que eles afetem os usuários.
Você deveria migrar do Xamarin para o .NET MAUI?
Se você estiver iniciando um novo projeto mobile em 2026, o .NET MAUI é a escolha certa. A Microsoft encerrou o suporte ao Xamarin em maio de 2024, o que significa que não haverá mais atualizações de segurança ou correções de bugs. O .NET MAUI é o sucessor direto e funciona no .NET 10, sendo compatível com o runtime atual do IronPDF .
A arquitetura do lado do servidor descrita neste guia funciona de forma idêntica para aplicativos .NET MAUI -- o código HTTP do cliente é essencialmente o mesmo; Apenas o DependencyService é substituído pela injeção de dependência integrada do MAUI. As equipes que mantêm aplicativos Xamarin existentes devem planejar uma migração para o MAUI; O guia oficial de migração para .NET MAUI da Microsoft documenta os passos em detalhes.
Como implantar e licenciar o IronPDF para produção?
A implantação é simples: basta conteinerizar a API ASP.NET Core com o Docker e enviá-la para o Azure App Service, AWS ECS ou qualquer cluster Kubernetes. A chave de licença do IronPDF é definida como uma variável de ambiente no servidor:
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY")
?? throw new InvalidOperationException("IronPDF license key not set.");
IronPdf.License.LicenseKey = Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY")
?? throw new InvalidOperationException("IronPDF license key not set.");
Imports System
Imports IronPdf
IronPdf.License.LicenseKey = If(Environment.GetEnvironmentVariable("IRONPDF_LICENSE_KEY"), Throw New InvalidOperationException("IronPDF license key not set."))
Consulte a página de licenciamento do IronPDF para selecionar o nível adequado para sua implementação. Uma licença de avaliação gratuita permite que você teste todos os recursos antes de se comprometer. Para implantações em contêineres ou sem servidor, verifique se o nível de licença cobre o número de instâncias de servidor em execução simultaneamente.
Após a aquisição da licença, explore a documentação do IronPDF para opções de configuração avançadas, incluindo configurações de renderização thread-safe, conformidade com PDF/A e marcação de acessibilidade.
Lista de verificação para implantação em produção
| Item | Recomendação |
|---|---|
| Chave de licença | Armazene em variáveis de ambiente ou em um gerenciador de segredos, nunca no código-fonte. |
| HTTPS | Imponha TLS em todos os endpoints da API; nunca envie payloads HTML por HTTP sem criptografia. |
| Autenticação | Use tokens JWT ou chaves de API; revogue em caso de violação. |
| Armazenamento em cache | Armazene em cache payloads HTML idênticos por um TTL curto para reduzir renderizações redundantes. |
| Escala | IronPDF é thread-safe; execute várias réplicas da API por trás de um balanceador de carga. |
| Monitoramento | Monitore a latência de renderização e as taxas de erro; receba alertas sobre picos acima da linha de base. |
O padrão do lado do servidor se adapta horizontalmente sem qualquer alteração no cliente Xamarin ou MAUI. Adicione réplicas à medida que o volume de geração de PDFs aumenta e conte com o balanceador de carga para distribuir as solicitações uniformemente.
Perguntas frequentes
O IronPDF pode ser usado nativamente no Xamarin.Forms?
O IronPDF não é executado nativamente no Xamarin.Forms, mas pode ser integrado usando uma abordagem do lado do servidor para lidar com a criação e manipulação de PDFs.
Quais são os benefícios de usar o IronPDF para geração de PDFs em aplicativos móveis?
O IronPDF permite criar arquivos PDF, preencher formulários, lidar com várias páginas e incluir imagens, fontes e layouts personalizados, aprimorando os recursos de geração de PDFs dos seus aplicativos móveis.
Como o IronPDF lida com a criação de PDFs no Xamarin?
O IronPDF utiliza uma abordagem do lado do servidor para gerar PDFs em Xamarin, possibilitando funcionalidades complexas de PDF que normalmente não são suportadas em dispositivos móveis.
É possível preencher formulários PDF usando o IronPDF no Xamarin?
Sim, o IronPDF suporta o preenchimento de formulários PDF como parte de seus recursos abrangentes de manipulação de PDF para aplicativos Xamarin.
Quais desafios o IronPDF resolve na geração de PDFs em Xamarin?
O IronPDF resolve problemas como erros e funcionalidades ausentes na geração de PDFs diretamente em dispositivos móveis, utilizando uma solução do lado do servidor.
O IronPDF consegue lidar com layouts personalizados em PDFs para aplicativos Xamarin?
Sim, o IronPDF pode incluir layouts personalizados em PDFs gerados, dando a você controle sobre o design e a apresentação de seus documentos.
Que tipo de funcionalidades de PDF podem ser implementadas no Xamarin usando o IronPDF?
O IronPDF permite a implementação de funcionalidades como documentos com várias páginas, preenchimento de formulários, incorporação de imagens e fontes, e layouts personalizados no Xamarin.
Por que é recomendada uma abordagem do lado do servidor para geração de PDFs em Xamarin com IronPDF?
Recomenda-se uma abordagem do lado do servidor, pois ela contorna as limitações dos dispositivos móveis, garantindo a criação confiável de PDFs e recursos avançados.


