Xamarin PDF生成器:使用IronPDF構建移動PDF應用
在 Xamarin.Forms 中建立 PDF 檔案可能比較棘手。 大多數 .NET PDF 程式庫不直接支援行動應用程序,嘗試在裝置上產生 PDF 文件通常會導致錯誤或功能缺失。 這時IronPDF就派上用場了。
雖然 IronPDF 不能在 Xamarin.Forms 應用程式中原生運行,但伺服器端 API 方法可以很好地彌補這一差距。 您的行動應用程式會向 API 發送 HTML 內容,並接收產生的 PDF 檔案—讓您可以存取專業的 PDF 生成功能,包括表單、頁首、頁尾、圖片和自訂佈局。
重要提示:微軟已於 2024 年 5 月停止對 Xamarin 的支援。對於新項目,建議使用.NET MAUI作為替代方案,它能更直接地支持 IronPDF。 本指南涵蓋了仍在維護中的傳統 Xamarin 專案的伺服器端模式,並解釋了從頭開始的團隊遷移到 MAUI 的路徑。
為什麼伺服器端方法適用於行動裝置 PDF 產生?
IronPDF 擅長將 HTML 內容轉換為精美的 PDF 文檔,並完全支援 CSS、JavaScript 和複雜佈局。 在專用伺服器上執行 IronPDF(而不是在行動應用程式內運行)可以繞過平台限制,從而避免在 iOS 和 Android 裝置上直接渲染 PDF。
伺服器端模式具有以下幾個實際優勢:
-輸出一致:字體、圖像和 CSS 在伺服器端解析,消除了 Android 和 iOS 硬體之間的渲染差異。 -功能存取: IronPDF 的所有功能,如 PDF 表單建立、數位簽章、浮水印和多頁佈局,均可在伺服器上無限制使用。 -更輕的行動應用程式:裝置僅發送 HTTP 請求並儲存返回的 PDF 位元組 - 手機上無需運行繁重的 PDF 引擎。 -集中式授權:一個IronPDF 授權即可覆蓋您的伺服器部署,而無需為每個裝置單獨授權。
Xamarin.Forms 用戶端呼叫 API,接收位元組數組,將其寫入本機存儲,並可選擇開啟 PDF 檢視器。 其他一切都由伺服器處理。
如何設定 IronPDF PDF 生成 API?
首先建立一個 ASP.NET Core Web API 專案。 這是一個標準的 .NET 10 最小 API,您可以將其託管在任何地方——Azure 應用程式服務、AWS、本機伺服器或 Docker 容器。
安裝 IronPDF
您可以使用下列任一指令從 NuGet 安裝 IronPDF :
Install-Package IronPdf
dotnet add package IronPdf
Install-Package IronPdf
dotnet add package IronPdf
建立 PDF 控制器
安裝 IronPDF 後,新增一個接受 HTML 並返回 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 使用基於 Chromium 的引擎來渲染 HTML,就像現代瀏覽器一樣。 HTML 轉 PDF 轉換會保留 CSS 動畫、嵌入式字體、SVG 圖形和 JavaScript 產生的內容。 紙張尺寸和頁邊距設定會直接影響最終文件的版面配置。
新增頁首和頁尾
對於專業文檔,請在呼叫渲染器之前新增頁首和頁尾:
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>"
}
頁碼標記(例如 {page} 和 {total-pages})在渲染時會自動解析。
如何實現 Xamarin 客戶端?
在 Xamarin.Forms 應用程式中,建立一個呼叫 API 的服務類別。 保持服務簡潔——它的唯一任務是序列化 HTML 有效負載,發送它,並將原始 PDF 位元組傳回給呼叫者。
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 秒超時時間可以處理包含大量圖像或 CSS 資源的複雜 HTML 文件。 對於非常大的文件,可以考慮從 API 傳回預先簽署的下載 URL,而不是直接串流二進位檔案——這樣可以保持行動記憶體使用量的可預測性。
如何在裝置上儲存和開啟PDF檔案?
服務返回位元組數組後,將其寫入設備存儲,並在平台 PDF 檢視器中開啟。 Xamarin.Forms 使用 DependencyService 模式來呼叫特定於平台的實作。
在共享程式碼中定義介面:
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
使用 DependencyService 註冊 iOS 實作:
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
對於 Android,寫入應用程式的外部檔案目錄,並在清單中註冊 FileProvider,以便您可以將 URI 傳遞給 PDF 檢視器意圖。 共享程式碼中的 DependencyService.Get<ISaveFile>() 呼叫會在執行時間檢索目前平台註冊的任何實作。
將所有部件連接起來
在 Xamarin.Forms 頁面或 ViewModel 中,將服務和平台保存器結合:
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")
})
這將使用用戶已安裝的任何檢視器開啟已儲存的 PDF 文件,在 iOS 和 Android 上通常是原生 PDF 應用程式。
如何產生專業的發票和報告PDF文件?
PDF檔案的品質幾乎完全取決於傳遞給渲染器的HTML模板的品質。 使用 C# 字串插值或像 Scriban 這樣的模板庫來建立資料驅動的 HTML:
public string BuildInvoiceHtml(Invoice invoice)
{
var rows = string.Join(
"\n",
invoice.項目s.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>項目</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.項目s.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>項目</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.項目s.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>項目</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 會像瀏覽器一樣渲染此範本。 您可以使用IronPDF 的浮水印 API新增浮水印,或為機密草稿套用自訂浮水印設計。 對於需要簽名欄位的文檔, IronPDF 的簽章支援功能可讓您在伺服器端嵌入數位簽章佔位符。
如何在 Xamarin 應用程式中處理 PDF 表單?
PDF 表單是行動商務應用程式的常見需求——合約、入職問捲和檢查清單都可以從預先填寫的可編輯欄位中受益。 伺服器 API 可以接受 HTML 範本中的欄位數據,並在返回 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
行動用戶端發送一個包含欄位名稱和值的字典。 伺服器會填寫這些信息,並傳回一個表單,使用者可以查看該表單,在 PDF 檢視器中填寫任何剩餘字段,然後提交。
如何從 Xamarin 應用程式中提取文字並合併 PDF?
除了產生文件之外,IronPDF 還支援多種文件操作,您可以將其公開為 API 端點:
-從 PDF 中提取文字:解析 PDF 內容以索引文件或預先填入資料輸入表單。 -合併或分割 PDF :將多個報告合併到一個 PDF 中,或將一個大文件分割成按章節的文件。 -將 PDF 轉換為影像:將 PDF 頁面渲染為 PNG 或 JPEG 縮圖,以便在行動 UI 中預覽。
它們各自成為一個獨立的 API 端點。 Xamarin 用戶端像呼叫任何其他 REST 資源一樣呼叫它們,使行動程式碼不包含 PDF 邏輯,並使伺服器成為權威的文件處理器。
常見問題有哪些?如何解決?
伺服器-客戶端架構雖然簡單明了,但有幾個生產環境方面的問題要注意:
| 問題 | 原因 | 建議修正 |
|---|---|---|
| 請求超時 | 包含大量遠端資源的複雜 HTML 程式碼渲染速度較慢。 | 增加HttpClient.Timeout值,並在渲染選項中設定伺服器端渲染逾時時間。 |
| PDF 記憶體佔用激增 | 透過回應正文串流 20 MB 的 PDF 文件 | 上傳到 Blob 儲存空間並傳回短期有效的下載 URL |
| 離線生成 | 當使用者要求 PDF 檔案時,設備沒有網路連線。 | 將請求排隊到本地,並在連線恢復後重試。 |
| 未經授權的 API 訪問 | 端點對網路開放 | 使用 JWT 或 API 金鑰進行安全保護;強制所有路由使用 HTTPS |
| 字體未嵌入 | 伺服器作業系統未安裝字型。 | 將字體以 base64 資料 URI 或 CSS @font-face規則的形式嵌入到 HTML 中 |
| iOS 儲存權限 | 該應用程式針對 iOS 14 及更高版本,並採用更嚴格的沙盒機制。 | 寫入應用程式沙箱內的Environment.SpecialFolder.MyDocuments夾 |
對於速率限制,可以使用AspNetCoreRateLimit等函式庫在 ASP.NET Core 端新增中間件。 記錄每次產生請求的時間數據,以便您在慢速範本影響使用者之前發現它們。
是否應該從 Xamarin 遷移到 .NET MAUI?
如果您計劃在 2026 年啟動一個新的行動項目,那麼 .NET MAUI 是理想之選。微軟已於 2024 年 5 月停止對 Xamarin 的支持,這意味著不會再有安全性修補程式或漏洞修復。 .NET MAUI 是其直接繼任者,運行在 .NET 10 上,與目前的 IronPDF 運行時相符。
本指南中所描述的伺服器端架構同樣適用於 .NET MAUI 應用程式-客戶端 HTTP 程式碼本質上是相同的; 只有 DependencyService 被 MAUI 的內建依賴注入所取代。 維護現有 Xamarin 應用程式的團隊應該計劃遷移到 MAUI; 微軟官方的 .NET MAUI 遷移指南詳細記錄了遷移步驟。
如何在生產環境中部署和授權 IronPDF?
部署非常簡單:使用 Docker 將 ASP.NET Core API 容器化,然後將其推送到 Azure 應用服務、AWS ECS 或任何 Kubernetes 叢集。 IronPDF許可證密鑰已設定為伺服器上的環境變數:
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."))
請查看IronPDF 許可頁面,選擇適合您部署的等級。 免費試用許可證可讓您在購買前測試所有功能。 對於容器化或無伺服器部署,請檢查許可證等級是否涵蓋同時執行的伺服器執行個體數量。
獲得許可後,您可以查閱IronPDF 文檔,以了解高級配置選項,包括線程安全渲染設定、PDF/A 合規性和輔助功能標記。
生產部署檢查清單
| 項目 | 推薦 |
|---|---|
| 許可密鑰 | 儲存在環境變數或金鑰管理員中,切勿儲存在原始程式碼中。 |
| HTTPS | 對所有 API 端點強制執行 TLS;切勿透過純 HTTP 傳送 HTML 負載。 |
| 身份驗證 | 使用 JWT 持有者令牌或 API 金鑰;一旦發生違規行為,立即撤銷。 |
| 快取 | 將相同的 HTML 有效負載快取一個較短的 TTL,以減少冗餘渲染。 |
| 縮放 | IronPDF 是執行緒安全的;可以在負載平衡器後執行多個 API 副本。 |
| 監控 | 追蹤渲染延遲和錯誤率;當數值高於基線時發出警報。 |
伺服器端模式可以水平擴展,而無需對 Xamarin 或 MAUI 用戶端進行任何更改。 隨著 PDF 生成量的增長,增加副本,並依靠負載平衡器均勻分配請求。
常見問題解答
IronPDF 能否在 Xamarin.Forms 中原生使用?
IronPDF 無法在 Xamarin.Forms 中原生運行,但可以透過伺服器端方法集成,以處理 PDF 的建立和操作。
在行動應用中使用 IronPDF 產生 PDF 檔案有哪些好處?
使用 IronPDF,您可以建立 PDF 檔案、填寫表單、處理多頁、新增圖像、字體和自訂佈局,從而增強行動應用程式的 PDF 生成功能。
IronPDF 如何在 Xamarin 中建立 PDF 檔案?
IronPDF 使用伺服器端方法在 Xamarin 中產生 PDF,從而實現行動裝置通常不支援的複雜 PDF 功能。
是否可以使用 Xamarin 中的 IronPDF 來填寫 PDF 表單?
是的,IronPDF 支援填寫 PDF 表單,這是其針對 Xamarin 應用程式的全面 PDF 處理功能的一部分。
IronPDF 解決了 Xamarin PDF 生成的哪些挑戰?
IronPDF 透過使用伺服器端解決方案,解決了在行動裝置上直接產生 PDF 時遇到的錯誤和功能缺失等挑戰。
IronPDF 能否處理 Xamarin 應用程式中 PDF 的自訂佈局?
是的,IronPDF 可以在生成的 PDF 文件中包含自訂佈局,讓您可以控製文件的設計和呈現方式。
在 Xamarin 中使用 IronPDF 可以實現哪些 PDF 功能?
IronPDF 允許在 Xamarin 中實現多頁文件、表單填寫、圖像和字體整合以及自訂佈局等功能。
為什麼建議使用伺服器端方法在 Xamarin 和 IronPDF 中產生 PDF 檔案?
建議採用伺服器端方法,因為它可以繞過行動裝置的限制,確保可靠地建立 PDF 檔案並實現高級功能。



