Cómo Convertir Elementos HTML y Secciones de Página Parciales a PDF en C

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronPDF no expone un método incorporado SelectElement o SelectCss para apuntar a elementos HTML específicos. El ChromePdfRenderer renderiza documentos HTML completos: una página completa, una URL completa, una cadena HTML completa. Para producir un PDF de una sección específica de una página, aislamos el elemento de destino antes de renderizar usando uno de cuatro enfoques: manipulación del DOM de JavaScript, inyección de CSS, extracción de fragmentos HTML del lado del servidor, o renderizado de URL con orientación de JS.

En el contexto de la facturación electrónica española, esta capacidad de convertir elementos HTML específicos a PDF es fundamental para generar las representaciones gráficas de facturas exigidas por VERI*FACTU (sistema antifraude de la AEAT) y por el estándar Facturae (B2G). Asimismo, los sistemas TicketBAI de Bizkaia, Gipuzkoa y Araba generan tickets en HTML que deben convertirse a PDF para su impresión o distribución digital. Los cuatro enfoques de esta guía se aplican directamente a estos escenarios: la extracción del lado del servidor (Enfoque 3) es el más eficiente para pipelines de alto volumen como el SII (Suministro Inmediato de Información), mientras que el aislamiento DOM de JavaScript (Enfoque 1) es más flexible para facturas generadas dinámicamente.

Cada enfoque se adapta a una restricción diferente. El aislamiento del DOM de JavaScript funciona al renderizar URLs o páginas completas donde necesitamos eliminar todo excepto el objetivo. La inyección de CSS oculta contenido no deseado sin alterar el DOM. La extracción del lado del servidor proporciona el resultado más limpio cuando tenemos acceso al HTML en bruto. El renderizado de URL con orientación de JS maneja paneles en tiempo real y páginas de terceros donde el HTML fuente no está disponible.

Comienza una prueba gratuita de 30 días para probar los cuatro enfoques.

Comienzo rápido: Extraer un Elemento HTML Específico como PDF

Apunte a cualquier elemento usando el selector CSS utilizando el aislamiento de DOM de JavaScript y WaitFor, luego renderice solo ese fragmento a PDF.

  1. Instala IronPDF con el Administrador de Paquetes NuGet

    PM > Install-Package IronPdf
  2. Copie y ejecute este fragmento de código.

    using IronPdf;
    
    var renderer = new ChromePdfRenderer();
    renderer.RenderingOptions.EnableJavaScript = true;
    renderer.RenderingOptions.JavaScript = @"
        var target = document.querySelector('#invoice-summary');
        document.body.innerHTML = target.outerHTML;
    ";
    renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000);
    
    var pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
    pdf.SaveAs("invoice-summary.pdf");
  3. Despliegue para probar en su entorno real

    Comienza a usar IronPDF en tu proyecto hoy mismo con una prueba gratuita

    arrow pointer

Flujo de Trabajo Mínimo (3 Pasos)

  1. Instale IronPdf a través de NuGet: Install-Package IronPdf
  2. Configure ChromePdfRenderOptions.JavaScript para aislar el elemento objetivo y WaitFor para asegurarse de que exista.
  3. Llame a RenderHtmlAsPdf() o RenderUrlAsPdf(): el PDF contiene solo el contenido aislado.

¿Cómo Aislar Elementos con la Manipulación del DOM de JavaScript?

La propiedad ChromePdfRenderOptions.JavaScript acepta una cadena de JavaScript que se ejecuta después de que se carga el HTML, pero antes de que se renderice el PDF. Reemplazando document.body.innerHTML con el outerHTML del elemento objetivo, eliminamos todo lo demás de la página renderizada. Este es el enfoque más versátil: funciona con ambos RenderHtmlAsPdf() y RenderUrlAsPdf().

El método WaitFor.HtmlQuerySelector() asegura que el elemento objetivo exista en el DOM antes de que se ejecute el JavaScript. Esto es crítico para páginas con contenido asincrónico: componentes React, plantillas Angular, o datos impulsados por API que se llenan después de la carga inicial de la página.

using IronPdf;

string fullPageHtml = @"
<html>
<body>
    <header><h1>Acme Corp Invoice</h1></header>
    <nav>Navigation links...</nav>
    <div id='invoice-summary'>
        <h2>Invoice #12345</h2>
        <table>
            <tr><td>Widget A</td><td>$49.99</td></tr>
            <tr><td>Widget B</td><td>$29.99</td></tr>
            <tr><td><strong>Total</strong></td><td><strong>$79.98</strong></td></tr>
        </table>
    </div>
    <footer>Footer content...</footer>
