如何在 C# ASP.NET Core MVC 中將視圖轉換為 PDF
使用 IronPDF 的 RenderRazorViewToPdf 方法將 ASP.NET Core MVC 檢視轉換為 PDF,此方法可在您的 MVC 應用程式中,僅需一行程式碼即可將 .cshtml 檔案轉換為高品質的 PDF 文件。
View 是 .NET Framework 中的一種元件,用於在網頁應用程式中產生 HTML 標記。 它是 Model-View-Controller (MVC) 模式的一部分,常應用於 ASP.NET MVC 和 ASP.NET Core MVC 應用程式中。 視圖負責透過動態渲染 HTML 內容,將資料呈現給使用者。 檢視通常採用 Razor 語法,這是一種用於將伺服器端程式碼嵌入網頁的標記語法,使其成為建立資料驅動型 PDF 文件的強大工具。
快速入門:在 ASP.NET Core 中將 CSHTML 轉換為 PDF
使用 IronPDF 將 ASP.NET Core MVC 檢視轉換為 PDF 檔案。 只需一行程式碼,即可將您的 .cshtml 檔案轉為 PDF 文件。 將此功能直接整合至您的 MVC 應用程式中,即可從動態 HTML 視圖無縫產生 PDF 檔案。 請遵循本指南設定環境並開始轉換。
-
using NuGet 套件管理員安裝 https://www.nuget.org/packages/IronPdf
PM > Install-Package IronPdf -
請複製並執行此程式碼片段。
// using IronPdf.Extensions.Mvc.Core new IronPdf.ChromePdfRenderer().RenderRazorViewToPdf(HttpContext, "Views/Home/Report.cshtml", model).SaveAs("report.pdf"); -
部署至您的生產環境進行測試
立即透過免費試用,在您的專案中開始使用 IronPDF
ASP.NET Core Web App MVC(模型-視圖-控制器)是由 Microsoft 提供的一套 Web 應用程式框架,用於透過 .NET Core 建置 Web 應用程式。
Model:代表資料與業務邏輯,管理資料互動,並與資料來源進行通訊。View:呈現使用者介面、顯示資料,並將資訊呈現給使用者。Controller:處理使用者輸入、回應請求、與Model進行通訊,並協調 Model-View 之間的互動。
IronPDF 允許在 ASP.NET Core MVC 專案中,直接從視圖 (Views) 建立 PDF 檔案。 這使得在 ASP.NET Core MVC 中生成 PDF 變得簡單直觀,並支援包括 CSS 樣式、JavaScript 執行及自訂字型在內的現代化功能。
簡化工作流程(5 個步驟)
- 下載用於在 ASP.NET Core MVC 中將視圖轉換為 PDF 的 C# 函式庫
- 為資料新增一個模型類別
- 編輯"HomeController.cs"檔案,並使用
RenderRazorViewToPdf方法 - 建立一個新的視圖,並編輯 ".cshtml" 檔案以渲染 PDF
- 下載範例專案以快速上手
使用 IronPDF 擴充套件需要哪些套件?
IronPdf.Extensions.Mvc.Core 套件是 IronPdf 主套件的擴充套件。 在 ASP.NET Core MVC 中,若要將視圖渲染為 PDF 文件,必須同時使用 IronPdf.Extensions.Mvc.Core 和 IronPdf 套件。 此擴充套件提供特定功能,用於與 .NET Core 的依賴注入系統及 Razor 視圖渲染管道進行整合。
Install-Package IronPdf.Extensions.Mvc.Core
為什麼我需要同時使用 IronPDF 和擴充套件?
IronPDF 主要套件包含核心 PDF 渲染引擎及基礎功能,而 Extensions.Mvc.Core 套件則提供與 ASP.NET Core MVC 視圖渲染系統的專用整合功能。 這種分離設計能提升模組化程度,並確保您僅需納入專案類型所需的特定功能。 此擴充套件包含 IRazorViewRenderer 介面及其實作,用於在生成 PDF 之前將 Razor 檢視轉換為 HTML。
我應該使用哪個 NuGet 套件版本?
請務必使用 IronPdf 與 IronPdf.Extensions.Mvc.Core 的對應版本,以確保相容性。 如需最新穩定版本及版本相容性資訊,請參閱 NuGet 套件文件。 更新時,請確保兩個套件同時更新,以維持正常功能。
常見的安裝問題有哪些?
常見的安裝問題包括核心套件與擴充套件版本不符、缺少依賴項,或特定平台的系統需求。 若遇到問題,請確認您的專案目標為受支援的 .NET 版本,並參閱安裝概覽以獲取疑難排解步驟。
透過 NuGet 安裝
Install-Package IronPdf.Extensions.Mvc.Core
如何將視圖渲染為 PDF?
您需要一個 ASP.NET Core Web App(模型-視圖-控制器)專案,才能將視圖轉換為 PDF 檔案。 此流程涉及建立一個控制器動作,該動作使用 IronPDF 的 RenderRazorViewToPdf 方法,將您的 Razor 檢視轉換為 PDF 文件。 此方法充分利用 Razor 語法的強大功能,讓您能夠建立包含動態內容的複雜、資料驅動型 PDF 檔案。
我應該選擇哪種專案類型?
請使用 ASP.NET Core Web App (Model-View-Controller) 範本,以確保與 IronPDF 的視圖渲染功能達到最佳相容性。 此專案類型提供了視圖渲染所需的基礎架構,包括 Razor 視圖引擎與適當的路由機制。 針對現有專案,請確保其遵循 MVC 模式,並已安裝所需的視圖渲染功能。
我能否在 API 極少的情況下使用此工具?
雖然 Minimal APIs 本身不具備內建的檢視功能,但您仍可使用 IronPDF 的 HTML 轉 PDF 轉換功能。 若要建立基於視圖的 PDF,請採用傳統的 MVC 架構,或考慮使用 Razor Pages 作為替代方案。
如何新增模型類別?
- 導航至"Models"資料夾。
- 建立一個名為"Person"的新 C# 類別檔案。此類別將作為模型,用以表示個人資料。 請使用以下程式碼片段:
:path=/static-assets/pdf/content-code-examples/how-to/cshtml-to-pdf-mvc-core-model.cs
namespace ViewToPdfMVCCoreSample.Models
{
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
}
Namespace ViewToPdfMVCCoreSample.Models
Public Class Person
Public Property Id() As Integer
Public Property Name() As String
Public Property Title() As String
Public Property Description() As String
End Class
End Namespace
為什麼我需要一個 PDF 生成模型?
模型提供結構化資料,這些資料可傳遞至視圖進行渲染。 這種關注點的分離,可確保您的 PDF 生成邏輯保持簡潔且易於維護。 此模型作為控制器與視圖之間的契約,確保類型安全性,並使您的 Razor 視圖能支援 IntelliSense。
哪些資料類型最適合用於 Views?
針對 PDF 生成,建議使用簡單的資料類型和集合。 可使用複雜的嵌套物件,但可能需要額外的檢視邏輯。 為獲得最佳效能,請在將複雜資料結構傳遞至檢視層之前,先在控制器中將其扁平化。 當您的領域模型過於複雜時,請考慮使用專為 PDF 輸出設計的 ViewModels。
以下是一個適用於 PDF 生成的較複雜模型結構範例:
public class InvoiceViewModel
{
public string InvoiceNumber { get; set; }
public DateTime InvoiceDate { get; set; }
public decimal TotalAmount { get; set; }
public List<InvoiceLineItem> LineItems { get; set; }
public CustomerInfo Customer { get; set; }
// Computed property for PDF display
public string FormattedTotal => TotalAmount.ToString("C");
}
public class InvoiceLineItem
{
public string Description { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal LineTotal => Quantity * UnitPrice;
}
public class CustomerInfo
{
public string Name { get; set; }
public string Email { get; set; }
public string Address { get; set; }
}
public class InvoiceViewModel
{
public string InvoiceNumber { get; set; }
public DateTime InvoiceDate { get; set; }
public decimal TotalAmount { get; set; }
public List<InvoiceLineItem> LineItems { get; set; }
public CustomerInfo Customer { get; set; }
// Computed property for PDF display
public string FormattedTotal => TotalAmount.ToString("C");
}
public class InvoiceLineItem
{
public string Description { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public decimal LineTotal => Quantity * UnitPrice;
}
public class CustomerInfo
{
public string Name { get; set; }
public string Email { get; set; }
public string Address { get; set; }
}
Public Class InvoiceViewModel
Public Property InvoiceNumber As String
Public Property InvoiceDate As DateTime
Public Property TotalAmount As Decimal
Public Property LineItems As List(Of InvoiceLineItem)
Public Property Customer As CustomerInfo
' Computed property for PDF display
Public ReadOnly Property FormattedTotal As String
Get
Return TotalAmount.ToString("C")
End Get
End Property
End Class
Public Class InvoiceLineItem
Public Property Description As String
Public Property Quantity As Integer
Public Property UnitPrice As Decimal
Public ReadOnly Property LineTotal As Decimal
Get
Return Quantity * UnitPrice
End Get
End Property
End Class
Public Class CustomerInfo
Public Property Name As String
Public Property Email As String
Public Property Address As String
End Class
如何編輯控制器?
請導航至"Controllers"資料夾並開啟 HomeController.cs 檔案。我們僅會修改 HomeController 並新增 Persons 動作。 請參考以下程式碼作為指引:
以下程式碼首先實例化 ChromePdfRenderer 類別,傳入 IRazorViewRenderer、我們的 Views/Home/Persons.cshtml 路徑,以及包含所需資料的 List 傳遞給 RenderRazorViewToPdf 方法。 使用者可透過 RenderingOptions 存取多項功能,例如新增自訂文字、在生成的 PDF 中加入 HTML 頁首與頁尾、設定自訂邊界,以及套用頁碼。 如需更進階的渲染選項,請參閱渲染選項文件。
File(pdf.BinaryData, "application/pdf")。 然而,在瀏覽器中檢視後下載該 PDF 檔案,會導致 PDF 文件損壞。)}]using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ViewToPdfMVCCoreSample.Models;
namespace ViewToPdfMVCCoreSample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IRazorViewRenderer _viewRenderService;
private readonly IHttpContextAccessor _httpContextAccessor;
public HomeController(ILogger<HomeController> logger, IRazorViewRenderer viewRenderService, IHttpContextAccessor httpContextAccessor)
{
_logger = logger;
_viewRenderService = viewRenderService;
_httpContextAccessor = httpContextAccessor;
}
public IActionResult Index()
{
return View();
}
public async Task<IActionResult> Persons()
{
// Example list of persons
var persons = new List<Person>
{
new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" },
new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" },
new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" }
};
// Check if the request method is POST
if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method)
{
// Create a new PDF renderer
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Configure rendering options for better output
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
renderer.RenderingOptions.Title = "Persons Report";
// Render View to PDF document
PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons);
Response.Headers.Add("Content-Disposition", "inline");
// Output PDF document
return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf");
}
return View(persons);
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using ViewToPdfMVCCoreSample.Models;
namespace ViewToPdfMVCCoreSample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IRazorViewRenderer _viewRenderService;
private readonly IHttpContextAccessor _httpContextAccessor;
public HomeController(ILogger<HomeController> logger, IRazorViewRenderer viewRenderService, IHttpContextAccessor httpContextAccessor)
{
_logger = logger;
_viewRenderService = viewRenderService;
_httpContextAccessor = httpContextAccessor;
}
public IActionResult Index()
{
return View();
}
public async Task<IActionResult> Persons()
{
// Example list of persons
var persons = new List<Person>
{
new Person { Name = "Alice", Title = "Mrs.", Description = "Software Engineer" },
new Person { Name = "Bob", Title = "Mr.", Description = "Software Engineer" },
new Person { Name = "Charlie", Title = "Mr.", Description = "Software Engineer" }
};
// Check if the request method is POST
if (_httpContextAccessor.HttpContext.Request.Method == HttpMethod.Post.Method)
{
// Create a new PDF renderer
ChromePdfRenderer renderer = new ChromePdfRenderer();
// Configure rendering options for better output
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait;
renderer.RenderingOptions.Title = "Persons Report";
// Render View to PDF document
PdfDocument pdf = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons);
Response.Headers.Add("Content-Disposition", "inline");
// Output PDF document
return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf");
}
return View(persons);
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc
Imports System.Diagnostics
Imports ViewToPdfMVCCoreSample.Models
Namespace ViewToPdfMVCCoreSample.Controllers
Public Class HomeController
Inherits Controller
Private ReadOnly _logger As ILogger(Of HomeController)
Private ReadOnly _viewRenderService As IRazorViewRenderer
Private ReadOnly _httpContextAccessor As IHttpContextAccessor
Public Sub New(logger As ILogger(Of HomeController), viewRenderService As IRazorViewRenderer, httpContextAccessor As IHttpContextAccessor)
_logger = logger
_viewRenderService = viewRenderService
_httpContextAccessor = httpContextAccessor
End Sub
Public Function Index() As IActionResult
Return View()
End Function
Public Async Function Persons() As Task(Of IActionResult)
' Example list of persons
Dim persons = New List(Of Person) From {
New Person With {.Name = "Alice", .Title = "Mrs.", .Description = "Software Engineer"},
New Person With {.Name = "Bob", .Title = "Mr.", .Description = "Software Engineer"},
New Person With {.Name = "Charlie", .Title = "Mr.", .Description = "Software Engineer"}
}
' Check if the request method is POST
If _httpContextAccessor.HttpContext.Request.Method = HttpMethod.Post.Method Then
' Create a new PDF renderer
Dim renderer As New ChromePdfRenderer()
' Configure rendering options for better output
renderer.RenderingOptions.MarginTop = 40
renderer.RenderingOptions.MarginBottom = 40
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Portrait
renderer.RenderingOptions.Title = "Persons Report"
' Render View to PDF document
Dim pdf As PdfDocument = renderer.RenderRazorViewToPdf(_viewRenderService, "Views/Home/Persons.cshtml", persons)
Response.Headers.Add("Content-Disposition", "inline")
' Output PDF document
Return File(pdf.BinaryData, "application/pdf", "viewToPdfMVCCore.pdf")
End If
Return View(persons)
End Function
Public Function Privacy() As IActionResult
Return View()
End Function
<ResponseCache(Duration:=0, Location:=ResponseCacheLocation.None, NoStore:=True)>
Public Function Error() As IActionResult
Return View(New ErrorViewModel With {.RequestId = If(Activity.Current?.Id, HttpContext.TraceIdentifier)})
End Function
End Class
End Namespace
使用 RenderRazorViewToPdf 方法後,您將獲得一個 PdfDocument 物件,該物件可供進一步增強與修改。 您可以將 PDF 轉換為 PDF/A 或 PDF/UA 格式,在生成的 PDF 中添加數位簽名,或根據需要合併及分割 PDF 文件。 此外,此函式庫還可讓您旋轉頁面、插入註解或書籤,並在 PDF 檔案上加蓋獨特的水印。
何謂 IRazorViewRenderer 服務?
IRazorViewRenderer 是由 IronPdf.Extensions.Mvc.Core 套件提供的服務介面,負責將 Razor 檢視轉換為 HTML。 它與 ASP.NET Core 的檢視引擎整合,用於處理 .cshtml 檔案及其相關模型,執行所有 Razor 語法,並產生最終的 HTML,該 HTML 將由 IronPDF 轉換為 PDF。
為何要在渲染前檢查 POST 方法?
透過檢查 POST 請求,可確保僅在透過表單提交明確要求時,才會產生 PDF 檔案。 此設計可防止頁面載入時意外產生 PDF,並讓同一操作同時支援 HTML 檢視(GET 請求)與 PDF 下載(POST 請求)。 此模式遵循 RESTful 原則,並提供更佳的使用者體驗。
如何自訂 PDF 輸出?
IronPDF 透過 RenderingOptions 屬性提供廣泛的自訂選項。 以下是一個包含進階設定的範例:
// Advanced rendering configuration example
var renderer = new ChromePdfRenderer();
// Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
// Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
Height = 25,
HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
};
// JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = new WaitFor()
{
RenderDelay = 500, // Wait 500ms for JS execution
NetworkIdle = NetworkIdleTypes.NetworkIdle0 // Wait for network requests
};
// Apply watermark
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
DrawDividerLine = true,
CenterText = "CONFIDENTIAL",
Font = new FontTypes() { FontSize = 16 }
};
// Advanced rendering configuration example
var renderer = new ChromePdfRenderer();
// Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
// Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter()
{
Height = 25,
HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
};
// JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = new WaitFor()
{
RenderDelay = 500, // Wait 500ms for JS execution
NetworkIdle = NetworkIdleTypes.NetworkIdle0 // Wait for network requests
};
// Apply watermark
renderer.RenderingOptions.TextHeader = new TextHeaderFooter()
{
DrawDividerLine = true,
CenterText = "CONFIDENTIAL",
Font = new FontTypes() { FontSize = 16 }
};
' Advanced rendering configuration example
Dim renderer As New ChromePdfRenderer()
' Page setup
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
' Headers and footers with merge fields
renderer.RenderingOptions.HtmlHeader = New HtmlHeaderFooter() With {
.Height = 25,
.HtmlFragment = "<div style='text-align: center; font-size: 12px;'>Page {page} of {total-pages}</div>"
}
' JavaScript execution delay for dynamic content
renderer.RenderingOptions.WaitFor = New WaitFor() With {
.RenderDelay = 500, ' Wait 500ms for JS execution
.NetworkIdle = NetworkIdleTypes.NetworkIdle0 ' Wait for network requests
}
' Apply watermark
renderer.RenderingOptions.TextHeader = New TextHeaderFooter() With {
.DrawDividerLine = True,
.CenterText = "CONFIDENTIAL",
.Font = New FontTypes() With {.FontSize = 16}
}
常見的控制器錯誤有哪些?
常見錯誤包括:服務未正確注入時產生的 null 參考例外、指定檢視位置時的路徑問題,以及模型綁定問題。 請確保所有必要服務均已註冊於 Program.cs,並在指定檢視位置時使用從專案根目錄起算的相對路徑。 若需進行疑難排解,請在開發模式下啟用詳細錯誤訊息。
如何新增檢視?
- 右鍵點擊新加入的
Person動作,並選擇"新增檢視"。

