跳過到頁腳內容
使用IRONPDF

如何在 Blazor 中顯示 PDF(指南)

介紹

在現代 Web 應用程式中,Blazor 顯示 PDF 功能需要一個強大的 PDF 檢視元件,超越基本的瀏覽器能力。 For .NET developers building Blazor applications, IronPDF provides a powerful PDF viewer solution that seamlessly integrates with your Blazor Server app. 這使您能夠在不依賴第三方瀏覽器工具的情況下顯示具有高性能和豐富功能的 PDF 文件。

在本教程中,我們將探討如何使用 IronPDF 實施 Blazor PDF 檢視器,創建一個 PDF 檢視元件,可以打開 PDF 檔案、處理 PDF 內容,並為用戶提供一個直觀的界面,以便在桌面和手機上顯示 PDF。

開始使用 IronPDF 顯示 PDF

在實現您的 Blazor PDF 檢視器之前,您需要安裝 IronPDF。 通過 NuGet 將其添加到您的 Blazor 服務器應用程式中:

Install-Package IronPdf

接下來,創建一個新的 Blazor 應用程式,並確保您已安裝最新版本的 .NET Core。 將您的 PDF 文件存儲在 wwwroot 資料夾中以便訪問,或準備從其他來源(例如字節數組或 URL)加載它們。

創建您的第一個 Blazor PDF 檢視元件

讓我們構建一個基本的 Blazor PDF 檢視元件,可以顯示 PDF 文件。 首先,創建一個新的 Razor 元件:

@page "/pdfviewer"
@rendermode InteractiveServer
@using IronPdf
@inject IJSRuntime JSRuntime
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment WebHostEnvironment
<h3>PDF Viewer Component</h3>
<div>
    <button @onclick="LoadPdfDocument">Open File</button>
    <div id="pdfContainer">
        @if (!string.IsNullOrEmpty(pdfUrl))
        {
            <iframe src="@pdfUrl" style="width:100%; height:600px;"></iframe>
        }
    </div>
</div>
@code {
    private string pdfUrl = "";
    private byte[] pdfData;
    private async Task LoadPdfDocument()
    {
        // Load PDF from file
        var pdfDocument = PdfDocument.FromFile("wwwroot/sample.pdf");
        pdfData = pdfDocument.BinaryData;
        // Create object URL for display
        pdfUrl = await CreateObjectUrl(pdfData);
    }
    private async Task<string> CreateObjectUrl(byte[] data)
    {
        var base64 = Convert.ToBase64String(data);
        return $"data:application/pdf;base64,{base64}";
    }
}
@page "/pdfviewer"
@rendermode InteractiveServer
@using IronPdf
@inject IJSRuntime JSRuntime
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment WebHostEnvironment
<h3>PDF Viewer Component</h3>
<div>
    <button @onclick="LoadPdfDocument">Open File</button>
    <div id="pdfContainer">
        @if (!string.IsNullOrEmpty(pdfUrl))
        {
            <iframe src="@pdfUrl" style="width:100%; height:600px;"></iframe>
        }
    </div>