</body>
</html>";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

// Replace the body with only the target element
renderer.RenderingOptions.JavaScript = @"
    var el = document.querySelector('#invoice-summary');
    if (el) {
        document.body.innerHTML = el.outerHTML;
    }
";

// Wait for the target element to exist before JS executes
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
pdf.SaveAs("invoice-summary-only.pdf");
using IronPdf;

string fullPageHtml = @"
<html>
<body>
    <header><h1>Acme Corp Invoice</h1></header>
    <nav>Navigation links...</nav>
    <div id='invoice-summary'>
        <h2>Invoice #12345</h2>
        <table>
            <tr><td>Widget A</td><td>$49.99</td></tr>
            <tr><td>Widget B</td><td>$29.99</td></tr>
            <tr><td><strong>Total</strong></td><td><strong>$79.98</strong></td></tr>
        </table>
    </div>
    <footer>Footer content...</footer>
</body>
</html>";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

// Replace the body with only the target element
renderer.RenderingOptions.JavaScript = @"
    var el = document.querySelector('#invoice-summary');
    if (el) {
        document.body.innerHTML = el.outerHTML;
    }
";

// Wait for the target element to exist before JS executes
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
pdf.SaveAs("invoice-summary-only.pdf");
Imports IronPdf

Dim fullPageHtml As String = "
<html>
<body>
    <header><h1>Acme Corp Invoice</h1></header>
    <nav>Navigation links...</nav>
    <div id='invoice-summary'>
        <h2>Invoice #12345</h2>
        <table>
            <tr><td>Widget A</td><td>$49.99</td></tr>
            <tr><td>Widget B</td><td>$29.99</td></tr>
            <tr><td><strong>Total</strong></td><td><strong>$79.98</strong></td></tr>
        </table>
    </div>
    <footer>Footer content...</footer>
</body>
</html>"

Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.EnableJavaScript = True

' Replace the body with only the target element
renderer.RenderingOptions.JavaScript = "
    var el = document.querySelector('#invoice-summary');
    if (el) {
        document.body.innerHTML = el.outerHTML;
    }
"

' Wait for the target element to exist before JS executes
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000)

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fullPageHtml)
pdf.SaveAs("invoice-summary-only.pdf")
$vbLabelText   $csharpLabel

El JavaScript reemplaza todo el cuerpo con el #invoice-summary del div outerHTML. El PDF resultante contiene solo la tabla de la factura: sin encabezado, sin navegación, sin pie de página. El método WaitFor.HtmlElementById() proporciona una alternativa más sencilla al apuntar por ID:

// Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000);
// Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000);
' Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000)
$vbLabelText   $csharpLabel

Para selectores complejos (nombres de clase, atributos de datos, elementos anidados), HtmlQuerySelector() acepta cualquier cadena de selector CSS válida que document.querySelector() aceptaría. Métodos de conveniencia adicionales WaitFor incluyen HtmlElementByClassName(), HtmlElementByName(), y HtmlElementByTagName() - cada uno internamente delega a HtmlQuerySelector() pero proporciona una intención más clara en el código.

Cuando el elemento objetivo depende de estilos heredados de contenedores padre, el reemplazo outerHTML puede perder reglas CSS que dependen de selectores ascendentes (por ejemplo, .dashboard .widget table { ... }. Para preservar estos, copie las etiquetas <style> y <link> relevantes del <head> en el aislamiento JS:

renderer.RenderingOptions.JavaScript = @"
    var el = document.querySelector('#invoice-summary');
    if (el) {
        var head = document.head.innerHTML;
        document.body.innerHTML = el.outerHTML;
        document.head.innerHTML = head;
    }
";
renderer.RenderingOptions.JavaScript = @"
    var el = document.querySelector('#invoice-summary');
    if (el) {
        var head = document.head.innerHTML;
        document.body.innerHTML = el.outerHTML;
        document.head.innerHTML = head;
    }
";
renderer.RenderingOptions.JavaScript = "
    var el = document.querySelector('#invoice-summary');
    if (el) {
        var head = document.head.innerHTML;
        document.body.innerHTML = el.outerHTML;
        document.head.innerHTML = head;
    }
"
$vbLabelText   $csharpLabel

Esto retiene el contenido original <head> (hojas de estilo, fuentes, etiquetas meta) mientras reemplaza solo el cuerpo. Cómo JavaScript a PDF y la Cómo esperar cubren opciones de configuración adicionales incluyendo NetworkIdle0() para páginas con múltiples fuentes asíncronas de datos.