跳過到頁腳內容
使用IRONPDF

如何使用IronPDF創建.NET PDF API

在使用現代應用程式時,像您這樣的 .NET 開發人員可能會發現自己需要建立一個集中式的 PDF 生成服務。無論您是產生發票、報告、證書還是合同,擁有專用的 .NET PDF API 都有助於高效地管理 PDF 文件。 那麼,它如何改進您的 PDF 生成任務呢? 它透過提供桌面和 Web 應用程式的一致性、可維護性和可擴展性來實現這一點。 管理文件內容、PDF 頁面和 PDF 表單欄位從未如此簡單。

在本教程中,您將學習如何使用 ASP.NET Core 和IronPDF (一個強大的 .NET PDF 庫)建立可用於生產的 PDF API。 我們將建立 RESTful 端點,這些端點可以從 HTML 產生 PDF、合併文件、新增浮水印,並在您的 Web API 中處理各種實際的 PDF 產生場景。

為什麼要建立專用的 PDF API?

在深入程式碼之前,讓我們先了解為什麼創建一個專用的 PDF API 是有意義的:

*集中式邏輯*:所有 PDF 產生邏輯都集中在一個地方,使維護和更新更加便利。 微服務架構:非常適合服務導向的架構,其中不同的應用程式需要 PDF 功能。 效能最佳化:更易於擴展和優化專用服務,以處理大型 PDF 檔案、多頁和動態資料。 語言無關**:任何客戶端應用程式都可以使用該 API,而無需考慮程式語言。 *輸出一致性:確保您組織內的所有 PDF 文件保持一致的文件佈局、段落格式和 PDF 內容。

準備開始建造了嗎? 下載IronPDF 的免費試用版,並依照本教學在 .NET Framework 專案中以程式設計方式建立 PDF 檔案。

IronPDF:完整的 .NET PDF 庫

IronPDF是 .NET 開發人員首選的 PDF 庫,它提供了一套全面的功能,使 Web API 專案中的 PDF 生成變得簡單可靠。 它基於 Chrome 渲染引擎構建,可確保像素級完美的HTML 到 PDF 轉換,通常只需幾行程式碼即可完成。 它在保持所有樣式、JavaScript 執行和響應式佈局的同時,也能做到這一切。

IronPDF 的關鍵特性使其成為 .NET PDF API 開發的理想選擇:

*基於 Chrome 的渲染*:利用 Google Chrome 的渲染引擎,將 HTML 內容精確轉換為 PDF 文檔,並完全支援嵌入式圖像和其他 Web 資源。 功能豐富**:支援編輯包含數位簽章、PDF 表單、註解、加密、壓縮等功能的新建和現有文檔 *建立安全的 PDF 文件:使用加密、數位簽章和文件保護來管理敏感的 PDF 內容。

  • 支援多種輸入格式:可使用 HTML、URL、圖像Office 文檔建立 PDF 文檔 *進階操作:*合併 PDF 頁面、分割文件、套用浮水印、建立互動式 PDF 表單以及以程式設計方式操作 PDF 文件。 跨平台支援**:可在 Windows、 Linux 、macOS、 Docker和雲端平台上運行 *效能優化非同步操作、高效的記憶體管理和快速渲染

如何設定您的PDF文檔API項目?

我們首先建立一個新的 ASP.NET Core Web API 專案並安裝必要的軟體包。

先決條件

  • .NET 6.0 SDK或更高版本
  • Visual Studio 2022 或 Visual Studio Code *使用 Postman或類似的 API 測試工具來測試您的 PDF REST API

創建專案

首先,讓我們建立一個項目,我們將在這個項目中建立我們的 PDF 生成工具。

dotnet new webapi -n PdfApiService
cd PdfApiService

安裝 IronPDF。

下一步是透過 NuGet 將 IronPDF 新增到您的專案中:

dotnet add package IronPdf

或者,使用 Visual Studio 中的 NuGet 套件管理器控制台:

Install-Package IronPdf

專案結構

C# 開發的一個重要方面是保持專案資料夾的整潔和結構清晰。 舉例來說

如何建立您的第一個 PDF 端點?

