Esta página puede contener texto traducido automáticamente.

Convertir HTML a PDF en C# y VB.NET

Si ya ha invertido mucho tiempo y dinero en crear contenido en formato HTML, le conviene crear archivos PDF a partir de ese HTML. Este enfoque es la opción ideal para quienes desean evitar la duplicación de trabajo.

Este artículo es una guía detallada para convertir HTML a PDF en .NET con Docotic.Pdf y su complemento gratuito HtmlToPdf.

Para obtener información sobre por qué Docotic.Pdf es la opción correcta, cómo instalar el complemento y cómo funciona la conversión internamente, consulte la página Descripción general de la API de HTML a PDF.

Conversión de HTML a PDF

Conversión sencilla de HTML a PDF con C#

Primero, instale el complemento.

Install-Package BitMiracle.Docotic.Pdf.HtmlToPdf

Usando la API de HTML a PDF, el código de conversión de C# puede verse así:

static async Task ConvertUrlToPdfAsync(string urlString, string pdfFileName)
{
    using var converter = await HtmlConverter.CreateAsync();
    using var pdf = await converter.CreatePdfAsync(new Uri(urlString));
    pdf.Save(pdfFileName);
}

Es bastante sencillo. Solo se requieren dos llamadas para generar un documento PDF.

El código crea una instancia del convertidor y la utiliza para generar un PDF a partir de HTML. Puedes editar el PDF o firmarlo con una firma digital. Para simplificar, el código de ejemplo guarda el documento tal cual.

Como puedes ver, la API es asíncrona y no proporciona ningún método síncrono.

Uso de la API asíncrona en código sincrónico

Hay casos en los que necesitas llamar a la API desde código síncrono. Por ejemplo, cuando tu aplicación de consola usa una versión anterior de C# y no tienes async Main. No te preocupes, aún puedes usar el complemento en tu aplicación.

El siguiente código muestra cómo convertir una URL a PDF con un método síncrono normal:

Task.Run(async () =>
{
    using var converter = await HtmlConverter.CreateAsync();
    var uri = new Uri("https://bitmiracle.com/pdf-library/html-pdf/");
    using var pdf = await converter.CreatePdfAsync(uri);
    pdf.Save("output.pdf");
}).GetAwaiter().GetResult();

Las aplicaciones VB.NET usan un código similar. Aquí hay un fragmento que muestra cómo convertir HTML a PDF en código VB.NET sincrónico.

Task.Run(
    Async Function()
        Using converter = Await HtmlConverter.CreateAsync()
            Dim uri = New Uri("https://bitmiracle.com/pdf-library/html-pdf/")
            Using pdf = Await converter.CreatePdfAsync(uri)
                pdf.Save("output.pdf")
            End Using
        End Using
    End Function
).GetAwaiter().GetResult()

Tenga en cuenta que, en general, no se recomienda llamar a métodos asíncronos de forma sincrónica, así que utilice el contenedor solo cuando no tenga otra opción.

Código de muestra

Ofrecemos códigos de ejemplo para aplicaciones de consola, Windows Forms y WPF. Descarga proyectos de prueba completos desde nuestro repositorio de GitHub:

También existe el grupo de ejemplos HTML a PDF. Cada ejemplo está disponible en versiones para C# y VB.NET.

Cree un PDF con una cadena o archivo HTML en C# y VB.NET

Con la API, es fácil convertir una cadena HTML a PDF. La cadena puede contener un documento HTML completo o solo un fragmento. El conversor creará un PDF a partir del código HTML.

using var converter = await HtmlConverter.CreateAsync();

var html = "<body><br><br><br><h1>Hello, World</h1></body>";
using var pdf = await converter.CreatePdfFromStringAsync(html);
pdf.Save("output.pdf");

El código HTML puede contener referencias relativas a imágenes, scripts y archivos CSS. Para convertir correctamente dicho código, deberá especificar una URL base para todos los enlaces relativos en el HTML. A continuación, se explica cómo especificar una URL base mediante las opciones de conversión:

using var converter = await HtmlConverter.CreateAsync();

var incompleteHtml = "<img src=\"/images/team.svg\"></img>";

var options = new HtmlConversionOptions();
options.Load.BaseUri = new Uri("https://bitmiracle.com/");

using var pdf = await converter.CreatePdfFromStringAsync(incompleteHtml, options);
pdf.Save("output.pdf");

Nuestro repositorio de GitHub contiene el proyecto de prueba completo.

Convertir un archivo HTML es prácticamente igual que convertir una URL. Simplemente use la sobrecarga CreatePdfAsync, que acepta una ruta en lugar de una URL. La URL base y otras opciones también son compatibles al convertir un archivo HTML a PDF en código C# o VB.NET.

