Blazor Abrir PDF en una nueva pestaña con IronPDF: Un tutorial para desarrolladores
Abrir documentos PDF en una nueva pestaña del navegador es un requisito común para las aplicaciones web de Blazor. Este tutorial muestra cómo generar archivos PDF utilizando IronPDF y mostrarlos en nuevas pestañas utilizando JavaScript interop, proporcionando a los usuarios una experiencia de visualización de documentos fluida. Este ejemplo se centra en una versión de Blazor Server.
Requisitos y Instalación
Comienza creando un nuevo proyecto de Blazor Server en Visual Studio 2022. Instala IronPDF a través de la Consola del Administrador de Paquetes NuGet:
Install-Package IronPdf
Configure su licencia IronPDF en Program.cs para habilitar la funcionalidad completa:
License.LicenseKey = "YOUR-LICENSE-KEY";
License.LicenseKey = "YOUR-LICENSE-KEY";
License.LicenseKey = "YOUR-LICENSE-KEY"
Entendiendo el reto
Las aplicaciones de Blazor Server no pueden manipular directamente las pestañas del navegador desde el código C# en el servidor. La tarea de Blazor open PDF in new tab requiere JavaScript InterOp (JS interop) para unir la generación de PDF del lado del servidor con la gestión de ventanas del lado del cliente.
IronPDF permite a los desarrolladores generar documentos PDF de alta calidad en el servidor , que luego pueden mostrarse utilizando la funcionalidad window.open() de JavaScript. Se trata de resolver un problema común cliente-servidor en una aplicación .NET.
Implementación de funciones JavaScript en su aplicación web Blazor
Añada este código JavaScript a su archivo _Host.cshtml para gestionar la visualización del PDF en nuevas pestañas del navegador. Este es el módulo responsable de la gestión de ventanas del lado del cliente:
<script>
window.openPdfInNewTab = function (pdfData, fileName) {
// Convert base64 to blob
const byteCharacters = atob(pdfData);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
// The type is 'application/pdf', not 'image/png' or 'image/jpg'
const blob = new Blob([byteArray], { type: 'application/pdf' });
// Create URL and open in new tab
const blobUrl = URL.createObjectURL(blob);
const newWindow = window.open(blobUrl, '_blank');
if (newWindow) {
newWindow.document.title = fileName || 'PDF Document';
}
// Clean up
setTimeout(() => URL.revokeObjectURL(blobUrl), 100);
return newWindow !== null;
};
</script>
<script>
window.openPdfInNewTab = function (pdfData, fileName) {
// Convert base64 to blob
const byteCharacters = atob(pdfData);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
// The type is 'application/pdf', not 'image/png' or 'image/jpg'
const blob = new Blob([byteArray], { type: 'application/pdf' });
// Create URL and open in new tab
const blobUrl = URL.createObjectURL(blob);
const newWindow = window.open(blobUrl, '_blank');
if (newWindow) {
newWindow.document.title = fileName || 'PDF Document';
}
// Clean up
setTimeout(() => URL.revokeObjectURL(blobUrl), 100);
return newWindow !== null;
};
</script>
The provided code is JavaScript, not C#. However, I can help you convert it into VB.NET code that would perform a similar function if executed in a VB.NET environment with a web browser control or similar setup. Here's how you might implement similar functionality in VB.NET:
Note: This VB.NET code assumes you are working in a desktop application environment where you can use the `Process.Start` method to open a PDF file with the default PDF viewer. If you are working in a web environment, you would need to adapt this code to fit the web context, possibly using a web server to serve the PDF file to the client.
La función de JavaScript window.openPdfInNewTab es crucial para resolver el desafío de abrir una nueva pestaña desde el servidor. Acepta los datos PDF como una cadena Base64 del servidor Blazor y el código del lado del cliente los convierte en un objeto Blob binario.
Este blob se utiliza para crear una URL temporal, que finalmente se pasa a window.open(blobUrl, '_blank') para forzar al navegador a abrir el PDF en una nueva pestaña.
Creación del componente Blazor
Crea un nuevo componente Razor que genere PDFs y los abra en nuevas pestañas. Esto sirve como la plantilla principal para la solución:
@page "/pdf-viewer"
@using IronPDF @inject IJSRuntime JS
<h3>Open PDF in New Tab</h3>
<div class="mb-3">
<label>Enter URL:</label>
</div>
<button class="btn btn-primary" @onclick="GenerateAndOpenPdf"
disabled="@isProcessing">
@if (isProcessing)
{
<span>Generating PDF...</span>
}
else
{
<span>Generate and Open PDF</span>
}
</button>
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-danger mt-3">@errorMessage</div>
}
@code {
private string targetUrl = "https://ironpdf.com";
private bool isProcessing = false;
private string errorMessage = "";
private async Task GenerateAndOpenPdf()
{
isProcessing = true;
errorMessage = "";
try
{
// Configure Chrome PDF renderer. Note the rendering details
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
MarginTop = 10,
MarginBottom = 10,
MarginLeft = 10,
MarginRight = 10,
EnableJavaScript = true,
RenderDelay = 500
}
};
// Generate PDF from URL
var pdfDocument = await Task.Run(() =>
renderer.RenderUrlAsPdf(targetUrl));
// Convert to base64
byte[] pdfBytes = pdfDocument.BinaryData;
string base64Pdf = Convert.ToBase64String(pdfBytes);
// Open in new tab via JS interop. We run this call to open the PDF
bool success = await JS.InvokeAsync<bool>("openPdfInNewTab",
base64Pdf, $"Document_{DateTime.Now:yyyyMMdd_HHmmss}.pdf");
if (!success)
{
// Giving the user an understandable error is key
errorMessage = "Pop-up blocked. Please allow pop-ups for this site.";
}
}
catch (Exception ex)
{
errorMessage = $"Error: {ex.Message}";
}
finally
{
isProcessing = false;
}
}
}
@page "/pdf-viewer"
@using IronPDF @inject IJSRuntime JS
<h3>Open PDF in New Tab</h3>
<div class="mb-3">
<label>Enter URL:</label>
</div>
<button class="btn btn-primary" @onclick="GenerateAndOpenPdf"
disabled="@isProcessing">
@if (isProcessing)
{
<span>Generating PDF...</span>
}
else
{
<span>Generate and Open PDF</span>
}
</button>
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-danger mt-3">@errorMessage</div>
}
@code {
private string targetUrl = "https://ironpdf.com";
private bool isProcessing = false;
private string errorMessage = "";
private async Task GenerateAndOpenPdf()
{
isProcessing = true;
errorMessage = "";
try
{
// Configure Chrome PDF renderer. Note the rendering details
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
MarginTop = 10,
MarginBottom = 10,
MarginLeft = 10,
MarginRight = 10,
EnableJavaScript = true,
RenderDelay = 500
}
};
// Generate PDF from URL
var pdfDocument = await Task.Run(() =>
renderer.RenderUrlAsPdf(targetUrl));
// Convert to base64
byte[] pdfBytes = pdfDocument.BinaryData;
string base64Pdf = Convert.ToBase64String(pdfBytes);
// Open in new tab via JS interop. We run this call to open the PDF
bool success = await JS.InvokeAsync<bool>("openPdfInNewTab",
base64Pdf, $"Document_{DateTime.Now:yyyyMMdd_HHmmss}.pdf");
if (!success)
{
// Giving the user an understandable error is key
errorMessage = "Pop-up blocked. Please allow pop-ups for this site.";
}
}
catch (Exception ex)
{
errorMessage = $"Error: {ex.Message}";
}
finally
{
isProcessing = false;
}
}
}
Imports IronPDF
Imports Microsoft.JSInterop
@page "/pdf-viewer"
@inject IJSRuntime JS
<h3>Open PDF in New Tab</h3>
<div class="mb-3">
<label>Enter URL:</label>
</div>
<button class="btn btn-primary" @onclick="GenerateAndOpenPdf" disabled="@isProcessing">
@If isProcessing Then
<span>Generating PDF...</span>
Else
<span>Generate and Open PDF</span>
End If
</button>
@If Not String.IsNullOrEmpty(errorMessage) Then
<div class="alert alert-danger mt-3">@errorMessage</div>
End If
@Code
Private targetUrl As String = "https://ironpdf.com"
Private isProcessing As Boolean = False
Private errorMessage As String = ""
Private Async Function GenerateAndOpenPdf() As Task
isProcessing = True
errorMessage = ""
Try
' Configure Chrome PDF renderer. Note the rendering details
Dim renderer As New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.MarginTop = 10,
.MarginBottom = 10,
.MarginLeft = 10,
.MarginRight = 10,
.EnableJavaScript = True,
.RenderDelay = 500
}
}
' Generate PDF from URL
Dim pdfDocument = Await Task.Run(Function() renderer.RenderUrlAsPdf(targetUrl))
' Convert to base64
Dim pdfBytes As Byte() = pdfDocument.BinaryData
Dim base64Pdf As String = Convert.ToBase64String(pdfBytes)
' Open in new tab via JS interop. We run this call to open the PDF
Dim success As Boolean = Await JS.InvokeAsync(Of Boolean)("openPdfInNewTab", base64Pdf, $"Document_{DateTime.Now:yyyyMMdd_HHmmss}.pdf")
If Not success Then
' Giving the user an understandable error is key
errorMessage = "Pop-up blocked. Please allow pop-ups for this site."
End If
Catch ex As Exception
errorMessage = $"Error: {ex.Message}"
Finally
isProcessing = False
End Try
End Function
End Code
Este bloque de código define la página interactiva principal. El marcado Razor crea una interfaz de usuario simple con un campo de entrada de URL y un botón. El bloque @code de C# se encarga de la lógica: cuando se hace clic en el botón, utiliza una instancia de ChromePdfRenderer para generar el PDF a partir de la URL proporcionada por el usuario.
Luego convierte la matriz de bytes PDF resultante en una cadena Base64 y utiliza @inject IJSRuntime JS para llamar a la función JavaScript , abriendo el documento para el usuario.
Salida de UI