</div>
@code {
    private string pdfUrl = "";
    private byte[] pdfData;
    private async Task LoadPdfDocument()
    {
        // Load PDF from file
        var pdfDocument = PdfDocument.FromFile("wwwroot/sample.pdf");
        pdfData = pdfDocument.BinaryData;
        // Create object URL for display
        pdfUrl = await CreateObjectUrl(pdfData);
    }
    private async Task<string> CreateObjectUrl(byte[] data)
    {
        var base64 = Convert.ToBase64String(data);
        return $"data:application/pdf;base64,{base64}";
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

此代碼創建了一個簡單的 PDF 檢視元件,使用 iframe 加載並顯示 PDF 文件。 LoadPdfDocument 方法從相同路徑(wwwroot 資料夾)讀取 PDF 文件並將其轉換為字節數組。 CreateObjectUrl 方法然後將此字節數組轉換為數據 URL,讓 iframe 可以顯示,以便用戶輕鬆查看加載的 PDF 文件。

輸出

如何在 Blazor 中顯示 PDF (指南):圖 1

實現 JavaScript Interop 以增強顯示

為了更好地控制 PDF 內容顯示,我們可以使用 JavaScript 函數來處理 PDF 檢視功能:

@page "/pdf-jsinterop"
@rendermode InteractiveServer
@using IronPdf
@inject IJSRuntime JSRuntime
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment WebHostEnvironment
<h3>IronPDF JavaScript Interop Viewer</h3>
<p>Displays PDF using JavaScript's Blob/ObjectURL capabilities.</p>
@if (!string.IsNullOrEmpty(ErrorMessage))
{
    <div class="alert alert-danger">Error: @ErrorMessage</div>
}
<div id="@documentId" style="border: 1px solid #ccc; width: 100%; min-height: 600px;">
    Loading PDF...
</div>
@code {
    private string documentId = Guid.NewGuid().ToString();
    private string ErrorMessage = string.Empty;
    private bool pdfLoaded = false;
    // Hold the reference to the loaded JavaScript module
    private IJSObjectReference? jsModule;
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender && !pdfLoaded)
        {
            try
            {
                // 1. Asynchronously load the JavaScript file as a module
                // This guarantees the script is loaded before the next line executes.
                jsModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import",
                    "./pdfViewerInterop.js");
                await LoadPdfWithJavaScript();
                pdfLoaded = true;
            }
            catch (Exception ex)
            {
                ErrorMessage = $"Failed to load JS module or execute: {ex.Message}";
            }
            finally
            {
                StateHasChanged();
            }
        }
    }
    private async Task LoadPdfWithJavaScript()
    {
        if (jsModule is null) return; // Should never happen if the module loads successfully
        try
        {
            var pdfPath = Path.Combine(WebHostEnvironment.WebRootPath, "sample.pdf");
            if (!File.Exists(pdfPath))
            {
                ErrorMessage = $"File not found: {pdfPath}";
                return;
            }
            var pdf = PdfDocument.FromFile(pdfPath);
            var stream = new MemoryStream(pdf.BinaryData);
            // 2. Invoke the function using the module reference
            // Note: We only pass the function name here.
            await jsModule.InvokeVoidAsync("displayPdf",
                documentId, stream.ToArray());
        }
        catch (Exception ex)
        {
            ErrorMessage = $"Failed to load PDF or invoke JS: {ex.Message}";
        }
    }
    // IMPORTANT: Dispose of the module when the component is removed
    public async ValueTask DisposeAsync()
    {
        if (jsModule is not null)
        {
            await jsModule.DisposeAsync();
        }
    }
}
@page "/pdf-jsinterop"
@rendermode InteractiveServer
@using IronPdf
@inject IJSRuntime JSRuntime
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment WebHostEnvironment
<h3>IronPDF JavaScript Interop Viewer</h3>
<p>Displays PDF using JavaScript's Blob/ObjectURL capabilities.</p>
@if (!string.IsNullOrEmpty(ErrorMessage))
{
    <div class="alert alert-danger">Error: @ErrorMessage</div>
}
<div id="@documentId" style="border: 1px solid #ccc; width: 100%; min-height: 600px;">
    Loading PDF...
