Saltar al pie de página
USANDO IRONPDF

Cómo mostrar un PDF en Blazor (Guía)

Introduction

Blazor display PDF functionality in modern web applications requires a robust PDF viewer component that goes beyond basic browser capabilities. For .NET developers building Blazor applications, IronPDF provides a powerful PDF viewer solution that seamlessly integrates with your Blazor Server app. This enables you to display PDF documents with high performance and rich functionality without relying on third-party browser tools.

In this tutorial, we'll explore how to implement a Blazor PDF viewer using IronPDF, creating a PDF viewer component that can open PDF files, handle PDF content, and provide users with an intuitive interface for displaying PDF on both desktop and mobile phones.

Getting Started Displaying PDFs with IronPDF

Before implementing your Blazor PDF viewer, you'll need to install IronPDF. Add it to your Blazor Server app through NuGet:

Install-Package IronPdf

Next, create a new Blazor application and ensure you have the latest version of .NET Core installed. Store your PDF files in the wwwroot folder for easy access, or prepare to load them from other sources like byte arrays or URLs.

Creating Your First Blazor PDF Viewer Component

Let's build a basic Blazor PDF viewer component that can display PDF documents. First, create a new Razor component:

@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

This code creates a simple PDF viewer component that loads a PDF document and displays it using an iframe. The LoadPdfDocument method reads PDF files from the same path (wwwroot folder) and converts them to a byte array. The CreateObjectUrl method then transforms this byte array into a data URL that the iframe can display, allowing users to easily view the loaded PDF document.

Output

How to Display a PDF in Blazor (Guide): Figure 1

Implementing JavaScript Interop for Enhanced Display

For better control over PDF content display, we can use JavaScript functions to handle the PDF viewer functionality:

@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

Add this JavaScript function to your JavaScript file in the wwwroot folder:

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

This JavaScript function creates a blob from the PDF data and generates an object URL. It then creates an iframe element dynamically and appends it to the container. This approach gives you more control over how PDF pages are displayed and allows for better handling of the PDF viewer component's lifecycle.

Output

How to Display a PDF in Blazor (Guide): Figure 2 - JavaScript PDF Viewer

Loading PDF Files from Different Sources

Your Blazor PDF viewer can retrieve and display PDF documents from various sources:

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

These methods demonstrate loading PDF files from URLs using HTTPS, converting HTML content to PDF, and displaying the resulting PDF content. The LoadFromUrl method retrieves PDF documents from remote locations, while LoadFromHtmlContent shows how to convert HTML to PDF on the fly, providing flexibility in how your Blazor PDF viewer component sources its content.

Output using HTML Content

How to Display a PDF in Blazor (Guide): Figure 3 - PDF Generated from HTML and displayed

Adding Interactive Features

Enhance your PDF viewer with interactive functionality:

@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

This code adds navigation between PDF pages, rotation functionality (including counterclockwise switch orientation), and the ability to print PDFs. The download functionality allows users to save PDF files locally. These features transform your basic PDF viewer into a powerful PDF viewer with a built-in toolbar that provides essential functionality for users working with PDF documents.

Output

How to Display a PDF in Blazor (Guide): Figure 4 - PDF Viewer with custom interactive features

Handling PDF Form Filling and Annotations

For PDF documents with form fields and annotations, IronPDF provides robust support:

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

This enables form filling capabilities within your Blazor PDF viewer component, allowing users to interact with form fields directly in the browser. The code iterates through form fields in the PDF document and can programmatically set values, making it ideal for applications requiring dynamic form filling.

Output

How to Display a PDF in Blazor (Guide): Figure 5 - Display PDF with Form Filling

Performance Optimization

To ensure high performance when displaying PDFs, especially for large PDF files:

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

This approach loads large PDF files in chunks, preventing memory issues and ensuring smooth performance even with substantial PDF documents. It's particularly useful when dealing with PDF files on mobile phones or devices with limited resources.

Security Considerations for Your Blazor Application

When working with password-protected PDF files:

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

This code demonstrates loading password-protected PDF documents while maintaining security through proper headers configuration.

Conclusion

Implementing a Blazor PDF viewer with IronPDF provides developers with a comprehensive solution for displaying PDFs in web applications. From basic display to advanced features like form filling and annotations, IronPDF's PDF viewer component offers the functionality needed for professional applications.

The examples shown demonstrate how to create a robust Blazor PDF viewer that can handle various PDF sources, provide interactive features, and maintain high performance. Whether you're building a simple document viewer or a complex document management system, IronPDF's integration with Blazor Server apps makes it easy to implement professional PDF viewing capabilities.

Ready to implement your own PDF viewer? Start your free trial of IronPDF today and access complete documentation, demo applications, and developer support to create powerful PDF viewing experiences in your Blazor applications.

Preguntas Frecuentes

¿Cómo puedo mostrar un PDF en una aplicación Blazor usando IronPDF?

IronPDF proporciona una API integral que le permite renderizar y mostrar PDFs dentro de aplicaciones Blazor. Al integrar IronPDF, puede implementar fácilmente un componente potente de visor de PDF.

¿Cuáles son los beneficios de usar IronPDF para visualizar PDFs en Blazor?

Usar IronPDF para visualizar PDFs en Blazor ofrece beneficios como el manejo de campos de formulario, la creación de visores interactivos y la renderización de PDFs de alta calidad sin problemas dentro de su aplicación.

¿Es posible manejar campos de formulario en PDFs usando IronPDF en Blazor?

Sí, IronPDF le permite manejar y manipular campos de formulario dentro de documentos PDF en una aplicación Blazor, ofreciendo mayor interactividad y participación del usuario.

¿Puede usar IronPDF para crear visores interactivos de PDF en Blazor?

Absolutamente. IronPDF proporciona herramientas para crear visores interactivos de PDF en Blazor, habilitando características como el manejo de formularios y la visualización de contenido dinámico.

¿Qué características ofrece IronPDF para la manipulación de PDF en Blazor?

IronPDF ofrece características como renderización de PDF, manejo de campos de formulario, extracción de texto y manipulación de páginas, lo que lo convierte en una opción versátil para operaciones de PDF en Blazor.

¿Cómo mejora IronPDF las experiencias de visualización de PDF en aplicaciones Blazor?

IronPDF mejora la experiencia de visualización de PDF en aplicaciones Blazor al proporcionar una renderización fluida, características interactivas y un manejo robusto de documentos PDF.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más