Salida con PDF abierto en una nueva pestaña

Trabajar con contenido HTML dinámico
Para generar archivos PDF a partir de contenido dinámico en lugar de URL, modifique su enfoque para utilizar RenderHtmlAsPdf:
private async Task GenerateFromHtml()
{
// Define CSS styles inside the HTML string for structure and appearance.
string htmlContent = $@"
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial; padding: 20px; }}
h1 {{ color: #2c3e50; }}
</style>
</head>
<body>
<h1>{documentTitle}</h1>
<p>{documentContent}</p>
<div>Generated: {DateTime.Now}</div>
</body>
</html>";
var renderer = new ChromePdfRenderer();
var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
byte[] pdfBytes = pdfDocument.BinaryData;
await JS.InvokeVoidAsync("openPdfInNewTab",
Convert.ToBase64String(pdfBytes), "dynamic.pdf");
}
private async Task GenerateFromHtml()
{
// Define CSS styles inside the HTML string for structure and appearance.
string htmlContent = $@"
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial; padding: 20px; }}
h1 {{ color: #2c3e50; }}
</style>
</head>
<body>
<h1>{documentTitle}</h1>
<p>{documentContent}</p>
<div>Generated: {DateTime.Now}</div>
</body>
</html>";
var renderer = new ChromePdfRenderer();
var pdfDocument = renderer.RenderHtmlAsPdf(htmlContent);
byte[] pdfBytes = pdfDocument.BinaryData;
await JS.InvokeVoidAsync("openPdfInNewTab",
Convert.ToBase64String(pdfBytes), "dynamic.pdf");
}
Private Async Function GenerateFromHtml() As Task
' Define CSS styles inside the HTML string for structure and appearance.
Dim htmlContent As String = $"
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial; padding: 20px; }}
h1 {{ color: #2c3e50; }}
</style>
</head>
<body>
<h1>{documentTitle}</h1>
<p>{documentContent}</p>
<div>Generated: {DateTime.Now}</div>
</body>
</html>"
Dim renderer = New ChromePdfRenderer()
Dim pdfDocument = renderer.RenderHtmlAsPdf(htmlContent)
Dim pdfBytes As Byte() = pdfDocument.BinaryData
Await JS.InvokeVoidAsync("openPdfInNewTab", Convert.ToBase64String(pdfBytes), "dynamic.pdf")
End Function
El método GenerateFromHtml demuestra cómo IronPDF puede generar un PDF a partir de un marcado HTML generado dinámicamente en lugar de una URL existente. Construye una cadena de HTML completa que contiene un encabezado, contenido y datos dinámicos. La respuesta a la generación de contenido dinámico es el método RenderHtmlAsPdf.
UI de servidor Blazor actualizada

PDF abierto en una nueva pestaña del navegador

Cómo resolver problemas comunes
Compatibilidad entre navegadores
Diferentes navegadores manejan los URLs de blob de manera diferente. Prueba tu implementación en Chrome, Firefox, Edge y Safari para asegurar un comportamiento consistente.
Archivos pesados
Para documentos PDF grandes, considera implementar almacenamiento en caché del lado del servidor para mejorar el rendimiento:
services.AddMemoryCache();
// Cache generated PDFs to avoid regeneration
services.AddMemoryCache();
// Cache generated PDFs to avoid regeneration
services.AddMemoryCache()
' Cache generated PDFs to avoid regeneration
Alternativas de navegación
Además de la interoperabilidad con JavaScript, puede servir archivos PDF a través de un middleware de archivos estáticos y utilizar etiquetas de anclaje HTML estándar para una opción de navegación alternativa:
<a href="/pdfs/document.pdf" target="_blank">Open PDF</a>
<a href="/pdfs/document.pdf" target="_blank">Open PDF</a>
The provided input is HTML, not C# code. Please provide valid C# code for conversion to VB.NET.
Este enfoque funciona bien para PDF pregenerados, pero carece de las capacidades de generación dinámica del método JS InterOp.
Mejores prácticas
- Manejo de errores: Envuelva siempre la generación de PDF en bloques try-catch y proporcione mensajes de error significativos a los usuarios cuando se produzca un problema.
- Rendimiento: Utilice patrones async/await para evitar el bloqueo de la interfaz de usuario durante la generación de PDF.
- Experiencia del usuario: Muestra indicadores de carga durante la generación y maneja los escenarios de bloqueadores de ventanas emergentes de manera adecuada.
- manipulación DOM: Recuerde que C# en el servidor no puede manipular directamente el DOM del cliente; por eso JS InterOp es esencial. No necesitas establecer manualmente la altura o el ancho de la nueva ventana, ya que el navegador maneja al visor de PDF.
- Seguridad: validar y desinfectar la entrada del usuario antes de generar archivos PDF
Conclusión
La combinación de las potentes capacidades de generación de PDF de IronPDF con JavaScript InterOp de Blazor proporciona una solución sólida para abrir PDF en nuevas pestañas del navegador. Este enfoque permite a los desarrolladores crear documentos PDF dinámicos y profesionales que se integran perfectamente con las aplicaciones modernas de Blazor construidas sobre la tecnología .NET de Microsoft.
¿Listo para implementar la funcionalidad de PDF en tu proyecto de Blazor? Inicie su prueba gratuita de IronPDF hoy mismo. La prueba incluye funcionalidad completa sin marcas de agua y soporte integral para asegurar tu éxito.
Preguntas Frecuentes
¿Cómo puedo abrir un PDF en una nueva pestaña usando Blazor?
Puede abrir un PDF en una nueva pestaña con Blazor generando el PDF con IronPDF y utilizando la interoperabilidad de JavaScript para mostrarlo en una nueva pestaña. Este enfoque garantiza una experiencia de usuario fluida al visualizar los documentos.
¿Qué es la interoperabilidad de JavaScript en Blazor?
La interoperabilidad de JavaScript en Blazor permite a las aplicaciones Blazor llamar a funciones JavaScript desde código .NET y viceversa. Esto resulta útil para tareas como abrir archivos PDF en una nueva pestaña, en las que JavaScript puede gestionar operaciones específicas del navegador.
¿Por qué debería utilizar IronPDF para generar archivos PDF en Blazor?
IronPDF es una herramienta eficaz para generar archivos PDF en aplicaciones Blazor. Proporciona funciones sólidas que permiten crear y manipular PDF sin problemas, que se pueden integrar fácilmente con la interoperabilidad JavaScript de Blazor para mejorar la gestión de documentos.
¿Es IronPDF compatible con Blazor Server?
Sí, IronPDF es totalmente compatible con Blazor Server. Se puede utilizar para generar y gestionar archivos PDF, que luego se pueden abrir en nuevas pestañas utilizando JavaScript interop.
¿Cuáles son las ventajas de abrir archivos PDF en una nueva pestaña en las aplicaciones de Blazor?
La apertura de archivos PDF en una nueva pestaña mejora la experiencia del usuario, ya que le permite ver los documentos sin salir de la página actual. Este método, compatible con IronPDF y la interoperabilidad de JavaScript, garantiza una sesión de navegación más interactiva e ininterrumpida.