- 為新的 Scaffolded 項目選擇"Razor View"。

- 請選擇"List"範本及
Person模型類別。

這會產生一個名為 Persons 的 .cshtml 檔案。
- 導航至"Views"資料夾 -> "首頁"資料夾 ->
Persons.cshtml檔案。
IronPdf.Extensions.Mvc.Core
若要新增一個可觸發 Persons 動作的按鈕,請使用以下程式碼:
@using (Html.BeginForm("Persons", "Home", FormMethod.Post))
{
<input type="submit" value="Print Person" />
}
@using (Html.BeginForm("Persons", "Home", FormMethod.Post))
{
<input type="submit" value="Print Person" />
}
為何使用 FormMethod.Post 來生成 PDF?
使用 FormMethod.Post 來生成 PDF 符合網頁最佳實務,此做法能明確標示該動作,並防止因瀏覽器重新整理或書籤連結而意外產生 PDF 檔案。 POST 請求應為冪等(不改變伺服器狀態),而 POST 請求則表示會產生結果的操作——在此情況下,即生成 PDF 文件。
如何自訂 PDF 列印按鈕的樣式?
請使用 CSS 類別為 PRINT 按鈕設定樣式,並透過 JavaScript 進行強化,以提升使用者體驗。 以下是改進後的版本:
@using (Html.BeginForm("Persons", "Home", FormMethod.Post, new { @class = "pdf-form" }))
{
<button type="submit" class="btn btn-primary pdf-download-btn">
<i class="fas fa-file-pdf"></i> Download as PDF
</button>
}
<style>
.pdf-download-btn {
background-color: #dc3545;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.pdf-download-btn:hover {
background-color: #c82333;
}
.pdf-download-btn:active {
transform: translateY(1px);
}
</style>
<script>
// Optional: Show loading indicator during PDF generation
document.querySelector('.pdf-form').addEventListener('submit', function() {
const button = this.querySelector('button');
button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Generating PDF...';
button.disabled = true;
});
</script>
@using (Html.BeginForm("Persons", "Home", FormMethod.Post, new { @class = "pdf-form" }))
{
<button type="submit" class="btn btn-primary pdf-download-btn">
<i class="fas fa-file-pdf"></i> Download as PDF
</button>
}
<style>
.pdf-download-btn {
background-color: #dc3545;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.pdf-download-btn:hover {
background-color: #c82333;
}
.pdf-download-btn:active {
transform: translateY(1px);
}
</style>
<script>
// Optional: Show loading indicator during PDF generation
document.querySelector('.pdf-form').addEventListener('submit', function() {
const button = this.querySelector('button');
button.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Generating PDF...';
button.disabled = true;
});
</script>
哪些檢視範本最適合用於 PDF?
List 和 Details 範本特別適合用於 PDF 生成,因為它們提供了結構化的版面配置。 專為 PDF 輸出設計的自訂範本通常能產生最佳效果。 建議建立專用的 PDF 檢視模式,針對列印版面進行優化(而非螢幕顯示),移除導覽元素並著重於內容呈現。
如何在頂部導覽列中新增區塊?
- 在同一個"Views"資料夾中,導航至"Shared"資料夾 ->
_Layout.cshtml。 請將Person導覽項目置於Home之後。
請確保 asp-action 屬性的值與我們的檔案名稱完全一致,本例中為 Persons。
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ViewToPdfMVCCoreSample</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Persons">Person</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">ViewToPdfMVCCoreSample</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Persons">Person</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
為什麼 asp-action 必須完全匹配?
asp-action 屬性會利用 .NET Core 的標籤輔助程式,根據您的路由設定產生正確的 URL。 精確匹配可確保連結能正確解析至對應的控制器動作。 若設定不符,將導致 404 錯誤或被導向至非預期的操作。 標籤輔助程式系統會區分大小寫,且必須與控制器中的方法名稱完全相符。
若導覽連結不匹配會發生什麼情況?
當導覽連結與控制器動作不匹配時,使用者會遇到 404 錯誤或被導向至錯誤的頁面。 在開發過程中,ASP.NET Core 的開發者例外頁面會顯示詳細的路由錯誤。 在生產環境中,使用者會看到通用錯誤頁面。 請務必確認導覽連結與控制器動作名稱完全一致,以避免造成使用者體驗中斷。
如何編輯 Program.cs 檔案?
將 IHttpContextAccessor 和 IRazorViewRenderer 介面註冊至依賴注入 (DI) 容器中。 請參閱以下程式碼作為參考。
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
// Register IRazorViewRenderer here
builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>();
// Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
using IronPdf.Extensions.Mvc.Core;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
// Register IRazorViewRenderer here
builder.Services.AddSingleton<IRazorViewRenderer, RazorViewRenderer>();
// Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE";
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Imports IronPdf.Extensions.Mvc.Core
Imports Microsoft.AspNetCore.Mvc.ViewFeatures
Dim builder = WebApplication.CreateBuilder(args)
' Add services to the container.
builder.Services.AddControllersWithViews()
builder.Services.AddSingleton(Of IHttpContextAccessor, HttpContextAccessor)()
builder.Services.AddSingleton(Of ITempDataProvider, CookieTempDataProvider)()
' Register IRazorViewRenderer here
builder.Services.AddSingleton(Of IRazorViewRenderer, RazorViewRenderer)()
' Optional: Configure IronPDF license if you have one
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY-HERE"
Dim app = builder.Build()
' Configure the HTTP request pipeline.
If Not app.Environment.IsDevelopment() Then
app.UseExceptionHandler("/Home/Error")
' The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts()
End If
app.UseHttpsRedirection()
app.UseStaticFiles()
app.UseRouting()
app.UseAuthorization()
app.MapControllerRoute(
name:="default",
pattern:="{controller=Home}/{action=Index}/{id?}")
app.Run()
為何要將服務註冊為單例?
單例服務僅建立一次,並在應用程式的整個生命週期中重複使用,因此對於 IRazorViewRenderer 之類的無狀態服務而言,其效能極佳。 由於視圖渲染服務不會維持特定於請求的狀態,此模式可降低記憶體開銷並提升效能。 IHttpContextAccessor 必須是單例,才能在不同的服務生命週期中被存取。
ITempDataProvider 的用途為何?
ITempDataProvider 允許在請求之間進行臨時資料儲存,通常用於在重定向後顯示訊息。 在 PDF 生成方面,它確保將視圖渲染為 PDF 時,能正確維持視圖狀態。 CookieTempDataProvider 將此臨時資料儲存於加密的 Cookie 中,提供了一種安全的狀態管理機制。
我可以使用 Scoped Services 來替代嗎?
雖然在某些情境下可以使用範圍服務,但 IRazorViewRenderer 作為單例運作效果最佳,因為它不保留特定於請求的狀態。 若使用範圍限定服務,將會為每個請求建立新的實例,這會增加記憶體使用量卻無實質效益。 然而,若您需要在檢視中注入作用域服務,請確保妥善管理服務的生命週期,以避免執行時錯誤。
執行專案
此處說明如何執行專案並產生 PDF 文件。 執行應用程式後,請透過頂部導覽選單前往 Persons 頁面,然後點擊 Print Person 按鈕以產生並下載 PDF 檔案。
我該去哪裡下載 ASP.NET Core MVC 專案?
下載本指南的完整程式碼。此檔案為 ZIP 檔,您可在 Visual Studio 中將其開啟為 ASP.NET Core Web App (Model-View-Controller) 專案。
範例專案包含哪些內容?
範例專案包含一個已完整配置且整合 IronPDF 的 ASP.NET Core MVC 應用程式,用以展示視圖轉 PDF 的功能。 其中包含 Person 模型、內含 PDF 生成邏輯的 HomeController、採用正確 Razor 語法的 Persons 檢視,以及 Program.cs 中的所有必要服務註冊。 本專案亦包含針對 PDF 輸出所優化的範例樣式與版面配置。
我應該使用哪個 Visual Studio 版本?
建議使用 Visual Studio 2022(版本 17.0 或更新)以獲得最佳的 .NET 6+ 專案開發體驗。 搭配 C# 擴充套件的 Visual Studio Code 亦非常適合用於跨平台開發。 請確認您已安裝 ASP.NET 及網頁開發工作負載。 本專案預設針對 .NET 6.0,但可更新至較新版本。
如何排除專案設定問題?
常見的設定問題包括缺少 NuGet 套件、.NET SDK 版本不正確,或配置問題。 首先,請使用 dotnet restore 或透過 Visual Studio 的套件管理員還原 NuGet 套件。 請使用 dotnet --version 確認您的 .NET SDK 版本符合專案需求。 有關授權事宜,請參閱授權金鑰文件。 若發生渲染問題,請參閱疑難排解指南以獲取解決方案。
準備好探索更多可能性了嗎? 請點此查看我們的教學頁面:PDF 轉換
常見問題
在 ASP.NET Core MVC 中,將 CSHTML 檢視轉換為 PDF 的最簡單方法是什麼?
最簡單的方法是使用 IronPDF 的 RenderRazorViewToPdf 方法,只需一行程式碼即可將您的 .cshtml 檔案轉換為 PDF 文件。只需呼叫:new IronPdf.ChromePdfRenderer().RenderRazorViewToPdf(HttpContext, "Views/首頁/Report.cshtml", model).SaveAs("report.pdf");
在 ASP.NET Core MVC 中,我需要哪些 NuGet 套件才能將視圖轉換為 PDF?
您需要兩個套件:IronPdf(主套件)和 IronPdf.Extensions.Mvc.Core(擴充套件)。擴充套件提供特定功能,用於與 ASP.NET Core 的依賴注入系統及 Razor 視圖渲染管道進行整合。
在將 CSHTML 轉換為 PDF/A 時,是否可以套用 CSS 樣式和 JavaScript?
是的,IronPDF 在將網頁視圖渲染為 PDF 時,完全支援 CSS 樣式、JavaScript 執行以及自訂字型。這確保您的 PDF 能維持與網頁視圖相同的外觀與功能,包括響應式 CSS 及動態 JavaScript 內容。
在我的 ASP.NET Core MVC 專案中,要實現「檢視轉 PDF」功能的主要步驟有哪些?
工作流程包含 5 個步驟:1) 下載 IronPDF 及其 MVC Core 擴充套件,2) 為您的資料新增模型類別,3) 編輯控制器以使用 RenderRazorViewToPdf 方法,4) 建立或修改用於 PDF 渲染的視圖(.cshtml 檔案),以及 5) 執行應用程式以產生 PDF 檔案。
MVC 模式如何透過視圖 (Views) 來生成 PDF?
在 ASP.NET Core MVC 中,Model 包含您的資料與業務邏輯;View(您的 .cshtml 檔案)負責呈現使用者介面並顯示資料;Controller 則處理請求,並使用 IronPDF 的 RenderRazorViewToPdf 方法,根據 View 內容協調 PDF 的生成。

