跳過到頁腳內容
使用IRONPDF

ASP.NET Core:使用IronPDF即時創建PDF

在 ASP.NET Core 中動態生成專業的 PDF 文檔,方法是將 HTML 內容轉換為精美的 PDF,並將其直接串流傳輸到瀏覽器——無需磁碟存儲,無需管理臨時文件。

在 ASP.NET Core 中建立現代 Web 應用程式時,按需產生PDF 文件的功能是一個重複出現的需求。 發票需在付款到帳後立即下載。 審計員點選"匯出"後,合規性報告必須立即顯示。證書應該在使用者來得及懷疑是否出了問題之前就準備就緒。 IronPDF透過其基於 Chromium 的PDF 庫處理所有這些場景,該庫將 HTML(包括 CSS、JavaScript 和 Web 字體)轉換為像素精確的 PDF 輸出,而無需將任何內容寫入磁碟。

本指南涵蓋您需要了解的一切:安裝庫、從 HTML 字串生成發票、從 Entity Framework 資料流式傳輸報告、應用程式頁面標頭和安全性設置,以及採用最佳實踐來保持高流量 ASP.NET 應用程式的良好效能。

即時建立 PDF 是什麼意思?

"即時產生"是指在發出 HTTP 請求時,文件會在記憶體中建構並直接傳送給呼叫者。 不會寫入 PDF 文件,不會在後台作業中排隊處理工作,也不會在請求之間快取結果。

這種方法之所以重要,原因有以下幾點。 首先,雲端部署目標(Azure 應用程式服務、AWS Lambda、Docker 容器)通常運行在本機檔案系統是臨時的或唯讀的環境中。 在這些環境下,將 PDF 檔案產生到臨時資料夾然後再讀取回來是不安全的。 其次,避免磁碟寫入可以減少攻擊面:不會留下殘留文件,後續請求可能會意外地將文件提供給錯誤的使用者。 第三,僅記憶體生成通常速度更快,因為它消除了關鍵路徑中的兩次 I/O 操作(寫入和讀取)。

IronPDF 的ChromePdfRenderer在每個產生的文件上公開一個 .BinaryData 屬性和一個 .Stream 屬性。 兩者都可以直接傳遞給 ASP.NET Core FileResult,從而在實踐中實現串流只需一行程式碼。