</div>
@code {
    private string documentId = Guid.NewGuid().ToString();
    private string ErrorMessage = string.Empty;
    private bool pdfLoaded = false;
    // Hold the reference to the loaded JavaScript module
    private IJSObjectReference? jsModule;
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender && !pdfLoaded)
        {
            try
            {
                // 1. Asynchronously load the JavaScript file as a module
                // This guarantees the script is loaded before the next line executes.
                jsModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import",
                    "./pdfViewerInterop.js");
                await LoadPdfWithJavaScript();
                pdfLoaded = true;
            }
            catch (Exception ex)
            {
                ErrorMessage = $"Failed to load JS module or execute: {ex.Message}";
            }
            finally
            {
                StateHasChanged();
            }
        }
    }
    private async Task LoadPdfWithJavaScript()
    {
        if (jsModule is null) return; // Should never happen if the module loads successfully
        try
        {
            var pdfPath = Path.Combine(WebHostEnvironment.WebRootPath, "sample.pdf");
            if (!File.Exists(pdfPath))
            {
                ErrorMessage = $"File not found: {pdfPath}";
                return;
            }
            var pdf = PdfDocument.FromFile(pdfPath);
            var stream = new MemoryStream(pdf.BinaryData);
            // 2. Invoke the function using the module reference
            // Note: We only pass the function name here.
            await jsModule.InvokeVoidAsync("displayPdf",
                documentId, stream.ToArray());
        }
        catch (Exception ex)
        {
            ErrorMessage = $"Failed to load PDF or invoke JS: {ex.Message}";
        }
    }
    // IMPORTANT: Dispose of the module when the component is removed
    public async ValueTask DisposeAsync()
    {
        if (jsModule is not null)
        {
            await jsModule.DisposeAsync();
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

將此 JavaScript 函數添加到 wwwroot 資料夾中的 JavaScript 文件中:

export function displayPdf(elementId, data) {
    // 1. Create a Blob from the byte array data
    const blob = new Blob([new Uint8Array(data)],
        { type: 'application/pdf' });
    // 2. Create a temporary URL for the Blob
    const url = URL.createObjectURL(blob);
    // 3. Find the container element
    const container = document.getElementById(elementId);
    if (!container) return;
    // 4. Clear any previous content
    container.innerHTML = '';
    // 5. Create and configure the iframe
    const iframe = document.createElement('iframe');
    iframe.src = url;
    iframe.style.width = '100%';
    iframe.style.height = '600px';
    iframe.style.border = 'none';
    // 6. Append the iframe to the container
    container.appendChild(iframe);
}
export function displayPdf(elementId, data) {
    // 1. Create a Blob from the byte array data
    const blob = new Blob([new Uint8Array(data)],
        { type: 'application/pdf' });
    // 2. Create a temporary URL for the Blob
    const url = URL.createObjectURL(blob);
    // 3. Find the container element
    const container = document.getElementById(elementId);
    if (!container) return;
    // 4. Clear any previous content
    container.innerHTML = '';
    // 5. Create and configure the iframe
    const iframe = document.createElement('iframe');
    iframe.src = url;
    iframe.style.width = '100%';
    iframe.style.height = '600px';
    iframe.style.border = 'none';
    // 6. Append the iframe to the container
    container.appendChild(iframe);
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

此 JavaScript 函數從 PDF 數據創建一個 blob 並生成一個對象 URL。 然後它動態創建一個 iframe 元件並將其附加到容器。 這種方法讓您對 PDF 頁面的顯示有更多控制,並允許更好地處理 PDF 檢視元件的生命週期。

輸出

如何在 Blazor 中顯示 PDF (指南):圖 2 - JavaScript PDF 檢視器

從不同來源加載 PDF 文件

您的 Blazor PDF 檢視器可以從多個來源檢索和顯示 PDF 文件:

private async Task LoadFromUrl()
{
    var client = new HttpClient();
    var response = await client.GetAsync("https://example.com/file.pdf");
    var stream = await response.Content.ReadAsStreamAsync();
    var pdfDocument = new PdfDocument(stream);
    await DisplayPdfContent(pdfDocument);
}
private async Task LoadFromHtmlContent()
{
    var renderer = new ChromePdfRenderer();
    var htmlContent = "<h1>Generated PDF</h1>";
    var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
    await DisplayPdfContent(pdfDocument);
}
private async Task DisplayPdfContent(PdfDocument document)
{
    var data = document.BinaryData;
    pdfUrl = $"data:application/pdf;base64,{Convert.ToBase64String(data)}";
}
private async Task LoadFromUrl()
{
    var client = new HttpClient();
    var response = await client.GetAsync("https://example.com/file.pdf");
    var stream = await response.Content.ReadAsStreamAsync();
    var pdfDocument = new PdfDocument(stream);
    await DisplayPdfContent(pdfDocument);
}
private async Task LoadFromHtmlContent()
{
    var renderer = new ChromePdfRenderer();
    var htmlContent = "<h1>Generated PDF</h1>";
    var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
    await DisplayPdfContent(pdfDocument);
}
private async Task DisplayPdfContent(PdfDocument document)
{
    var data = document.BinaryData;
    pdfUrl = $"data:application/pdf;base64,{Convert.ToBase64String(data)}";
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

這些方法示範了使用 HTTPS 從 URL 加載 PDF 文件、將 HTML 內容轉換為 PDF 並顯示生成的 PDF 內容。 LoadFromUrl 方法從遠程位置檢索 PDF 文件,而 LoadFromHtmlContent 顯示如何動態將 HTML 轉換為 PDF,為您的 Blazor PDF 檢視元件如何獲得內容提供靈活性。

輸出 using HTML Content

如何在 Blazor 中顯示 PDF (指南):圖 3 - 由 HTML 生成並顯示的 PDF

添加交互功能

為您的 PDF 檢視器增強交互功能:

@code {
    private int currentPage = 1;
    private int totalPages;
    private string rotationClass = "";
    private async Task NavigateToPage(int page)
    {
        currentPage = page;
        await JSRuntime.InvokeVoidAsync("navigateTo", page);
    }
    private void RotateCounterclockwise()
    {
        // Counterclockwise switch orientation
        rotationClass = "rotate-270";
    }
    private async Task PrintPdf()
    {
        await JSRuntime.InvokeVoidAsync("printDocument", documentId);
    }
    private async Task DownloadPdf()
    {
        var fileName = "document.pdf";
        await JSRuntime.InvokeVoidAsync("downloadFile", 
           pdfData, fileName);
    }
}
@code {
    private int currentPage = 1;
    private int totalPages;
    private string rotationClass = "";
    private async Task NavigateToPage(int page)
    {
        currentPage = page;
        await JSRuntime.InvokeVoidAsync("navigateTo", page);
    }
    private void RotateCounterclockwise()
    {
        // Counterclockwise switch orientation
        rotationClass = "rotate-270";
    }
    private async Task PrintPdf()
    {
        await JSRuntime.InvokeVoidAsync("printDocument", documentId);
    }
    private async Task DownloadPdf()
    {
        var fileName = "document.pdf";
        await JSRuntime.InvokeVoidAsync("downloadFile", 
           pdfData, fileName);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

這段代碼添加了 PDF 頁面之間的導航、旋轉功能(包括逆時針旋轉方向)以及打印 PDF 的功能。 下載功能允許用戶將 PDF 文件保存到本地。 這些功能將您的基本 PDF 檢視器轉變為一個強大的 PDF 檢視器,內置工具欄提供用戶使用 PDF 文件所需的基本功能。

輸出

如何在 Blazor 中顯示 PDF (指南):圖 4 - 具有自訂交互功能的 PDF 檢視器

處理 PDF 表單填充和註解

對於具有表單欄位和註解的 PDF 文件,IronPDF 提供了強大的支持:

private async Task ProcessFormFields(
{
    var pdfDocument = PdfDocument.FromFile("form.pdf");
    foreach (var field in pdfDocument.Form.Fields)
    {
        if (field.Type == PdfFormFieldType.Text)
        {
            field.Value = "User Input";
        }
    }
    // Enable form filling in viewer
    var modifiedPdf = pdfDocument.BinaryData;
    await DisplayPdfContent(pdfDocument);
}
private async Task ProcessFormFields(
{
    var pdfDocument = PdfDocument.FromFile("form.pdf");
    foreach (var field in pdfDocument.Form.Fields)
    {
        if (field.Type == PdfFormFieldType.Text)
        {
            field.Value = "User Input";
        }
    }
    // Enable form filling in viewer
    var modifiedPdf = pdfDocument.BinaryData;
    await DisplayPdfContent(pdfDocument);
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

這樣可以在您的 Blazor PDF 檢視器元件中啟用表單填充功能,允許用戶直接在瀏覽器中與表單欄位互動。 該代碼遍歷 PDF 文件中的表單欄位並可以以程式方式設置值,這對於需要動態表單填充的應用程式非常理想。

輸出

如何在 Blazor 中顯示 PDF (指南):圖 5 - 顯示帶有表單填充的 PDF

性能優化

為確保顯示 PDF 時的高性能,特別是對於大型 PDF 文件:

private async Task LoadLargePdf()
{
    const int chunkSize = 1024 * 1024; // 1MB chunks
    var pdfPath = "largefile.pdf";
    using (var fileStream = File.OpenRead(pdfPath))
    {
        var buffer = new byte[chunkSize];
        var chunks = new List<byte[]>();
        int bytesRead;
        while ((bytesRead = await fileStream.ReadAsync(buffer)) > 0)
        {
            var chunk = new byte[bytesRead];
            Array.Copy(buffer, chunk, bytesRead);
            chunks.Add(chunk);
        }
        // Process chunks for display
        await ProcessPdfChunks(chunks);
    }
}
private async Task LoadLargePdf()
{
    const int chunkSize = 1024 * 1024; // 1MB chunks
    var pdfPath = "largefile.pdf";
    using (var fileStream = File.OpenRead(pdfPath))
    {
        var buffer = new byte[chunkSize];
        var chunks = new List<byte[]>();
        int bytesRead;
        while ((bytesRead = await fileStream.ReadAsync(buffer)) > 0)
        {
            var chunk = new byte[bytesRead];
            Array.Copy(buffer, chunk, bytesRead);
            chunks.Add(chunk);
        }
        // Process chunks for display
        await ProcessPdfChunks(chunks);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

此方法分塊加載大 PDF 文件,防止內存問題,並確保即使面對大型 PDF 文件時也能保持平穩的性能。 當處理移動手機或資源有限的設備上的 PDF 文件時,這尤其有用。

Blazor 應用程式的安全考量

處理受密碼保護的 PDF 文件時:

private async Task LoadSecurePdf(string password)
{
    var pdfDocument = PdfDocument.FromFile("secure.pdf", password);
    if (pdfDocument != null)
    {
       var headers = new Dictionary<string, string>
        {
            {"X-Frame-Options", "SAMEORIGIN"},
            {"Content-Security-Policy", "default-src 'self'"}
        };
        await DisplayPdfContent(pdfDocument);
    }
}
private async Task LoadSecurePdf(string password)
{
    var pdfDocument = PdfDocument.FromFile("secure.pdf", password);
    if (pdfDocument != null)
    {
       var headers = new Dictionary<string, string>
        {
            {"X-Frame-Options", "SAMEORIGIN"},
            {"Content-Security-Policy", "default-src 'self'"}
        };
        await DisplayPdfContent(pdfDocument);
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

此代碼演示了加載受密碼保護的 PDF 文件,同時通過適當的標頭配置保持安全。

結論

使用 IronPDF 實現 Blazor PDF 檢視器為開發人員提供了一個顯示 Web 應用程式中 PDF 的全面解決方案。 從基本顯示到表單填充和註解等高級功能,IronPDF 的 PDF 檢視元件提供了專業應用程式所需的功能。

展示的示例演示了如何創建一個強健的 Blazor PDF 檢視器,可以處理各種 PDF 來源,提供交互功能並保持高性能。 無論您是在構建簡單的文檔檢視器還是複雜的文檔管理系統,IronPDF 與 Blazor 服務器應用程式的集成使您輕鬆實現專業的 PDF 顯示能力。

準備好實現您自己的 PDF 檢視器了嗎? 立即開始您的 IronPDF 免費試用,並獲取完整的文檔、演示應用程式和開發人員支持,在您的 Blazor 應用中創建強大的 PDF 顯示體驗。

常見問題解答

我如何使用 IronPDF 在 Blazor 應用程式中顯示 PDF?

IronPDF 提供了一個全面的 API,允許您在 Blazor 應用程式中渲染和顯示 PDF。通過整合 IronPDF,您可以輕鬆實施強大的 PDF 檢視元件。

使用 IronPDF 進行 Blazor PDF 檢視有哪些好處?

使用 IronPDF 進行 Blazor PDF 檢視的好處包括處理表單字段、創建互動檢視器,並在應用程式中無縫渲染高品質的 PDF。

是否可以使用 IronPDF 在 Blazor 中處理 PDF 中的表單字段?

是的,IronPDF 允許您在 Blazor 應用程式中處理和操作 PDF 文件中的表單字段,提高互動性和用戶參與度。

IronPDF 可以用來在 Blazor 中創建互動 PDF 檢視器嗎?

絕對可以。IronPDF 提供工具來在 Blazor 中創建互動 PDF 檢視器,實現像表單處理和動態內容顯示等功能。

IronPDF 在 Blazor 中提供了哪些 PDF 操作功能?

IronPDF 提供的功能包括 PDF 渲染、表單字段處理、文本提取和頁面操作,使其成為 Blazor 中 PDF 操作的多用途選擇。

IronPDF 如何提升 Blazor 應用程式中的 PDF 檢視體驗?

IronPDF 通過提供平滑渲染、互動功能以及強大的 PDF 文件處理,提升 Blazor 應用程式中的 PDF 檢視體驗。

Curtis Chau
技術作家

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

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