跳至页脚内容
使用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的查看器组件。

开始使用IronPDF展示PDF

在实现Blazor PDF查看器之前,您需要安装IronPDF。 通过NuGet将其添加到您的Blazor服务器应用程序中:

Install-Package IronPdf

接下来,创建一个新的Blazor应用程序,并确保您已安装最新版本的.NET Core。 将您的PDF文件存储在wwwroot文件夹中以便于访问,或准备从字节数组或URL等其他来源加载它们。

创建您的第一个Blazor PDF查看器组件

我们来构建一个可以显示PDF文档的基础Blazor 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查看器组件,加载PDF文档并通过iframe显示。 LoadPdfDocument方法从相同路径(wwwroot文件夹)读取PDF文件并将其转换为字节数组。 CreateObjectUrl方法然后将这个字节数组转换为iframe可以显示的数据URL,使用户可以轻松查看加载的PDF文档。

输出

如何在Blazor中显示PDF(指南):图1

实现JavaScript互操作以增强显示

为了更好地控制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

这些方法演示了从URL使用HTTPS加载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文档,同时通过适当的标题配置保持安全性。

结论

实现一个Blazor PDF查看器与IronPDF为开发人员提供了一个完整的解决方案,用于在Web应用程序中显示PDF。 从基础显示到高级功能如表单填写和注释,IronPDF的PDF查看器组件为专业应用程序提供了所需的功能。

所示示例演示了如何创建一个强大的Blazor PDF查看器,能够处理各种PDF来源,提供互动功能并保持高性能。 无论您是在构建简单的文档查看器还是复杂的文档管理系统,IronPDF与Blazor服务器应用程序的集成让实施专业的PDF查看能力变得简单。

准备好实现您自己的PDF查看器了吗? 立即开始您的IronPDF免费试用 并访问完整文档、演示应用程序以及开发者支持,以在您的Blazor应用程序中创建强大的PDF查看体验。

常见问题解答

如何在Blazor应用中使用IronPDF显示PDF?

IronPDF提供全面的API,允许在Blazor应用中渲染和显示PDF。通过集成IronPDF,您可以轻松实现一个强大的PDF查看组件。

使用IronPDF进行Blazor PDF查看有哪些优势?

使用IronPDF进行Blazor PDF查看带来诸如处理表单字段、创建互动查看器以及在您的应用程序中无缝渲染高质量PDF等好处。

在Blazor中使用IronPDF处理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 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。