Xamarin PDF Generator: Twórz mobilne aplikacje PDF za pomocą IronPDF
Tworzenie plików PDF w Xamarin.Forms może być trudne. Większość bibliotek .NET do obsługi plików PDF nie obsługuje bezpośrednio aplikacji mobilnych, a próba generowania dokumentów PDF na urządzeniu często prowadzi do błędów lub braku niektórych funkcji. Właśnie tu wkracza IronPDF.
Chociaż IronPDF nie działa natywnie w aplikacji Xamarin.Forms, podejście oparte na API po stronie serwera zgrabnie wypełnia tę lukę. Twoja aplikacja mobilna wysyła treści HTML do API i otrzymuje w zamian gotowe pliki PDF — zapewniając dostęp do profesjonalnego generowania plików PDF, w tym formularzy, nagłówków, stopek, obrazów i niestandardowych układów.
Ważna uwaga: firma Microsoft zakończyła wsparcie dla Xamarin w maju 2024 r. W przypadku nowych projektów zalecanym następcą jest .NET MAUI, który zapewnia bardziej bezpośrednią obsługę IronPDF. Niniejszy przewodnik obejmuje wzorzec po stronie serwera dla starszych projektów Xamarin, które są nadal utrzymywane, oraz wyjaśnia ścieżkę migracji do MAUI dla zespołów rozpoczynających pracę od nowa.
Dlaczego podejście po stronie serwera sprawdza się w przypadku generowania plików PDF na urządzenia mobilne?
IronPDF doskonale radzi sobie z konwersją treści HTML na dopracowane dokumenty PDF z pełną obsługą CSS, JavaScript i złożonych układów. Uruchomienie IronPDF na serwerze dedykowanym — zamiast w aplikacji mobilnej — pozwala ominąć ograniczenia platformy, które uniemożliwiają bezpośrednie renderowanie plików PDF na urządzeniach z systemem iOS i Android.
Wzorzec po stronie serwera oferuje kilka konkretnych zalet:
- Spójny wygląd: czcionki, obrazy i CSS są renderowane po stronie serwera, co eliminuje różnice w wyświetlaniu między urządzeniami z systemem Android i iOS.
- Dostęp do funkcji: Funkcje IronPDF, takie jak tworzenie formularzy PDF, podpisy cyfrowe, znaki wodne i układy wielostronicowe, są dostępne na serwerze bez ograniczeń.
- Lżejsza aplikacja mobilna: Urządzenie wysyła jedynie żądanie HTTP i przechowuje zwrócone bajty pliku PDF — w telefonie nie działa żaden ciężki silnik PDF.
- Scentralizowane licencjonowanie: pojedyncza licencja IronPDF obejmuje wdrożenie na serwerze, zamiast licencjonowania każdego urządzenia osobno.
Klient Xamarin.Forms wywołuje API, odbiera tablicę bajtów, zapisuje ją w lokalnej pamięci i opcjonalnie otwiera przeglądarkę plików PDF. Serwer zajmuje się wszystkim innym.
Jak skonfigurować API generowania plików PDF IronPDF?
Zacznij od utworzenia projektu ASP.NET Core Web API. Jest to standardowy, minimalny interfejs API .NET Standard 10, który można hostować w dowolnym miejscu — w usłudze Azure App Service, AWS, na serwerze lokalnym lub w kontenerze Docker.
Zainstaluj IronPDF
Zainstaluj IronPDF z NuGet, używając jednego z poniższych poleceń:
Install-Package IronPdf
dotnet add package IronPdf
Install-Package IronPdf
dotnet add package IronPdf
Utwórz kontroler PDF
Po zainstalowaniu IronPDF dodaj kontroler, który przyjmuje HTML i zwraca plik 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 wykorzystuje silnik oparty na Chromium, aby renderować HTML dokładnie tak, jak zrobiłaby to nowoczesna przeglądarka. Konwersja HTML do PDF uwzględnia animacje CSS, osadzone czcionki, grafikę SVG oraz treści generowane przez JavaScript. Ustawienia rozmiaru papieru i marginesów mają bezpośredni wpływ na ostateczny układ dokumentu.
Dodaj nagłówki i stopki
W przypadku dokumentów profesjonalnych przed wywołaniem renderera należy dodać nagłówki i stopki:
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>"
}
Tokeny numerów stron, takie jak {page} i {total-pages}, są rozpoznawane automatycznie w momencie renderowania.
Jak wdrożyć klienta Xamarin?
W aplikacji Xamarin.Forms utwórz klasę usługi, która wywołuje API. Usługa powinna być prosta — jej jedynym zadaniem jest serializacja ładunku HTML, wysłanie go i zwrócenie surowych bajtów PDF do wywołującego.
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
60-sekundowy limit czasu pozwala na obsługę złożonych dokumentów HTML zawierających wiele obrazów lub zasobów CSS. W przypadku bardzo dużych plików warto rozważyć zwracanie przez API wstępnie podpisanego adresu URL do pobrania zamiast bezpośredniego przesyłania strumieniowego pliku binarnego — pozwala to zachować przewidywalne zużycie pamięci w urządzeniach mobilnych.
Jak zapisywać i otwierać pliki PDF na urządzeniu?
Gdy usługa zwróci tablicę bajtów, zapisz ją w pamięci urządzenia i otwórz w przeglądarce PDF platformy. Xamarin.Forms używa wzorca DependencyService do wywoływania implementacji specyficznych dla platformy.
Zdefiniuj interfejs w kodzie współdzielonym:
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
Zarejestruj implementację na iOS za pomocą 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
W przypadku systemu Android należy zapisać dane w katalogu plików zewnętrznych aplikacji i zarejestrować FileProvider w manifeście, aby można było przekazać adres URI do intencji przeglądarki plików PDF. Wywołanie DependencyService.Get<ISaveFile>() w kodzie współdzielonym pobiera implementację zarejestrowaną dla bieżącej platformy w czasie wykonywania.
Łączenie wszystkich elementów
Na stronie Xamarin.Forms lub w ViewModel połącz usługę z platformą saver:
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")
})
Powoduje to otwarcie zapisanego pliku PDF w przeglądarce zainstalowanej przez użytkownika, którą zazwyczaj jest natywna aplikacja do obsługi plików PDF na systemach iOS i Android.
Jak generować profesjonalne pliki PDF z fakturami i raportami?
Jakość pliku PDF zależy prawie wyłącznie od jakości szablonu HTML przekazanego do renderera. Użyj interpolacji ciągów znaków w języku C# lub biblioteki szablonów, takiej jak Scriban, do tworzenia kodu HTML opartego na danych:
public string BuildInvoiceHtml(Invoice invoice)
{
var rows = string.Join(
"\n",
invoice.Elements.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>Element</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.Elements.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>Element</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.Elements.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>Element</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
ChromePdfRenderer wyświetla ten szablon dokładnie tak, jak zrobiłaby to przeglądarka. Możesz dodawać znaki wodne za pomocą interfejsu API IronPDF do znaków wodnych lub stosować niestandardowe projekty znaków wodnych w przypadku poufnych wersji roboczych. W przypadku dokumentów wymagających pola podpisu funkcja podpisu IronPDF umożliwia osadzenie symboli zastępczych podpisu cyfrowego po stronie serwera.
Jak obsługiwać formularze PDF w aplikacji Xamarin?
Formularze PDF są powszechnym wymaganiem w mobilnych aplikacjach biznesowych — umowy, kwestionariusze rejestracyjne i listy kontrolne z inspekcji zyskują dzięki wstępnie wypełnionym, edytowalnym polom. Interfejs API serwera może przyjmować dane pól wraz z szablonem HTML i osadzać wartości formularza przed zwróceniem pliku 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
Klient mobilny wysyła słownik nazw pól i wartości. Serwer wypełnia je i zwraca formularz, który użytkownik może przejrzeć, uzupełnić pozostałe pola w przeglądarce PDF i przesłać.
Jak wyodrębnić tekst i połączyć pliki PDF z aplikacji Xamarin?
Oprócz generowania dokumentów IronPDF obsługuje szeroki zakres operacji na dokumentach, które można udostępnić jako punkty końcowe API:
- Wyodrębnianie tekstu z plików PDF: analizowanie zawartości plików PDF w celu indeksowania dokumentów lub wstępnego wypełniania formularzy.
- Łączenie lub dzielenie plików PDF: Łączenie wielu raportów w jeden plik PDF lub dzielenie dużego dokumentu na pliki po sekcjach.
- Konwersja plików PDF na obrazy: renderowanie stron PDF jako miniatur w formacie PNG lub JPEG w celu podglądu w interfejsie użytkownika na urządzeniach mobilnych.
Każdy z nich staje się oddzielnym punktem końcowym API. Klient Xamarin wywołuje je tak jak każdy inny zasób REST, dzięki czemu kod mobilny jest wolny od logiki PDF, a serwer pozostaje głównym procesorem dokumentów.
Jakie są typowe problemy i jak je rozwiązać?
Architektura serwer-klient jest prosta, ale należy zwrócić uwagę na kilka kwestii związanych z produkcją:
| Problem | Przyczyna | Zalecana poprawka |
|---|---|---|
| Przekroczono limit czasu żądania | Renderowanie złożonego kodu HTML z wieloma zasobami zdalnymi zajmuje dużo czasu | Zwiększ wartość HttpClient.Timeout i ustaw limit czasu renderowania po stronie serwera w opcjach renderowania |
| Duży skok zużycia pamięci przez pliki PDF | Przesyłanie strumieniowe pliku PDF o rozmiarze 20 MB w treści odpowiedzi | Prześlij do magazynu obiektów blob i zwróć krótkotrwały adres URL do pobrania |
| Generowanie w trybie offline | Urządzenie nie ma połączenia, gdy użytkownik żąda pliku PDF | Lokalne kolejkowanie żądań i ponowne próby po przywróceniu łączności |
| Nieautoryzowany dostęp do API | Punkt końcowy jest otwarty na Internet | Zabezpiecz za pomocą JWT lub klucza API; wymuś HTTPS na wszystkich trasach |
| Czcionka nie jest osadzona | W systemie operacyjnym serwera nie ma zainstalowanej czcionki | Osadź czcionkę w kodzie HTML jako URI danych base64 lub jako regułę CSS @font-face |
| Uprawnienia do pamięci w systemie iOS | Aplikacja jest przeznaczona dla systemu iOS 14+ z bardziej restrykcyjnym sandboxingiem | Zapisz do Środowisko.SpecialFolder.MyDocuments wewnątrz piaskownicy aplikacji |
W celu ograniczenia szybkości dodaj oprogramowanie pośredniczące po stronie .NET Core, korzystając z biblioteki takiej jak AspNetCoreRateLimit. Rejestruj każde żądanie generowania wraz z danymi dotyczącymi czasu, abyś mógł wykryć wolno działające szablony, zanim wpłyną one na użytkowników.
Czy warto przejść z Xamarin na .NET MAUI?
Jeśli w 2026 r. rozpoczynasz nowy projekt mobilny, .NET MAUI to właściwy wybór. Firma Microsoft zakończyła wsparcie dla Xamarin w maju 2024 r., co oznacza brak dalszych poprawek bezpieczeństwa i napraw błędów. .NET MAUI jest bezpośrednim następcą i działa na platformie .NET 10, co odpowiada aktualnemu środowisku uruchomieniowemu IronPDF.
Architektura po stronie serwera opisana w tym przewodniku działa identycznie w przypadku aplikacji .NET MAUI — kod HTTP klienta jest zasadniczo taki sam; tylko DependencyService jest zastępowane przez wbudowaną w MAUI funkcję wstrzykiwania zależności. Zespoły zajmujące się utrzymaniem istniejących aplikacji Xamarin powinny zaplanować migrację do MAUI; Oficjalny przewodnik Microsoftu dotyczący migracji do .NET MAUI szczegółowo opisuje poszczególne kroki.
Jak wdrożyć i uzyskać licencję na IronPDF do użytku produkcyjnego?
Wdrożenie jest proste: wystarczy skontainerować interfejs API .NET Core za pomocą Docker i przesłać go do usługi Azure App Service, AWS ECS lub dowolnego klastra Kubernetes. Klucz licencyjny IronPDF jest ustawiony jako zmienna środowiskowa na serwerze:
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."))
Zapoznaj się ze stroną dotyczącą licencji IronPDF, aby wybrać odpowiedni poziom licencji dla swojego wdrożenia. Bezpłatna licencja próbna pozwala przetestować pełen zestaw funkcji przed podjęciem decyzji o zakupie. W przypadku wdrożeń kontenerowych lub bezserwerowych należy sprawdzić, czy poziom licencji obejmuje liczbę instancji serwerów działających jednocześnie.
Po uzyskaniu licencji zapoznaj się z dokumentacją IronPDF, aby poznać zaawansowane opcje konfiguracyjne, w tym ustawienia renderowania bezpieczne dla wątków, zgodność z PDF/A oraz tagowanie dostępności.
Lista kontrolna wdrożenia produkcyjnego
| Element | Zalecenie |
|---|---|
| Klucz licencyjny | Przechowuj w zmiennych środowiskowych lub menedżerze sekretów, nigdy w kodzie źródłowym |
| HTTPS | Wymuszaj TLS na wszystkich punktach końcowych API; nigdy nie wysyłaj ładunków HTML przez zwykły protokół HTTP |
| Uwierzytelnianie | Używaj tokenów JWT typu bearer lub kluczy API; w przypadku naruszenia bezpieczeństwa cofnij uprawnienia |
| Buforowanie | Buforuj identyczne dane HTML z krótkim czasem życia (TTL), aby ograniczyć zbędne renderowanie |
| Skalowanie | IronPDF jest bezpieczny dla wątków; uruchamiaj wiele replik API za modułem równoważenia obciążenia |
| Monitorowanie | Śledź opóźnienia renderowania i wskaźniki błędów; ostrzegaj o skokach powyżej poziomu bazowego |
Wzorzec po stronie serwera skaluje się horyzontalnie bez żadnych zmian w kliencie Xamarin lub MAUI. Dodawaj repliki w miarę wzrostu liczby generowanych plików PDF i polegaj na modułach równoważenia obciążenia, aby równomiernie rozdzielać żądania.
Często Zadawane Pytania
Czy IronPDF może być używany natywnie w Xamarin.Forms?
IronPDF nie działa natywnie w Xamarin.Forms, ale można go zintegrować przy użyciu podejścia po stronie serwera w celu obsługi tworzenia i manipulacji plikami PDF.
Jakie są zalety korzystania z IronPDF do generowania plików PDF w aplikacjach mobilnych?
Korzystanie z IronPDF pozwala tworzyć pliki PDF, wypełniać formularze, obsługiwać wiele stron oraz dodawać obrazy, czcionki i niestandardowe układy, zwiększając możliwości generowania plików PDF w aplikacjach mobilnych.
W jaki sposób IronPDF obsługuje tworzenie plików PDF w Xamarin?
IronPDF wykorzystuje podejście po stronie serwera do generowania plików PDF w Xamarin, umożliwiając korzystanie ze złożonych funkcji PDF, które zazwyczaj nie są obsługiwane na urządzeniach mobilnych.
Czy w Xamarin można wypełniać formularze PDF za pomocą IronPDF?
Tak, IronPDF obsługuje wypełnianie formularzy PDF w ramach swoich kompleksowych funkcji obsługi plików PDF dla aplikacji Xamarin.
Jakie wyzwania rozwiązuje IronPDF w zakresie generowania plików PDF w Xamarin?
IronPDF rozwiązuje problemy, takie jak błędy i brakujące funkcje podczas generowania plików PDF bezpośrednio na urządzeniach mobilnych, wykorzystując rozwiązanie po stronie serwera.
Czy IronPDF obsługuje niestandardowe układy w plikach PDF dla aplikacji Xamarin?
Tak, IronPDF może uwzględniać niestandardowe układy w generowanych plikach PDF, dając Ci kontrolę nad projektem i wyglądem dokumentów.
Jakie funkcje PDF można zaimplementować w Xamarin przy użyciu IronPDF?
IronPDF umożliwia wdrażanie w Xamarin takich funkcji, jak dokumenty wielostronicowe, wypełnianie formularzy, wbudowywanie obrazów i czcionek oraz niestandardowe układy.
Dlaczego w przypadku generowania plików PDF w Xamarin przy użyciu IronPDF zaleca się podejście po stronie serwera?
Zalecane jest podejście po stronie serwera, ponieważ pozwala ono ominąć ograniczenia urządzeń mobilnych, zapewniając niezawodne tworzenie plików PDF i zaawansowane funkcje.