!{--01001100010010010100001001010010010000010101001001011001010111110100011101000101010101 01000101111101010011010101000100000101010010010101000100010101000100010111110101011101001000110 1010101000100100001011111010100000101001001001111010001000101010101010000110101010100101010101011 10101010001010010010010010010000010100110001011111010000100100110001001111101000011010010111111010000110100101110--

如何在 ASP.NET Core 專案中安裝 IronPDF?

可以透過套件管理器控制台或 .NET CLI 新增 NuGet 套件:

Install-Package IronPdf
dotnet add package IronPdf
Install-Package IronPdf
dotnet add package IronPdf
SHELL

安裝軟體包後,請在應用程式啟動時設定您的許可證金鑰——通常是在 Program.cs 中,在建立第一個渲染器之前:

using IronPdf;

// Place license activation before any IronPDF call
License.LicenseKey = "YOUR-LICENSE-KEY";

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();

// Register ChromePdfRenderer as a singleton so the Chromium engine
// is initialised once and reused across all requests.
builder.Services.AddSingleton<ChromePdfRenderer>();

var app = builder.Build();
app.MapDefaultControllerRoute();
app.Run();
using IronPdf;

// Place license activation before any IronPDF call
License.LicenseKey = "YOUR-LICENSE-KEY";

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();

// Register ChromePdfRenderer as a singleton so the Chromium engine
// is initialised once and reused across all requests.
builder.Services.AddSingleton<ChromePdfRenderer>();

var app = builder.Build();
app.MapDefaultControllerRoute();
app.Run();
Imports IronPdf

' Place license activation before any IronPDF call
License.LicenseKey = "YOUR-LICENSE-KEY"

Dim builder = WebApplication.CreateBuilder(args)
builder.Services.AddControllersWithViews()

' Register ChromePdfRenderer as a singleton so the Chromium engine
' is initialised once and reused across all requests.
builder.Services.AddSingleton(Of ChromePdfRenderer)()

Dim app = builder.Build()
app.MapDefaultControllerRoute()
app.Run()
$vbLabelText   $csharpLabel

ChromePdfRenderer 註冊為單例非常重要。 渲染器首次使用時會啟動內部 Chromium 子程序。 如果每次請求都建立新實例,則每次呼叫都需要支付啟動成本,這會在負載下增加數百毫秒的延遲。 單例實例是線程安全的,無需額外配置即可處理並發渲染請求。

若要更全面地了解安裝選項(包括私有來源的 NuGet.config 設定),請造訪安裝概述

如何根據 HTML 字串產生發票 PDF?

最常見的即時使用情境是產生交易文件——發票、收據、訂單確認——其中內容會根據請求而變化,但佈局保持不變。

模式是:建立一個包含插值資料的 HTML 字串,將其傳遞給 RenderHtmlAsPdf,並將二進位結果作為檔案下載傳回。

using IronPdf;
using Microsoft.AspNetCore.Mvc;

public class DocumentController : Controller
{
    private readonly ChromePdfRenderer _renderer;

    public DocumentController(ChromePdfRenderer renderer)
    {
        _renderer = renderer;
    }

    [HttpGet("invoice/{orderId:int}")]
    public IActionResult GetInvoice(int orderId)
    {
        // In a real application, fetch this from your database or order service.
        var order = GetOrderData(orderId);

        string html = $"""
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="utf-8">
                <style>
                    body  {{ font-family: Arial, sans-serif; margin: 40px; color: #333; }}
                    h1   {{ color: #1a56db; }}
                    table {{ width: 100%; border-collapse: collapse; margin-top: 24px; }}
                    th, td {{ padding: 10px 14px; border: 1px solid #d1d5db; text-align: left; }}
                    th   {{ background: #f3f4f6; }}
                    tfoot td {{ font-weight: bold; }}
                </style>
            </head>
            <body>
                <h1>Invoice #{order.InvoiceNumber}</h1>
                <p>Date: {DateTime.UtcNow:yyyy-MM-dd} &nbsp;|&nbsp; Customer: {order.CustomerName}</p>
                <table>
                    <thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Subtotal</th></tr></thead>
                    <tbody>
                        {string.Join("", order.Items.Select(i =>
                            $"<tr><td>{i.Name}</td><td>{i.Quantity}</td>" +
                            $"<td>${i.UnitPrice:F2}</td><td>${i.Quantity * i.UnitPrice:F2}</td></tr>"))}
                    </tbody>
                    <tfoot>
                        <tr><td colspan="3">Total</td><td>${order.Items.Sum(i => i.Quantity * i.UnitPrice):F2}</td></tr>
                    </tfoot>
                </table>
            </body>
            </html>
            """;

        var pdf = _renderer.RenderHtmlAsPdf(html);
        return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf");
    }
}
using IronPdf;
using Microsoft.AspNetCore.Mvc;

public class DocumentController : Controller
{
    private readonly ChromePdfRenderer _renderer;

    public DocumentController(ChromePdfRenderer renderer)
    {
        _renderer = renderer;
    }

    [HttpGet("invoice/{orderId:int}")]
    public IActionResult GetInvoice(int orderId)
    {
        // In a real application, fetch this from your database or order service.
        var order = GetOrderData(orderId);

        string html = $"""
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="utf-8">
                <style>
                    body  {{ font-family: Arial, sans-serif; margin: 40px; color: #333; }}
                    h1   {{ color: #1a56db; }}
                    table {{ width: 100%; border-collapse: collapse; margin-top: 24px; }}
                    th, td {{ padding: 10px 14px; border: 1px solid #d1d5db; text-align: left; }}
                    th   {{ background: #f3f4f6; }}
                    tfoot td {{ font-weight: bold; }}
                </style>
            </head>
            <body>
                <h1>Invoice #{order.InvoiceNumber}</h1>
                <p>Date: {DateTime.UtcNow:yyyy-MM-dd} &nbsp;|&nbsp; Customer: {order.CustomerName}</p>
                <table>
                    <thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Subtotal</th></tr></thead>
                    <tbody>
                        {string.Join("", order.Items.Select(i =>
                            $"<tr><td>{i.Name}</td><td>{i.Quantity}</td>" +
                            $"<td>${i.UnitPrice:F2}</td><td>${i.Quantity * i.UnitPrice:F2}</td></tr>"))}
                    </tbody>
                    <tfoot>
                        <tr><td colspan="3">Total</td><td>${order.Items.Sum(i => i.Quantity * i.UnitPrice):F2}</td></tr>
                    </tfoot>
                </table>
            </body>
            </html>
            """;

        var pdf = _renderer.RenderHtmlAsPdf(html);
        return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf");
    }
}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc

Public Class DocumentController
    Inherits Controller

    Private ReadOnly _renderer As ChromePdfRenderer

    Public Sub New(renderer As ChromePdfRenderer)
        _renderer = renderer
    End Sub

    <HttpGet("invoice/{orderId:int}")>
    Public Function GetInvoice(orderId As Integer) As IActionResult
        ' In a real application, fetch this from your database or order service.
        Dim order = GetOrderData(orderId)

        Dim html As String = $"
            <!DOCTYPE html>
            <html lang=""en"">
            <head>
                <meta charset=""utf-8"">
                <style>
                    body  {{ font-family: Arial, sans-serif; margin: 40px; color: #333; }}
                    h1   {{ color: #1a56db; }}
                    table {{ width: 100%; border-collapse: collapse; margin-top: 24px; }}
                    th, td {{ padding: 10px 14px; border: 1px solid #d1d5db; text-align: left; }}
                    th   {{ background: #f3f4f6; }}
                    tfoot td {{ font-weight: bold; }}
                </style>
            </head>
            <body>
                <h1>Invoice #{order.InvoiceNumber}</h1>
                <p>Date: {DateTime.UtcNow:yyyy-MM-dd} &nbsp;|&nbsp; Customer: {order.CustomerName}</p>
                <table>
                    <thead><tr><th>Item</th><th>Qty</th><th>Unit Price</th><th>Subtotal</th></tr></thead>
                    <tbody>
                        {String.Join("", order.Items.Select(Function(i) $"<tr><td>{i.Name}</td><td>{i.Quantity}</td>" +
                            $"<td>${i.UnitPrice:F2}</td><td>${i.Quantity * i.UnitPrice:F2}</td></tr>"))}
                    </tbody>
                    <tfoot>
                        <tr><td colspan=""3"">Total</td><td>${order.Items.Sum(Function(i) i.Quantity * i.UnitPrice):F2}</td></tr>
                    </tfoot>
                </table>
            </body>
            </html>
            "

        Dim pdf = _renderer.RenderHtmlAsPdf(html)
        Return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf")
    End Function
End Class
$vbLabelText   $csharpLabel

RenderHtmlAsPdf 使用與 Google Chrome 相同的 Chromium 引擎處理完整的 HTML 文件——CSS 網格、Flexbox、網頁字體,甚至內嵌 SVG。 傳回的 PdfDocument 暴露了 BinaryData(一個 byte[])和 Stream(一個 MemoryStream)。 將 BinaryData 傳遞給 File(),並傳入 "application/pdf" 和檔案名,即可觸發瀏覽器下載。

對於需要像素級精確度的佈局,請參閱HTML 到 PDF 渲染指南,其中涵蓋響應式 CSS、自訂字體和JavaScript 渲染

產生的發票 PDF 文件長什麼樣子?

專業PDF發票,發票編號123,日期為2025年11月13日,包含樣式化的頁首部分,以及包含產品A(10.99美元)和產品B(5.49美元)的表格,展示了使用自訂CSS樣式動態產生PDF的功能。

如何在不彈出下載對話框的情況下將 PDF 文件直接串流到瀏覽器?

以內聯方式提供 PDF 檔案(即在瀏覽器的內建檢視器中開啟而不是下載),需要進行兩項小的變更:將 Content-Disposition 設定為 inline,並從 File() 呼叫中省略檔案名稱。

[HttpPost("report/preview")]
public async Task<IActionResult> PreviewReport([FromBody] ReportRequest request)
{
    string html = BuildReportHtml(request);

    var pdfDocument = await _renderer.RenderHtmlAsPdfAsync(html);

    // "inline" tells the browser to display rather than download.
    Response.Headers["Content-Disposition"] = "inline; filename=report.pdf";

    return new FileContentResult(pdfDocument.BinaryData, "application/pdf");
}
[HttpPost("report/preview")]
public async Task<IActionResult> PreviewReport([FromBody] ReportRequest request)
{
    string html = BuildReportHtml(request);

    var pdfDocument = await _renderer.RenderHtmlAsPdfAsync(html);

    // "inline" tells the browser to display rather than download.
    Response.Headers["Content-Disposition"] = "inline; filename=report.pdf";

    return new FileContentResult(pdfDocument.BinaryData, "application/pdf");
}
Imports Microsoft.AspNetCore.Mvc

<HttpPost("report/preview")>
Public Async Function PreviewReport(<FromBody> request As ReportRequest) As Task(Of IActionResult)
    Dim html As String = BuildReportHtml(request)

    Dim pdfDocument = Await _renderer.RenderHtmlAsPdfAsync(html)

    ' "inline" tells the browser to display rather than download.
    Response.Headers("Content-Disposition") = "inline; filename=report.pdf"

    Return New FileContentResult(pdfDocument.BinaryData, "application/pdf")
End Function
$vbLabelText   $csharpLabel

建議ASP.NET Core 控制器使用非同步重載 RenderHtmlAsPdfAsync,因為它會在 Chromium 渲染時釋放線程池線程,從而在並發負載下保持伺服器的回應能力。

基於記憶體的PDF生成是如何運作的?

產生的 PDF 報告標題為"月度績效評估",其中包含格式化的內容,展示瞭如何生成實際的業務文檔,包括圖表、指標和詳細分析部分,這些內容均由 HTML 模板渲染而成。

pdfDocument.BinaryData 位元組陣列完全駐留在託管記憶體中。 不涉及中間文件路徑。 Content-Disposition 標頭控制 PDF 是內嵌顯示還是作為下載提供-這是 HTTP 規範定義的瀏覽器行為。 若要深入了解 MemoryStream 方法,包括串流傳輸到 Azure Blob 存儲,請存取PDF 記憶體流文件

如何從 Entity Framework Core 查詢結果產生 PDF?

大多數業務應用程式都從資料庫中提取報表數據,而不是在呼叫時建立報表。以下模式查詢Entity Framework Core ,建立 HTML 表格,並傳回 PDF 檔案-所有操作都在單一控制器操作中完成。

[HttpGet("report/monthly")]
public async Task<IActionResult> MonthlyReport(int year, int month)
{
    // Pull aggregated transaction data from EF Core.
    var rows = await _dbContext.Transactions
        .Where(t => t.Date.Year == year && t.Date.Month == month)
        .GroupBy(t => t.Category)
        .Select(g => new { Category = g.Key, Count = g.Count(), Total = g.Sum(t => t.Amount) })
        .OrderByDescending(g => g.Total)
        .ToListAsync();

    string tableRows = string.Join("", rows.Select(r =>
        $"<tr><td>{r.Category}</td><td>{r.Count}</td><td>${r.Total:F2}</td></tr>"));

    string html = $"""
        <html><body style="font-family:Arial,sans-serif;padding:32px">
        <h1>Monthly Report -- {month:D2}/{year}</h1>
        <table style="width:100%;border-collapse:collapse">
          <thead>
            <tr style="background:#e5e7eb">
              <th style="padding:8px;border:1px solid #d1d5db">Category</th>
              <th style="padding:8px;border:1px solid #d1d5db">Transactions</th>
              <th style="padding:8px;border:1px solid #d1d5db">Total</th>
            </tr>
          </thead>
          <tbody>{tableRows}</tbody>
        </table>
        </body></html>
        """;

    var pdf = _renderer.RenderHtmlAsPdf(html);
    pdf.MetaData.Title  = $"Monthly Report {month:D2}/{year}";
    pdf.MetaData.Author = "Reporting System";

    return File(pdf.BinaryData, "application/pdf", $"report-{year}-{month:D2}.pdf");
}
[HttpGet("report/monthly")]
public async Task<IActionResult> MonthlyReport(int year, int month)
{
    // Pull aggregated transaction data from EF Core.
    var rows = await _dbContext.Transactions
        .Where(t => t.Date.Year == year && t.Date.Month == month)
        .GroupBy(t => t.Category)
        .Select(g => new { Category = g.Key, Count = g.Count(), Total = g.Sum(t => t.Amount) })
        .OrderByDescending(g => g.Total)
        .ToListAsync();

    string tableRows = string.Join("", rows.Select(r =>
        $"<tr><td>{r.Category}</td><td>{r.Count}</td><td>${r.Total:F2}</td></tr>"));

    string html = $"""
        <html><body style="font-family:Arial,sans-serif;padding:32px">
        <h1>Monthly Report -- {month:D2}/{year}</h1>
        <table style="width:100%;border-collapse:collapse">
          <thead>
            <tr style="background:#e5e7eb">
              <th style="padding:8px;border:1px solid #d1d5db">Category</th>
              <th style="padding:8px;border:1px solid #d1d5db">Transactions</th>
              <th style="padding:8px;border:1px solid #d1d5db">Total</th>
            </tr>
          </thead>
          <tbody>{tableRows}</tbody>
        </table>
        </body></html>
        """;

    var pdf = _renderer.RenderHtmlAsPdf(html);
    pdf.MetaData.Title  = $"Monthly Report {month:D2}/{year}";
    pdf.MetaData.Author = "Reporting System";

    return File(pdf.BinaryData, "application/pdf", $"report-{year}-{month:D2}.pdf");
}
Imports Microsoft.AspNetCore.Mvc
Imports System.Threading.Tasks
Imports System.Linq

<HttpGet("report/monthly")>
Public Async Function MonthlyReport(year As Integer, month As Integer) As Task(Of IActionResult)
    ' Pull aggregated transaction data from EF Core.
    Dim rows = Await _dbContext.Transactions _
        .Where(Function(t) t.Date.Year = year AndAlso t.Date.Month = month) _
        .GroupBy(Function(t) t.Category) _
        .Select(Function(g) New With {Key .Category = g.Key, Key .Count = g.Count(), Key .Total = g.Sum(Function(t) t.Amount)}) _
        .OrderByDescending(Function(g) g.Total) _
        .ToListAsync()

    Dim tableRows As String = String.Join("", rows.Select(Function(r) $"<tr><td>{r.Category}</td><td>{r.Count}</td><td>${r.Total:F2}</td></tr>"))

    Dim html As String = $"
        <html><body style='font-family:Arial,sans-serif;padding:32px'>
        <h1>Monthly Report -- {month:D2}/{year}</h1>
        <table style='width:100%;border-collapse:collapse'>
          <thead>
            <tr style='background:#e5e7eb'>
              <th style='padding:8px;border:1px solid #d1d5db'>Category</th>
              <th style='padding:8px;border:1px solid #d1d5db'>Transactions</th>
              <th style='padding:8px;border:1px solid #d1d5db'>Total</th>
            </tr>
          </thead>
          <tbody>{tableRows}</tbody>
        </table>
        </body></html>
        "

    Dim pdf = _renderer.RenderHtmlAsPdf(html)
    pdf.MetaData.Title = $"Monthly Report {month:D2}/{year}"
    pdf.MetaData.Author = "Reporting System"

    Return File(pdf.BinaryData, "application/pdf", $"report-{year}-{month:D2}.pdf")
End Function
$vbLabelText   $csharpLabel

設定 pdf.MetaData.Titlepdf.MetaData.Author 會將資訊嵌入 PDF 文件屬性中,這對於合規性追蹤和文件管理系統非常有用。 對於更複雜的報表佈局,請考慮使用CSS 列印樣式明確分頁符號嵌入式圖表影像

如何為產生的 PDF 檔案新增頁首、頁尾和安全設定?

生產文件通常需要包含文件標題的頁首、頁碼頁尾以及防止未經授權的列印或複製的存取控制。 IronPDF 的 ChromePdfRenderOptions 滿足所有這些要求。

[HttpPost("document/secured")]
public async Task<IActionResult> GenerateSecuredDocument([FromBody] SecuredDocRequest request)
{
    var renderOptions = new ChromePdfRenderOptions
    {
        紙張尺寸       = Pdf紙張尺寸.A4,
        MarginTop       = 45,
        MarginBottom    = 45,
        MarginLeft      = 25,
        MarginRight     = 25,
        啟用 JavaScript = true,
        WaitFor         = new WaitFor { RenderDelay = 500 }
    };

    renderOptions.TextHeader = new 文字頁眉頁腳
    {
        CenterText       = request.DocumentTitle,
        DrawDividerLine  = true,
        FontSize         = 11
    };

    renderOptions.TextFooter = new 文字頁眉頁腳
    {
        LeftText  = "{date} {time}",
        RightText = "Page {page} of {total-pages}",
        FontSize  = 9
    };

    _renderer.RenderingOptions = renderOptions;

    var pdf = await _renderer.RenderHtmlAsPdfAsync(request.HtmlContent);

    if (request.RequirePassword)
    {
        pdf.SecuritySettings.OwnerPassword         = request.OwnerPassword;
        pdf.SecuritySettings.UserPassword          = request.UserPassword;
        pdf.SecuritySettings.AllowUserPrinting     = PdfPrintSecurity.NoPrint;
        pdf.SecuritySettings.AllowUserCopyPasteContent = false;
    }

    return File(pdf.BinaryData, "application/pdf", $"{request.FileName}.pdf");
}
[HttpPost("document/secured")]
public async Task<IActionResult> GenerateSecuredDocument([FromBody] SecuredDocRequest request)
{
    var renderOptions = new ChromePdfRenderOptions
    {
        紙張尺寸       = Pdf紙張尺寸.A4,
        MarginTop       = 45,
        MarginBottom    = 45,
        MarginLeft      = 25,
        MarginRight     = 25,
        啟用 JavaScript = true,
        WaitFor         = new WaitFor { RenderDelay = 500 }
    };

    renderOptions.TextHeader = new 文字頁眉頁腳
    {
        CenterText       = request.DocumentTitle,
        DrawDividerLine  = true,
        FontSize         = 11
    };

    renderOptions.TextFooter = new 文字頁眉頁腳
    {
        LeftText  = "{date} {time}",
        RightText = "Page {page} of {total-pages}",
        FontSize  = 9
    };

    _renderer.RenderingOptions = renderOptions;

    var pdf = await _renderer.RenderHtmlAsPdfAsync(request.HtmlContent);

    if (request.RequirePassword)
    {
        pdf.SecuritySettings.OwnerPassword         = request.OwnerPassword;
        pdf.SecuritySettings.UserPassword          = request.UserPassword;
        pdf.SecuritySettings.AllowUserPrinting     = PdfPrintSecurity.NoPrint;
        pdf.SecuritySettings.AllowUserCopyPasteContent = false;
    }

    return File(pdf.BinaryData, "application/pdf", $"{request.FileName}.pdf");
}
Imports Microsoft.AspNetCore.Mvc

<HttpPost("document/secured")>
Public Async Function GenerateSecuredDocument(<FromBody> request As SecuredDocRequest) As Task(Of IActionResult)
    Dim renderOptions As New ChromePdfRenderOptions With {
        .紙張尺寸 = Pdf紙張尺寸.A4,
        .MarginTop = 45,
        .MarginBottom = 45,
        .MarginLeft = 25,
        .MarginRight = 25,
        .啟用JavaScript = True,
        .WaitFor = New WaitFor With {.RenderDelay = 500}
    }

    renderOptions.TextHeader = New 文字頁眉頁腳 With {
        .CenterText = request.DocumentTitle,
        .DrawDividerLine = True,
        .FontSize = 11
    }

    renderOptions.TextFooter = New 文字頁眉頁腳 With {
        .LeftText = "{date} {time}",
        .RightText = "Page {page} of {total-pages}",
        .FontSize = 9
    }

    _renderer.RenderingOptions = renderOptions

    Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(request.HtmlContent)

    If request.RequirePassword Then
        pdf.SecuritySettings.OwnerPassword = request.OwnerPassword
        pdf.SecuritySettings.UserPassword = request.UserPassword
        pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint
        pdf.SecuritySettings.AllowUserCopyPasteContent = False
    End If

    Return File(pdf.BinaryData, "application/pdf", $"{request.FileName}.pdf")
End Function
$vbLabelText   $csharpLabel

當您的 HTML 包含 Chart.js 或 ApexCharts 等圖表庫,而這些圖表庫會非同步完成繪製時,WaitFor.RenderDelay 設定特別有用。 設定 300-500 毫秒的延遲可確保 Chromium 捕捉最終渲染狀態。 對於需要符合歸檔標準的文檔,將上述方法與PDF/A 合規性和數位簽章結合。

頁尾文字中的 {page}{total-pages} 標記由 IronPDF 在渲染時自動解析。其他頁首和頁尾選項包括用於放置徽標的基於 HTML 的頁眉以及按章節覆蓋設定的功能。

有哪些渲染選項?

下表總結了用於即時生成的最有用的 ChromePdfRenderOptions 屬性:

常用的 ChromePdfRenderOptions 屬性
屬性 類型 目的
紙張尺寸Pdf紙張尺寸設定頁面尺寸(A4、Letter、Legal、自訂)
上邊距/下邊距整數(毫米)控制列印區域間距
啟用 JavaScript布林值允許在捕獲之前執行 JS 操作
WaitFor.RenderDelay整數(毫秒)延遲擷取以進行非同步渲染
文字頁首/文字頁腳文字頁眉頁腳頁面頁首和頁尾
HTML頁首/HTML頁尾HtmlHeaderFooter帶有圖片的 HTML 格式頁首/頁腳
灰階布林值輸出單色 PDF
適應紙張寬度布林值將寬內容縮放以適應頁面

高容量 PDF 產生的最佳效能實踐是什麼?

當單一伺服器處理數百個並發 PDF 請求時,一些架構決策會對吞吐量和延遲產生巨大的影響。

單例渲染器註冊。如安裝部分所示,將 ChromePdfRenderer 註冊為依賴注入容器中的單例,可以避免每次請求都啟動一個新的 Chromium 子程序所帶來的開銷。根據微軟的 ASP.NET Core 效能指南,減少物件分配和重複使用高成本資源是兩種最有效的最佳化方法。

始終使用 async。 RenderHtmlAsPdfAsync 傳回一個 Task<PdfDocument> 並在 Chromium 運行時掛起控制器執行緒。 這樣可以釋放線程池,使其能夠並行處理其他傳入的請求,這也是非同步文件建議 Web 主機使用此重載的原因。 同步重載僅適用於可以接受執行緒阻塞的控制台工具或背景服務。

直接串流,盡可能跳過中間數組。對於大型 PDF 文件,可以直接將 .Stream 寫入響應體,而無需實例化完整的位元組數組:

[HttpGet("document/large")]
public IActionResult StreamLargeDocument(int documentId)
{
    string html = BuildLargeDocumentHtml(documentId);
    var pdf = _renderer.RenderHtmlAsPdf(html);

    // Stream.Position is already at 0; no seek needed.
    return File(pdf.Stream, "application/pdf", $"document-{documentId}.pdf");
}
[HttpGet("document/large")]
public IActionResult StreamLargeDocument(int documentId)
{
    string html = BuildLargeDocumentHtml(documentId);
    var pdf = _renderer.RenderHtmlAsPdf(html);

    // Stream.Position is already at 0; no seek needed.
    return File(pdf.Stream, "application/pdf", $"document-{documentId}.pdf");
}
Imports Microsoft.AspNetCore.Mvc

<HttpGet("document/large")>
Public Function StreamLargeDocument(documentId As Integer) As IActionResult
    Dim html As String = BuildLargeDocumentHtml(documentId)
    Dim pdf = _renderer.RenderHtmlAsPdf(html)

    ' Stream.Position is already at 0; no seek needed.
    Return File(pdf.Stream, "application/pdf", $"document-{documentId}.pdf")
End Function
$vbLabelText   $csharpLabel

使用後請處置。 PdfDocument 實現了 IDisposable。 將其包裝在 using 語句中可以立即釋放底層記憶體緩衝區,這在連續產生多個大型 PDF 時非常重要:

using var pdf = _renderer.RenderHtmlAsPdf(html);
byte[] data = pdf.BinaryData;
// pdf is disposed here; data is safely copied to the local array.
return File(data, "application/pdf", "output.pdf");
using var pdf = _renderer.RenderHtmlAsPdf(html);
byte[] data = pdf.BinaryData;
// pdf is disposed here; data is safely copied to the local array.
return File(data, "application/pdf", "output.pdf");
Imports System.IO

Using pdf = _renderer.RenderHtmlAsPdf(html)
    Dim data As Byte() = pdf.BinaryData
    ' pdf is disposed here; data is safely copied to the local array.
    Return File(data, "application/pdf", "output.pdf")
End Using
$vbLabelText   $csharpLabel

IronPDF 文件針對Azure 、AWS、Docker 和 Linux 環境提供了雲端部署指導,並提供了特定於環境的配置說明。 如果啟動後的第一次渲染速度較慢,請參考預熱和快取指南,以了解在第一個使用者要求到達之前預初始化渲染器的策略。

如何在生成的PDF文件中添加浮水印?

在串流媒體之前,可以在生成的文件的每一頁上添加文字或圖像浮水印:

[HttpGet("document/draft/{id:int}")]
public IActionResult GetDraftDocument(int id)
{
    string html = BuildDocumentHtml(id);
    var pdf = _renderer.RenderHtmlAsPdf(html);

    // Stamp "DRAFT" diagonally across every page.
    pdf.ApplyWatermark(
        "<h1 style='color:rgba(200,0,0,0.25);transform:rotate(-45deg)'>DRAFT</h1>",
        rotation: 45,
        opacity: 30
    );

    return File(pdf.BinaryData, "application/pdf", $"draft-{id}.pdf");
}
[HttpGet("document/draft/{id:int}")]
public IActionResult GetDraftDocument(int id)
{
    string html = BuildDocumentHtml(id);
    var pdf = _renderer.RenderHtmlAsPdf(html);

    // Stamp "DRAFT" diagonally across every page.
    pdf.ApplyWatermark(
        "<h1 style='color:rgba(200,0,0,0.25);transform:rotate(-45deg)'>DRAFT</h1>",
        rotation: 45,
        opacity: 30
    );

    return File(pdf.BinaryData, "application/pdf", $"draft-{id}.pdf");
}
<AttributeUsage(AttributeTargets.Method, Inherited:=True, AllowMultiple:=False)>
Public Class HttpGetAttribute
    Inherits Attribute

    Public Sub New(route As String)
    End Sub
End Class

<HttpGet("document/draft/{id:int}")>
Public Function GetDraftDocument(id As Integer) As IActionResult
    Dim html As String = BuildDocumentHtml(id)
    Dim pdf = _renderer.RenderHtmlAsPdf(html)

    ' Stamp "DRAFT" diagonally across every page.
    pdf.ApplyWatermark(
        "<h1 style='color:rgba(200,0,0,0.25);transform:rotate(-45deg)'>DRAFT</h1>",
        rotation:=45,
        opacity:=30
    )

    Return File(pdf.BinaryData, "application/pdf", $"draft-{id}.pdf")
End Function
$vbLabelText   $csharpLabel

有關完整的浮水印配置選項(包括影像浮水印和每頁控制),請參閱浮水印文件

!{--010011000100100101000010010100100100000101010010010110010101111101001110010101010101010101010101010101010101010 0100010111110100100101001101010100010000010100110001001100010111110100001001001100010011110010101010

下一步計劃是什麼?

ASP.NET Core 中的動態 PDF 產生遵循一致的模式:建立 HTML,呼叫 RenderHtmlAsPdf 或其非同步重載,並透過 FileResult 傳回結果。 IronPDF 可以處理中間的所有步驟——Chromium 渲染、CSS 應用、JavaScript 執行——而無需在任何階段進行磁碟 I/O。

從這裡出發,您可以根據自己的應用需求探索多個方向。 如果您的 PDF 需要合併多個來源文檔,合併和分割指南涵蓋如何將現有 PDF 與新渲染的頁面連接起來。 如果您需要使用者填寫並提交嵌入在 PDF 中的表單,則互動式表單文件將展示如何建立和讀取欄位值。 對於受監管的行業, PDF/A 合規性PDF/UA 可存取性可確保文件符合存檔和可存取性標準。

如果您正在評估 IronPDF 與其他替代方案, iText 與 IronPDF 的比較提供了並排的技術分析。 準備好投入生產時,請購買許可證以解鎖所有功能並獲得優先工程支援。 完整的API 參考文檔包含了本指南中討論的每個類別和方法。

如果在實施過程中遇到任何問題,工程支援團隊隨時為您提供協助。關於Blazor Server或 MAUI 等平台的具體說明,我們提供了專門的指南,其中涵蓋了每種主機型號的配置差異。

常見問題解答

如何在ASP.NET Core中動態生成PDF?

您可以使用IronPDF在ASP.NET Core中動態生成PDF而不需將檔案儲存至磁碟。它允許您直接將PDF串流至瀏覽器。

使用IronPDF生成PDF的好處是什麼?

IronPDF提供了一個強大的渲染引擎,能夠直接在您的.NET Core專案中動態創建PDF,確保即時生成PDF而無需伺服器端存儲。

IronPDF可以用來創建發票和報告嗎?

是的,IronPDF適合用於創建各種類型的文件,如發票、報告和證書,這些都在ASP.NET Core應用程式中即時生成。

使用IronPDF時伺服器端存儲是否必要?

不,IronPDF允許您直接生成並將PDF串流至瀏覽器,而無需伺服器端存儲,使其高效且快速。

哪些類型的應用可以從即時PDF生成中受益?

現代Web應用,尤其是那些需要即時創建文件的系統,如開票系統和報告工具,都能從IronPDF提供的即時PDF生成中大大受益。

IronPDF是否支持.NET Core專案?

是的,IronPDF完全兼容.NET Core專案,使開發者能夠無縫整合PDF生成功能到其應用中。

Curtis Chau
技術作家

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

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

鋼鐵支援團隊

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