var sampleHtmlPath = @"C:\path\to\sample.html";
using var pdf = await converter.CreatePdfAsync(sampleHtmlPath);
pdf.Save("output.pdf");

También puedes convertir imágenes SVG a PDF usando la API.

Utilice tamaño de página, márgenes y escala personalizados

Al trabajar con páginas web con diseños anchos, puede aumentar el tamaño del PDF de salida o reducir la escala del contenido para que se ajuste a la página. Para posicionar mejor el contenido escalado, también puede configurar los márgenes.

Un PDF bien escalado ofrece una mejor experiencia de lectura, ya que los lectores no tendrán que ampliar ni reducir el tamaño para ver el contenido correctamente. Si el documento HTML resulta difícil de leer debido al tamaño de fuente pequeño, puede ampliar el contenido.

De forma predeterminada, la API genera archivos PDF con un tamaño de página igual a A4. No hay márgenes ni ampliación. Puede cambiar estos ajustes con las opciones de conversión.

Vea cómo configurar el factor de escala y los márgenes al generar PDF desde HTML.

using var converter = await HtmlConverter.CreateAsync();

var html = "<html><head><style>body { background-color: coral; margin-top: 100px;}</style></head>" +
"<body><h1>Did you notice the margins and the scale?</h1></body></html>";

var options = new HtmlConversionOptions();
options.Page.MarginLeft = 10;
options.Page.MarginTop = 20;
options.Page.MarginRight = 30;
options.Page.MarginBottom = 40;
options.Page.Scale = 1.5;

using var pdf = await converter.CreatePdfFromStringAsync(html, options);
pdf.Save("output.pdf");

El repositorio de muestras de Docotic.Pdf contiene el proyecto completo.

La API de HTML a PDF puede añadir bloques repetibles de pie de página y encabezado en las páginas generadas. El conversor crea los bloques a partir de las plantillas HTML especificadas en opciones de página. Recomendamos usar estilos en línea y URI de datos para las imágenes dentro de las plantillas.

El conversor coloca los encabezados y pies de página dentro de los márgenes de la página. Dado que los márgenes predeterminados son pequeños, es posible que el contenido del encabezado y pie de página no sea visible. Recomendamos especificar los márgenes superior e inferior explícitamente. El tamaño debe coincidir con el del encabezado y pie de página, respectivamente.

Consulta cómo convertir de HTML a PDF y añadir encabezado y pie de página.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.HeaderTemplate = File.ReadAllText("header-template.html");
options.Page.MarginTop = 50;

options.Page.FooterTemplate = File.ReadAllText("footer-template.html");
options.Page.MarginBottom = 50;

var url = new Uri("https://www.iana.org/numbers");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Las plantillas usan código HTML estándar y admiten algunas variables. Estas variables son date, title, url, pageNumber y totalPages. Tanto las plantillas de encabezado como las plantillas de pie de página admiten el mismo conjunto de variables.

El proyecto de prueba completo y el código de la plantilla se encuentran en el repositorio de ejemplos de Docotic.Pdf. El código de ejemplo muestra cómo usar las variables y las URI de datos en las plantillas.

Conversión de HTML a PDF con C# protegida con contraseña

Algunas páginas web requieren autenticación para acceder. Al acceder a una URL segura que requiere autenticación HTTP, el navegador solicita el nombre de usuario y la contraseña.

Con las opciones de conversión, puede indicar a la API que proporcione credenciales para las páginas web que requieren inicio de sesión.

Este código de C# muestra cómo convertir HTML protegido con contraseña a PDF

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://httpbin.org/basic-auth/foo/bar");

var options = new HtmlConversionOptions();
options.Authentication.SetCredentials("foo", "bar");

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Encuentre la muestra de trabajo completa en el repositorio de muestras.

También es fácil si la página necesita configurar algunas cookies para funcionar correctamente. Simplemente añádelas a las opciones. Así es como se hace:

var options = new HtmlConversionOptions();
options.Cookies.Add(new Cookie("sessionID", "my-session-ID"));

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Retrasar el inicio de la conversión

Por defecto, la conversión comienza inmediatamente después de la carga. Retrasar la conversión de HTML a PDF puede ser útil si la página se actualiza constantemente tras la carga. Esto suele ocurrir al trabajar con contenido dinámico generado por JavaScript o llamadas AJAX.

