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
安裝軟體包後,請在應用程式啟動時設定您的許可證金鑰——通常是在 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()
將 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} | 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} | 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} | 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
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
建議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
設定 pdf.MetaData.Title 和 pdf.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
當您的 HTML 包含 Chart.js 或 ApexCharts 等圖表庫,而這些圖表庫會非同步完成繪製時,WaitFor.RenderDelay 設定特別有用。 設定 300-500 毫秒的延遲可確保 Chromium 捕捉最終渲染狀態。 對於需要符合歸檔標準的文檔,將上述方法與PDF/A 合規性和數位簽章結合。
頁尾文字中的 {page} 和 {total-pages} 標記由 IronPDF 在渲染時自動解析。其他頁首和頁尾選項包括用於放置徽標的基於 HTML 的頁眉以及按章節覆蓋設定的功能。
有哪些渲染選項?
下表總結了用於即時生成的最有用的 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
使用後請處置。 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
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
有關完整的浮水印配置選項(包括影像浮水印和每頁控制),請參閱浮水印文件。
!{--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生成功能到其應用中。