讓我們建立一個簡單的端點,將 HTML 轉換為 PDF 格式。 首先,建立服務介面和實作:

建立 PDF 服務

首先,我們將以下內容新增到 IPdfService.cs 檔案中:

public interface IPdfService
{
    byte[] GeneratePdfFromHtml(string htmlContent);
    byte[] GeneratePdfFromUrl(string url);
}
public interface IPdfService
{
    byte[] GeneratePdfFromHtml(string htmlContent);
    byte[] GeneratePdfFromUrl(string url);
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

在 PdfService.cs 檔案中,我們將新增以下程式碼:

using IronPdf;
public class PdfService : IPdfService
{
    private readonly ChromePdfRenderer _renderer;
    public PdfService()
    {
        _renderer = new ChromePdfRenderer();
        // Configure rendering options for optimal PDF generation in .NET
        _renderer.RenderingOptions.MarginTop = 20;
        _renderer.RenderingOptions.MarginBottom = 20;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GeneratePdfFromHtml(string htmlContent)
    {
        // Generate PDF from HTML using the .NET PDF API
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    }
    public byte[] GeneratePdfFromUrl(string url)
    {
        // Convert URL to PDF in the REST API
        var pdf = _renderer.RenderUrlAsPdf(url);
        return pdf.BinaryData;
    }
}
using IronPdf;
public class PdfService : IPdfService
{
    private readonly ChromePdfRenderer _renderer;
    public PdfService()
    {
        _renderer = new ChromePdfRenderer();
        // Configure rendering options for optimal PDF generation in .NET
        _renderer.RenderingOptions.MarginTop = 20;
        _renderer.RenderingOptions.MarginBottom = 20;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GeneratePdfFromHtml(string htmlContent)
    {
        // Generate PDF from HTML using the .NET PDF API
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    }
    public byte[] GeneratePdfFromUrl(string url)
    {
        // Convert URL to PDF in the REST API
        var pdf = _renderer.RenderUrlAsPdf(url);
        return pdf.BinaryData;
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

PdfService 負責將 HTML 轉換為 PDF 的核心流程。 該類別利用 IronPDF 的 ChromePdfRenderer,設定了合理的預設值,例如頁面邊距和背景渲染,以產生精美的最終文件。

當控制器傳入原始 HTML 時,該服務使用 IronPDF 將其渲染成專業品質的 PDF,並將結果作為位元組資料返回,即可下載。 此外,它還可以透過將 URL 直接轉換為 PDF 來處理整個網頁。

建立控制器

現在是時候為我們的 API 建立控制器了。 這將提供一個能夠從 HTML 產生 PDF 檔案的 API 端點。 之後,它就可以將 PDF 文件下載並儲存到您的系統中,以便進一步使用或共用。

// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
    private readonly IPdfService _pdfService;
    public PdfController(IPdfService pdfService)
    {
        _pdfService = pdfService;
    }
    [HttpPost("html-to-pdf")]
    public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
    {
        try
        {
            var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
            // Return as downloadable file
            return File(pdfBytes, "application/pdf", "document.pdf");
        }
        catch (Exception ex)
        {
            return BadRequest($"Error generating PDF: {ex.Message}");
        }
    }
}
// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
    private readonly IPdfService _pdfService;
    public PdfController(IPdfService pdfService)
    {
        _pdfService = pdfService;
    }
    [HttpPost("html-to-pdf")]
    public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
    {
        try
        {
            var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
            // Return as downloadable file
            return File(pdfBytes, "application/pdf", "document.pdf");
        }
        catch (Exception ex)
        {
            return BadRequest($"Error generating PDF: {ex.Message}");
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

然後,在 HtmlRequest.cs 檔案中,我們將新增以下程式碼:

// Models/HtmlRequest.cs
public class HtmlRequest
{
    public string HtmlContent { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
// Models/HtmlRequest.cs
public class HtmlRequest
{
    public string HtmlContent { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

在第一個檔案中,我們設定了一個簡單的 API 端點,可以將 HTML 轉換為可下載的 PDF。 當有人透過簡單的 POST 請求向 api/pdf/html-to-pdf 路由發送 HTML 內容時,PdfController 會將其轉換為 PDF 的任務傳遞給專用服務。

PDF 檔案產生後,控制器會將其作為可供下載的檔案傳回給使用者。該請求本身使用 HtmlRequest 模型構建,其中包含原始 HTML 程式碼以及最終文件的可選檔案名稱。 簡而言之,這種設定使得客戶可以輕鬆發送 HTML 文件,並立即收到精美的 PDF 文件作為回報。

註冊服務

更新 Program.cs 檔案以註冊 PDF 服務:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

如何處理不同類型的回覆?

您的 API 應支援根據客戶端需求傳回不同方式的 PDF 檔案:

[HttpPost("generate")]
 public IActionResult GeneratePdf([FromBody] PdfRequest request)
 {
     var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
     switch (request.ResponseType?.ToLower())
     {
         case "base64":
             return Ok(new
             {
                 data = Convert.ToBase64String(pdfBytes),
                 filename = request.FileName
             });
         case "inline":
             return File(pdfBytes, "application/pdf");
         default: // download
             return File(pdfBytes, "application/pdf", request.FileName);
     }
 }
[HttpPost("generate")]
 public IActionResult GeneratePdf([FromBody] PdfRequest request)
 {
     var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
     switch (request.ResponseType?.ToLower())
     {
         case "base64":
             return Ok(new
             {
                 data = Convert.ToBase64String(pdfBytes),
                 filename = request.FileName
             });
         case "inline":
             return File(pdfBytes, "application/pdf");
         default: // download
             return File(pdfBytes, "application/pdf", request.FileName);
     }
 }
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

在這裡,我們為控制器添加了一個更靈活的 PDF 生成端點。 GeneratePdf 方法不會強制下載文件,而是允許客戶端選擇如何傳回結果。 此選項提供了靈活性,允許以各種格式顯示 PDF:作為可下載的文件、直接在瀏覽器中顯示,或編碼為 Base64 字串以便在 API 中輕鬆使用。

該請求由 PdfRequest 模型定義,該模型基於早期的 HtmlRequest 模型,並新增了 ResponseType 選項。 簡而言之,這使用戶能夠更好地控制接收 PDF 的方式,從而使 API 更加靈活且用戶友好。

現在,當我們運行程式時,我們將在 Swagger 上看到以下輸出。

如何使用 IronPDF 建立 .NET PDF API:圖 4 - Swagger UI

如何實現常見的PDF操作?

讓我們擴展服務,以處理各種 PDF 生成場景:

URL 轉 PDF

[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
    try
    {
        var pdfBytes = await Task.Run(() => 
            _pdfService.GeneratePdfFromUrl(request.Url));
        return File(pdfBytes, "application/pdf", 
            $"{request.FileName ?? "website"}.pdf");
    }
    catch (Exception ex)
    {
        return BadRequest($"Failed to convert URL: {ex.Message}");
    }
}
public class UrlRequest
{
    public string Url { get; set; }
    public string FileName { get; set; }
}
[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
    try
    {
        var pdfBytes = await Task.Run(() => 
            _pdfService.GeneratePdfFromUrl(request.Url));
        return File(pdfBytes, "application/pdf", 
            $"{request.FileName ?? "website"}.pdf");
    }
    catch (Exception ex)
    {
        return BadRequest($"Failed to convert URL: {ex.Message}");
    }
}
public class UrlRequest
{
    public string Url { get; set; }
    public string FileName { get; set; }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

透過此端點,用戶端可以傳送 URL 並取得該網頁的可下載 PDF 檔案。 當收到 POST /api/pdf/url-to-pdf 請求時,控制器使用 _pdfService 在後台將給定的 URL 轉換為 PDF 位元組,然後將其作為文件下載返回。 如果在轉換過程中出現問題,它會優雅地返回清晰的錯誤訊息。

我們來試試使用這個網址"https://www.apple.com/nz並測試 POST 請求。以下是我們得到的輸出結果。

輸出

如何使用 IronPDF 建立 .NET PDF API:圖 5 - URL PDF 輸出

新增自訂浮水印

public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
    // Load PDF directly from file
    var pdf = PdfDocument.FromFile(filePath);
    pdf.ApplyWatermark(
        $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
        75,
        IronPdf.Editing.VerticalAlignment.Middle,
        IronPdf.Editing.HorizontalAlignment.Center
    );
    return pdf.BinaryData;
}
public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
    // Load PDF directly from file
    var pdf = PdfDocument.FromFile(filePath);
    pdf.ApplyWatermark(
        $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
        75,
        IronPdf.Editing.VerticalAlignment.Middle,
        IronPdf.Editing.HorizontalAlignment.Center
    );
    return pdf.BinaryData;
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

這裡我們只是為了測試目的手動載入本地文件。 不過,您可以調整此設置,使 PDF API 生成 PDF 文檔,然後輕鬆地為其應用自訂浮水印。

水印輸出

如何使用 IronPDF 建立 .NET PDF API:圖 6 - 上述程式碼範例中的浮水印輸出

如何使用範本新增動態數據

在實際應用中,您經常需要使用包含動態資料的範本來產生 PDF 檔案:

[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
    // Simple template replacement
    var html = request.Template;
    foreach (var item in request.Data)
    {
        html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
    }
    var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
    return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
    public string Template { get; set; }
    public Dictionary<string, string> Data { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
    // Simple template replacement
    var html = request.Template;
    foreach (var item in request.Data)
    {
        html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
    }
    var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
    return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
    public string Template { get; set; }
    public Dictionary<string, string> Data { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

對於使用 Razor、Handlebars 或其他引擎的更高級範本場景,請查看IronPDF 的 HTML 轉 PDF 文件。 您也可以探索 MVC 應用程式的CSHTML 轉 PDF 功能以及 Blazor 應用程式的Razor 轉 PDF 功能

如何優化效能?

建立生產級 PDF API 時,效能至關重要。 以下是一些關鍵的最佳化策略:

非同步操作

在建構涉及 I/O 操作的項目時,使用非同步編碼是明智之舉。 如果您的 PDF 內容來自外部資源,例如:這將特別有幫助。

  • 下載 HTML 頁面(RenderUrlAsPdf)
  • 透過 HTTP 取得圖像、CSS 或字體
  • 讀取/寫入檔案到磁碟或雲端存儲

這些操作可能會阻塞線程,但使用非同步操作可以防止 API 線程空閒等待。

範例:

public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
    return await Task.Run(() => 
    {
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    });
}
public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
    return await Task.Run(() => 
    {
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    });
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

渲染選項

配置 IronPDF 以獲得最佳性能:

_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout
_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

如何保護您的 PDF API?

對於任何生產環境的API來說,安全性至關重要。 以下是一種簡單的 API 金鑰認證方法:

// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private const string ApiKeyHeader = "X-API-Key";
    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("API Key required");
            return;
        }
        // Validate API key (in production, check against database)
        var validApiKey = context.RequestServices
            .GetRequiredService<IConfiguration>()["ApiKey"];
        if (apiKey != validApiKey)
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsync("Invalid API Key");
            return;
        }
        await _next(context);
    }
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();
// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private const string ApiKeyHeader = "X-API-Key";
    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("API Key required");
            return;
        }
        // Validate API key (in production, check against database)
        var validApiKey = context.RequestServices
            .GetRequiredService<IConfiguration>()["ApiKey"];
        if (apiKey != validApiKey)
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsync("Invalid API Key");
            return;
        }
        await _next(context);
    }
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

對於更高級的身份驗證場景,請考慮:

實際案例:發票產生 API

讓我們建立一個實用的發票產生端點,以演示完整的實作過程。 此範例展示了生產環境中的 .NET PDF API 如何使用動態資料產生專業發票。

!{--01001100010010010100001001010010010000010101001001011001010111110100011101000101010101 01000101111101010011010101000100000101010010010101000100010101000100010111110101011101001000110 1010101000100100001011111010100000101001001001111010001000101010101010000110101010100101010101011 10101010001010010010010010010000010100110001011111010000100100110001001111101000011010010111111010000110100101110--

首先,我們將在 Models 資料夾中建立一個新檔案。 在這裡,我把我的檔案名稱命名為 Invoice.cs。 然後,將以下程式碼新增至您的新檔案。

public class Invoice
{
    public string InvoiceNumber { get; set; }
    public DateTime Date { get; set; }
    public string CustomerName { get; set; }
    public string CustomerAddress { get; set; }
    public List<InvoiceItem> Items { get; set; }
    public decimal Tax { get; set; }
}
public class InvoiceItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal Total => Quantity * UnitPrice;
}
public class Invoice
{
    public string InvoiceNumber { get; set; }
    public DateTime Date { get; set; }
    public string CustomerName { get; set; }
    public string CustomerAddress { get; set; }
    public List<InvoiceItem> Items { get; set; }
    public decimal Tax { get; set; }
}
public class InvoiceItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal Total => Quantity * UnitPrice;
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

接下來,我們需要為發票產生器建立一個新的服務文件。 在 Services 資料夾中,新增以下程式碼。 我新建了一個名為 InvoiceService.cs 的檔案。 這段程式碼將處理發票 PDF 文件的樣式和佈局。

public class InvoiceService
{
    private readonly ChromePdfRenderer _renderer;
    public InvoiceService()
    {
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.MarginTop = 10;
        _renderer.RenderingOptions.MarginBottom = 10;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GenerateInvoice(Invoice invoice)
{
    var html = BuildInvoiceHtml(invoice);
    // Add footer with page numbers
    _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
    {
        MaxHeight = 15,
        HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
        DrawDividerLine = true
    };
    var pdf = _renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}
    private string BuildInvoiceHtml(Invoice invoice)
    {
        var subtotal = invoice.Items.Sum(i => i.Total);
        var taxAmount = subtotal * (invoice.Tax / 100);
        var total = subtotal + taxAmount;
        var itemsHtml = string.Join("", invoice.Items.Select(item => 
            $@"<tr>
                <td>{item.Description}</td>
                <td class='text-center'>{item.Quantity}</td>
                <td class='text-right'>${item.UnitPrice:F2}</td>
                <td class='text-right'>${item.Total:F2}</td>
            </tr>"));
        return $@"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; }}
                .invoice-header {{ 
                    background-color: #f8f9fa; 
                    padding: 20px; 
                    margin-bottom: 20px; 
                }}
                table {{ 
                    width: 100%; 
                    border-collapse: collapse; 
                }}
                th, td {{ 
                    padding: 10px; 
                    border-bottom: 1px solid #ddd; 
                }}
                th {{ 
                    background-color: #007bff; 
                    color: white; 
                }}
                .text-right {{ text-align: right; }}
                .text-center {{ text-align: center; }}
                .total-section {{ 
                    margin-top: 20px; 
                    text-align: right; 
                }}
            </style>
        </head>
        <body>
            <div class='invoice-header'>
                <h1>Invoice #{invoice.InvoiceNumber}</h1>
                <p>Date: {invoice.Date:yyyy-MM-dd}</p>
            </div>   
            <div>
                <h3>Bill To:</h3>
                <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
            </div>    
            <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    {itemsHtml}
                </tbody>
            </table>
            <div class='total-section'>
                <p>Subtotal: ${subtotal:F2}</p>
                <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
                <h3>Total: ${total:F2}</h3>
            </div>
        </body>
        </html>";
    }
}
public class InvoiceService
{
    private readonly ChromePdfRenderer _renderer;
    public InvoiceService()
    {
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.MarginTop = 10;
        _renderer.RenderingOptions.MarginBottom = 10;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GenerateInvoice(Invoice invoice)
{
    var html = BuildInvoiceHtml(invoice);
    // Add footer with page numbers
    _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
    {
        MaxHeight = 15,
        HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
        DrawDividerLine = true
    };
    var pdf = _renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}
    private string BuildInvoiceHtml(Invoice invoice)
    {
        var subtotal = invoice.Items.Sum(i => i.Total);
        var taxAmount = subtotal * (invoice.Tax / 100);
        var total = subtotal + taxAmount;
        var itemsHtml = string.Join("", invoice.Items.Select(item => 
            $@"<tr>
                <td>{item.Description}</td>
                <td class='text-center'>{item.Quantity}</td>
                <td class='text-right'>${item.UnitPrice:F2}</td>
                <td class='text-right'>${item.Total:F2}</td>
            </tr>"));
        return $@"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; }}
                .invoice-header {{ 
                    background-color: #f8f9fa; 
                    padding: 20px; 
                    margin-bottom: 20px; 
                }}
                table {{ 
                    width: 100%; 
                    border-collapse: collapse; 
                }}
                th, td {{ 
                    padding: 10px; 
                    border-bottom: 1px solid #ddd; 
                }}
                th {{ 
                    background-color: #007bff; 
                    color: white; 
                }}
                .text-right {{ text-align: right; }}
                .text-center {{ text-align: center; }}
                .total-section {{ 
                    margin-top: 20px; 
                    text-align: right; 
                }}
            </style>
        </head>
        <body>
            <div class='invoice-header'>
                <h1>Invoice #{invoice.InvoiceNumber}</h1>
                <p>Date: {invoice.Date:yyyy-MM-dd}</p>
            </div>   
            <div>
                <h3>Bill To:</h3>
                <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
            </div>    
            <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    {itemsHtml}
                </tbody>
            </table>
            <div class='total-section'>
                <p>Subtotal: ${subtotal:F2}</p>
                <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
                <h3>Total: ${total:F2}</h3>
            </div>
        </body>
        </html>";
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

最後,您需要建立一個新的控制器,以便使用 API 存取和建立新的發票。

[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
    private readonly InvoiceService _invoiceService;
    public InvoiceController(InvoiceService invoiceService)
    {
        _invoiceService = invoiceService;
    }
    [HttpPost("generate")]
    public IActionResult GenerateInvoice([FromBody] Invoice invoice)
    {
        try
        {
            var pdfBytes = _invoiceService.GenerateInvoice(invoice);
            var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
            return File(pdfBytes, "application/pdf", fileName);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error generating invoice: {ex.Message}");
        }
    }
}
[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
    private readonly InvoiceService _invoiceService;
    public InvoiceController(InvoiceService invoiceService)
    {
        _invoiceService = invoiceService;
    }
    [HttpPost("generate")]
    public IActionResult GenerateInvoice([FromBody] Invoice invoice)
    {
        try
        {
            var pdfBytes = _invoiceService.GenerateInvoice(invoice);
            var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
            return File(pdfBytes, "application/pdf", fileName);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error generating invoice: {ex.Message}");
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

發票輸出

如何使用 IronPDF 建立 .NET PDF API:圖 7 - PDF 發票輸出

容器部署注意事項

雖然本教學專注於本地開發,但這裡簡要概述如何將 PDF API 容器化:

基本 Dockerfile

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["PdfApiService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# IronPDF requires additional dependencies on Linux
RUN apt-get update && apt-get install -y \
    libgdiplus \
    libc6-dev \
    libx11-dev \
    && rm -rf /var/lib/apt/lists/*     
ENTRYPOINT ["dotnet", "PdfApiService.dll"]
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["PdfApiService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# IronPDF requires additional dependencies on Linux
RUN apt-get update && apt-get install -y \
    libgdiplus \
    libc6-dev \
    libx11-dev \
    && rm -rf /var/lib/apt/lists/*     
ENTRYPOINT ["dotnet", "PdfApiService.dll"]
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

有關 .NET PDF API 的詳細部署指南,請參閱:

IronPDF Docker 文件- 完整的容器化指南

錯誤處理最佳實踐

為了提高程序的容錯能力,最佳實踐是實作一個全域錯誤處理程序,以便提供一致的錯誤回應,例如:

// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }
    private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = 500;
        var response = new
        {
            error = "An error occurred processing your request",
            message = ex.Message
        };
        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}
// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }
    private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = 500;
        var response = new
        {
            error = "An error occurred processing your request",
            message = ex.Message
        };
        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

有關 IronPDF 的具體故障排除場景,請參閱IronPDF 故障排除指南

結論

現在您已經使用 ASP.NET Core 和 IronPDF 建立了一個強大的 .NET PDF API,可以處理各種文件產生場景。 此 REST API 為您的應用程式中的集中式 PDF 操作提供了堅實的基礎。

主要心得:

IronPDF 基於 Chrome 的渲染技術,讓 Web API 專案中的 PDF 產生變得簡單易行。 您可以輕鬆調整 Web API,以便使用 IronPDF 的進階編輯工具編輯現有 PDF 文件。

  • RESTful 設計原則確保您的 PDF API 直覺且易於維護
  • 正確的錯誤處理和安全措施對生產至關重要。
  • 透過非同步操作和快取進行效能最佳化,提高可擴展性 您將獲得對桌面和 Web 應用程式以及可擴展文件解決方案的支援。

IronPDF 讓開發人員有效地建立 PDF 文件、保存 PDF 文件和轉換 HTML,使其成為現代 .NET Framework 應用程式必不可少的 PDF 文件 API。

下一步。

準備好在生產環境的 .NET PDF API 中整合 IronPDF 了嗎? 接下來,您需要執行以下步驟:

1.開始免費試用- 在您的開發環境中體驗 IronPDF 的全部功能 2.探索進階功能- 查看數位簽章PDF 表單和其他進階 PDF 功能 3.輕鬆擴展- 審查滿足您生產 API 需求的許可選項

立即建立您的 .NET PDF API,並使用 IronPDF 簡化整個應用程式生態系統中的文件產生!

常見問題解答

什麼是 .NET PDF API?

.NET PDF API 是一個函式庫,可讓開發人員在 .NET 應用程式中建立、編輯和擷取 PDF 內容。它簡化了複雜的 PDF 任務,並確保 PDF 檔案的有效管理。

.NET PDF API 如何讓我的應用程式獲益?

.NET PDF API 可在管理 PDF 檔案(例如產生發票、報告、證書或合約)時提供一致性、可維護性和可擴展性,從而增強您的應用程式。

.NET PDF API 有哪些常見用例?

.NET PDF API 的常見用例包括在桌面和 Web 應用程式中產生發票、建立報告、製作證書和管理合約。

IronPDF 如何簡化 PDF 生成工作?

IronPdf 透過提供強大的函式庫,簡化了 PDF 的產生任務,可輕鬆管理文件內容、PDF 頁面和表單欄位,讓應用程式的維護和擴充更加容易。

IronPdf 能否處理 PDF 表單欄位?

是的,IronPDF 可以有效地管理 PDF 表單欄位,讓開發人員可以在 PDF 文件中建立、填寫表單並從表單中擷取資料。

IronPDF 是否同時適用於桌上型電腦和網頁應用程式?

絕對的,IronPDF 的設計可以在桌面和網頁應用程式之間無縫運作,提供一致且可擴充的 PDF 管理解決方案。

是什麼讓 IronPDF 成為 .NET 開發人員的可靠選擇?

IronPDF for .NET 易於使用、功能全面,而且能夠簡化 PDF 任務,從而提高生產力和應用程式效能,因此是 .NET 開發人員的可靠選擇。

IronPDF 是否支援 PDF 擷取功能?

是的,IronPDF 支援 PDF 擷取功能,可讓您有效率地從 PDF 文件擷取文字、圖片和其他資料。

IronPDF 如何提高管理 PDF 的可擴展性?

IronPDF 可提供集中式 PDF 生成服務,在不犧牲性能的情況下處理不斷增加的需求,從而提高了可擴展性,非常適合不斷成長的應用程式。

IronPDF 為 .NET 應用程式提供哪些支援?

IronPDF 為 .NET 應用程式提供廣泛的支援,包括詳細的說明文件、範例程式碼,以及反應迅速的支援團隊,協助開發人員整合 PDF 功能。

IronPDF 是否與 .NET 10 完全相容?

是的 - IronPDF 與 .NET 10 完全相容。它支援 .NET 10 引進的所有效能、語言和執行時增強功能,並可在 .NET 10 專案中開箱即用,就像在過去的版本(如 .NET6、7、8 和 9)中一樣。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。