La prueba Acid 3 es un ejemplo perfecto de una página que se beneficiaría de un retraso antes de la conversión. La prueba ejecuta varias comprobaciones para evaluar la capacidad del navegador para renderizar correctamente páginas web complejas. Estas comprobaciones llevan tiempo. Pruebe a cambiar el tiempo de espera en el siguiente código para ver cómo afecta a los resultados de la conversión.

var options = new HtmlConversionOptions();
options.Start.SetStartAfterDelay(10 * 1000);

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://acid3.acidtests.org/");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

El código anterior muestra cómo convertir HTML a PDF con retraso. Si bien el tiempo adicional ayuda a obtener mejores resultados, tenga en cuenta que añadir retrasos puede afectar el rendimiento. Un retraso insuficiente puede afectar negativamente la calidad de la conversión. Una alternativa al retraso es usar un script que se ejecute hasta que la página esté lista.

Puede obtener el proyecto de prueba completo en el repositorio de muestras Docotic.Pdf.

Ejecutar JavaScript antes de la conversión

La API del complemento permite ejecutar código JS antes de la conversión. Este código puede generar o modificar dinámicamente el contenido HTML. Por ejemplo, puede alternar elementos o activar la carga dinámica de contenido.

El siguiente código muestra cómo retrasar la conversión de HTML a PDF hasta que JavaScript haya finalizado.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
var js = @"document.body.style.backgroundColor = 'green';";
options.Start.SetStartAfterScriptRun(js);

var url = new Uri("https://google.com");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

El fragmento anterior utiliza un código muy simple para ilustrar el enfoque. Para un ejemplo más práctico, consulta la aplicación de ejemplo correspondiente en nuestro repositorio de GitHub. La aplicación muestra cómo gestionar una página que carga su contenido dinámicamente. El código JavaScript de la aplicación desplaza la página hasta que no hay más contenido nuevo. Después, se realiza la conversión a PDF.

Convierte HTML a PDF en .NET ignorando errores SSL

Al enviar solicitudes seguras para cargar HTML, el complemento comprueba si el certificado SSL que autentica la identidad de un sitio web y permite una conexión cifrada es válido y confiable.

De forma predeterminada, el complemento generará una excepción si el conversor de HTML a PDF no confía en el certificado por cualquier motivo. Esto suele ocurrir debido a un certificado autofirmado, revocado o caducado.

Si comprende el riesgo de aceptar un certificado no confiable, puede indicarle al complemento que omita las comprobaciones mediante las opciones del motor.

var engineOptions = new HtmlEngineOptions
{
    IgnoreSslErrors = true
};
using var converter = await HtmlConverter.CreateAsync(engineOptions);

var url = new Uri("https://self-signed.badssl.com/");
using var pdf = await converter.CreatePdfAsync(url);
pdf.Save("output.pdf");

Para obtener el código completo, diríjase al repositorio de ejemplos de Docotic.Pdf.

Superponer HTML sobre un PDF existente

Hay casos en los que se desea usar un PDF existente como fondo para el resultado de la conversión. Por ejemplo, si se tiene la imagen de un formulario y se desea colocar algo sobre las áreas vacías, el resultado se verá como un formulario completo. Esto es posible con Docotic.Pdf y el complemento.

Este proceso implica crear un nuevo PDF a partir del HTML (el contenido de la superposición) y luego fusionarlo con el PDF existente. El documento final incluirá tanto el contenido original como la nueva superposición. Aquí está el código que ilustra el proceso.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.SetSizeInches(4.13, 5.83);

string htmlCode =
    "<div style=\"position: absolute; top: 270px; right: 100px;\">" +
    "I would like to put this here</div>";
using var htmlPdf = await converter.CreatePdfFromStringAsync(htmlCode, options);

using var pdf = new PdfDocument("pdf-to-merge-with.pdf");
var xObj = pdf.CreateXObject(htmlPdf.Pages[0]);

pdf.Pages[0].Canvas.DrawXObject(xObj, 0, 0);
pdf.Save("output.pdf");

Es importante especificar un tamaño de página para la superposición. Normalmente, el tamaño debe ser igual al tamaño de la página que desea superponer. A continuación, deberá generar el nuevo PDF con el contenido de la superposición. Tenga en cuenta que el fondo es transparente por defecto. Puede cambiar el fondo ejecutando un script antes de la conversión si es necesario.

El código anterior:

  • crea un documento PDF con una página transparente a partir del HTML
  • abre un PDF existente
  • crea un XObject a partir de la primera página del documento convertido en el documento existente
  • dibuja el XObject sobre la primera página PDF del documento existente

El proyecto de prueba completo con un ejemplo de fuente PDF se encuentra en el repositorio de muestras de Docotic.Pdf.