跳至頁尾內容
使用IRONPDF

如何使用ASP.NET C#和IronPDF在新窗口中打開PDF

在Xamarin.Forms中建立PDF檔案可能會很棘手。 .NET大多數PDF程式庫不直接支持移動應用程式,並且嘗試在裝置上生成PDF文件通常會導致錯誤或缺少功能。 這就是IronPDF介入的地方。

雖然IronPDF無法直接在Xamarin.Forms應用程式中運行,但伺服器端API方法清楚地彌補了這一缺口。 您的移動應用程式將HTML內容發送到API,並接收完成的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 License涵蓋您的伺服器部署,而不是分別授權每臺裝置。

Xamarin.Forms客戶端呼叫API,接收位元組陣列,將其寫入本地儲存,然後可選地打開PDF檢視器。 伺服器處理其他的所有任務。

如何設置IronPDF PDF生成API?

首先建立一個ASP.NET Core Web API專案。 這是一個標準的.NET 10最小API,你可以在任何地方託管——Azure App Service、AWS、本地伺服器,或Docker容器中。

安裝IronPDF

使用以下命令安裝IronPDF from NuGet

Install-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
$vbLabelText   $csharpLabel

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>"
}
$vbLabelText   $csharpLabel

{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
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

使用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
$vbLabelText   $csharpLabel

對於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")
})
$vbLabelText   $csharpLabel

這將在使用者已安裝的任何檢視器中打開保存的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} &nbsp;|&nbsp; 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} &nbsp;|&nbsp; 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>";
}
Option Strict On



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} &nbsp;|&nbsp; 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
$vbLabelText   $csharpLabel

ChromePdfRenderer將這個模板精確地渲染成現代瀏覽器。 您可以使用IronPDF 的水印API自訂水印設計為保密草稿新增水印。 對於需要簽名欄位的文件,IronPDF 的簽名支持讓您可以在伺服器端嵌入數位簽名佔位符。

如何在Xamarin應用中處理PDF表單?

PDF 表單是移動商務應用的常見要求——合同、入職問卷、檢查清單都受益於預填的可編輯欄位。 伺服器API可以在返回PDF之前接受字段資料與HTML模板一起,並嵌入表單值:

[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
$vbLabelText   $csharpLabel

移動客戶端發送包含字段名稱和值的字典。 伺服器填充它們,然後返回一個使用者可以在PDF檢視器中查看的表單,完成任何剩餘的欄位並提交。

如何從Xamarin應用中提取文字和合併PDF?

除了生成外,IronPDF還支持您可以作為API端點公開的廣泛的文件操作:

  • 從PDF提取文字 解析PDF內容以索引文件或預填資料輸入表單。
  • 合併或拆分PDF 將多個報告合併為一個PDF,或將大型文件拆分為每個部分的文件。
  • 將PDF轉換為圖像 渲染PDF頁面為PNG或JPEG縮圖,以在移動介面中预览。

這每一個都成為一個獨立的API端點。 Xamarin客戶端像調用其他REST資源一樣調用它們,保持移動程式碼不含PDF邏輯,伺服器作為權威的文件處理器。

常見問題是什麼,您如何解決它們?

伺服器-客戶端架構是簡單明瞭的,但幾個問題需要引起注意:

Xamarin - IronPDF API整合的常見問題和建議解決方案
問題原因建議的解決方案
請求超時許多遠程資產的複雜HTML需要時間來渲染增加HttpClient.Timeout並在渲染選項中設置伺服器端渲染超時
大PDF記憶體激增通過響應體流式傳輸20 MB的PDF上傳到blob儲存並返回短期下載URL
離線生成當使用者請求PDF時,裝置無法連接在本地排隊請求並在連接恢復後重試
未授權的API存取端點向Internet開放使用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 App Service、AWS ECS或任何Kubernetes集群中。 IronPDF License鍵設置為伺服器上的環境變數:

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."))
$vbLabelText   $csharpLabel

查看IronPDF License頁面選擇適合您部署的層級。 一個免費試用授權允許您測試完整的功能套件在做承諾之前。 對於容器化或無伺服器部署,檢查授權層級是否覆蓋同時運行的伺服器實例數量。

授權之後,探索IronPDF文件以獲取包括執行緒安全渲染設置、PDF/A合規性和可存取性標記的高級配置選項。

生產部署檢查清單

基於IronPDF的PDF生成API的部署檢查清單
項目建議
License Key儲存在環境變數或秘密管理器中,永遠不要在源程式碼中
HTTPS在所有API端點上強制使用TLS;絕不要通過普通HTTP發送HTML負載
身份驗證使用JWT持票人標記或API密鑰;在破壞時撤銷
快取在短TTL內快取相同的HTML負載,以減少重複渲染
擴展IronPDF是執行緒安全的;在負載均衡器後面運行多個API副本
監控追踪渲染延遲和錯誤率;在超過基線的尖峰時警報

服務側模式可以橫向擴展,而無需對Xamarin或MAUI客戶端進行任何更改。 隨著PDF生成量的增長,新增副本並依賴負載均衡器均勻分配請求。

常見問題

IronPDF可以在Xamarin.Forms中原生使用嗎?

IronPDF不能在Xamarin.Forms中原生運行,但可以通過伺服器端方法整合以處理PDF建立和操控。

在移動應用中使用IronPDF進行PDF生成有哪些好處?

使用IronPDF可以建立PDF文件、填寫表單、處理多個頁面,並包含圖像、字體和自定義佈局,增強您的移動應用的PDF生成能力。

IronPDF如何在Xamarin中處理PDF建立?

IronPDF使用伺服器端方法在Xamarin中生成PDF,啟用不常見於移動裝置上的複雜PDF功能。

可以使用IronPDF在Xamarin中填寫PDF表單嗎?

可以,IronPDF支援作為其全面PDF處理功能的一部分,填寫Xamarin應用中的PDF表單。

IronPDF在Xamarin的PDF生成中解決了哪些挑戰?

IronPDF通過使用伺服器端解決方案解決了直接在移動裝置上生成PDF時出現的錯誤和功能缺失等問題。

IronPDF可以處理Xamarin應用中PDF的自定義佈局嗎?

可以,IronPDF可以在生成的PDF中包含自定義佈局,讓您可以控制文件的設計和呈現。

使用IronPDF可以在Xamarin中實現哪種PDF功能?

IronPDF允許在Xamarin中實現多頁文件、表單填寫、圖像與字體融合以及自定義佈局等功能。

為什麼建議使用伺服器端方法在Xamarin中使用IronPDF進行PDF生成?

建議使用伺服器端方法因為它避免了移動裝置的限制,確保可靠的PDF建立和高級功能。

Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

Iron 支援團隊

我們線上24小時,每週5天。
聊天
電子郵件
給我打電話