# Cómo Convertir Elementos HTML y Secciones de Página Parciales a PDF en C#
[IronPDF](https://ironpdf.com) no expone un método incorporado `SelectElement` o `SelectCss` para apuntar a elementos HTML específicos. El [`ChromePdfRenderer`](https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderer.html) 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](https://ironpdf.com/#trial-license) para probar los cuatro enfoques.
*as-heading:2(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.
```cs
:title=Extract a Specific HTML Element as PDF!
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");
```
### Flujo de Trabajo Mínimo (3 Pasos)
1. Instale `IronPdf` a través de NuGet: `Install-Package IronPdf`
2. Configure [`ChromePdfRenderOptions.Javascript`](https://ironpdf.com/examples/execute-custom-javascript/) para aislar el elemento objetivo y [`WaitFor`](https://ironpdf.com/how-to/waitfor/) para asegurarse de que exista.
3. Llame a [`RenderHtmlAsPdf()`](https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderer.html) o [`RenderUrlAsPdf()`](https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderer.html): el PDF contiene solo el contenido aislado.
## ¿Cómo Aislar Elementos con la Manipulación del DOM de JavaScript?
La propiedad [`ChromePdfRenderOptions.Javascript`](https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderOptions.html) 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()`](https://ironpdf.com/object-reference/api/IronPdf.Engines.Chrome.WaitFor.html) 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.
```cs
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");
```
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()`](https://ironpdf.com/object-reference/api/IronPdf.Engines.Chrome.WaitFor.html) proporciona una alternativa más sencilla al apuntar por ID:
```cs
// Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000);
```
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:
```cs
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;
}
";
```
Esto retiene el contenido original `<head>` (hojas de estilo, fuentes, etiquetas meta) mientras reemplaza solo el cuerpo. [Cómo JavaScript a PDF](https://ironpdf.com/how-to/javascript-to-pdf/) y la [Cómo esperar](https://ironpdf.com/how-to/waitfor/) cubren opciones de configuración adicionales incluyendo `NetworkIdle0()` para páginas con múltiples fuentes asíncronas de datos.
## ¿Cómo aislar elementos con inyección de CSS?
La propiedad [`ChromePdfRenderOptions.CustomCssUrl`](https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderOptions.html) acepta una ruta de archivo o URL a una hoja de estilo que IronPDF aplica antes de renderizar. En lugar de manipular el DOM, escondemos todo excepto el elemento objetivo usando CSS `display: none`. Esto preserva la estructura original del DOM y evita por completo la ejecución de JavaScript.
```cs
using IronPdf;
// Create a CSS file that hides everything except #invoice-summary
string cssContent = @"
body > *:not(#invoice-summary) {
display: none !important;
}
#invoice-summary {
display: block !important;
margin: 0;
padding: 20px;
}
";
File.WriteAllText("isolate-element.css", cssContent);
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CustomCssUrl = "isolate-element.css";
PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
pdf.SaveAs("invoice-css-isolated.pdf");
```
**Nota:** La propiedad `CustomCssUrl` solo funciona con `RenderHtmlAsPdf()` al renderizar desde cadenas HTML. Para renderizar desde URL, inserte la inyección CSS en la propiedad [`Javascript`](https://ironpdf.com/examples/execute-custom-javascript/) en su lugar:
```cs
renderer.RenderingOptions.Javascript = @"
var style = document.createElement('style');
style.textContent = 'body > *:not(#invoice-summary) { display: none !important; }';
document.head.appendChild(style);
";
```
Cuando controlamos el HTML fuente, las reglas `@media print` ofrecen la alternativa más liviana: sin dependencias externas, sin inyección en tiempo de ejecución:
```css
@media print {
header, nav, footer, .sidebar { display: none !important; }
#invoice-summary { width: 100%; margin: 0; }
}
```
Configure [`CssMediaType`](https://ironpdf.com/how-to/rendering-options/) a `PdfCssMediaType.Print` en el renderer para activar estas reglas:
```cs
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
```
Esto es ideal para escenarios de impresión de sección de formularios donde la aplicación ya define reglas `@media print`, o el Enfoque 3 cuando el HTML del formulario se ensambla del lado del servidor.
El enfoque CSS tiene una limitación importante: los elementos ocultos aún ocupan espacio en el flujo del documento si se usa `display: none` en el nivel de especificidad equivocado. Siempre use `!important` para anular estilos de framework (Bootstrap, Tailwind) que podrían volver a mostrar elementos en ciertos puntos de ruptura. Para objetivos profundamente anidados, un selector más preciso evita ocultamientos colaterales:
```css
body > *:not(#target),
body > *:not(#target) ~ * {
display: none !important;
}
```
## ¿Cómo extraer fragmentos HTML del lado del servidor?
Cuando tenemos acceso al HTML sin procesar - leyéndolo desde un archivo, una base de datos, un CMS, o una respuesta HTTP - el enfoque más limpio es extraer el elemento objetivo del lado del servidor usando un analizador HTML, luego pasar el fragmento a `RenderHtmlAsPdf()`. Sin JavaScript, sin inyección de CSS, sin manipulación del DOM en tiempo de ejecución.
[AngleSharp](https://anglesharp.github.io/) es el analizador HTML estándar de .NET para este patrón:
```cs
using IronPdf;
using AngleSharp;
using AngleSharp.Html.Parser;
string fullPageHtml = @"
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
td, th { border: 1px solid #ddd; padding: 8px; text-align: left; }
</style>
</head>
<body>
<header><h1>Dashboard</h1></header>
<div id='revenue-widget'>
<h3>Q4 Revenue</h3>
<table>
<tr><th>Month</th><th>Revenue</th></tr>
<tr><td>October</td><td>$1.2M</td></tr>
<tr><td>November</td><td>$1.5M</td></tr>
<tr><td>December</td><td>$1.8M</td></tr>
</table>
</div>
<div id='other-content'>Other widgets...</div>
</body>
</html>";
// Parse and extract the target element
var parser = new HtmlParser();
var document = parser.ParseDocument(fullPageHtml);
var targetElement = document.QuerySelector("#revenue-widget");
if (targetElement is null)
{
Console.WriteLine("Target element not found.");
return;
}
// Wrap the fragment in a minimal HTML document to preserve styles
string fragmentHtml = $@"
<html>
<head>
<style>
table {{ border-collapse: collapse; width: 100%; }}
td, th {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
</style>
</head>
<body>
{targetElement.OuterHtml}
</body>
</html>";
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);
pdf.SaveAs("revenue-widget.pdf");
```
El detalle clave es envolver el fragmento extraído en un documento HTML completo con las etiquetas `<style>` o `<link>` relevantes. Sin este contenedor, los estilos en línea se renderizan correctamente, pero se pierden hojas de estilo externas y reglas CSS heredadas. Para la renderización de vistas previas de plantillas de correo electrónico, donde el HTML de la plantilla ya está almacenado como una cadena, este patrón de extracción brinda resultados perfectos en píxeles porque controlamos cada aspecto del contenido renderizado.
El mismo patrón funciona con HtmlAgilityPack como un analizador alternativo:
```cs
using HtmlAgilityPack;
using IronPdf;
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(fullPageHtml);
var targetNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='revenue-widget']");
if (targetNode is null)
{
Console.WriteLine("Target element not found.");
return;
}
string fragmentHtml = $"<html><body>{targetNode.OuterHtml}</body></html>";
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);
pdf.SaveAs("revenue-widget-hap.pdf");
```
```cs
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml, @"C:\templates\assets\");
```
La elección entre AngleSharp y HtmlAgilityPack es principalmente una preferencia. AngleSharp usa selectores CSS (`QuerySelector`), que se alinean con los modelos mentales de los desarrolladores de frontend. HtmlAgilityPack usa XPath (`SelectSingleNode`), que es más familiar en bases de código .NET orientadas a XML.
Para la renderización previa de plantillas de correo electrónico — generando una vista previa en PDF de una plantilla de correo electrónico HTML antes de enviarlo — es un escenario puro del Enfoque 3. El HTML de la plantilla es una cadena almacenada, los recursos externos (imágenes, fuentes) están alojados en URLs conocidas, y el parámetro `RenderHtmlAsPdf(string Html, string BaseUrlOrPath)` en `RenderHtmlAsPdf()` resuelve todas las rutas relativas.
Cuando el HTML contiene `<div id="app"></div>` que una aplicación React o Vue completa en tiempo de ejecución, el fragmento extraído estará vacío. Para esos casos, use el Enfoque 1 o 4.
## ¿Cómo enfocar elementos al renderizar URLs en vivo?
Para URLs en vivo donde no podemos acceder al HTML fuente - paneles de terceros, informes externos, aplicaciones alojadas - combinamos [`RenderUrlAsPdf()`](https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderer.html) con la propiedad `Javascript` y `WaitFor` para aislar una sección específica después de que se carga la página.
Este es el escenario de exportación de widgets de tablero: una herramienta de BI genera gráficos y tablas en una página web, y necesitamos exportar un solo widget como PDF para la distribución a las partes interesadas.
```cs
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;
// Wait for the dashboard widget to render (async content)
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("[data-widget='revenue-chart']", 15000);
// Isolate the widget after it renders
renderer.RenderingOptions.Javascript = @"
var widget = document.querySelector('[data-widget=""revenue-chart""]');
if (widget) {
// Preserve computed styles by cloning into a clean body
document.body.innerHTML = '';
document.body.appendChild(widget);
}
";
PdfDocument pdf = renderer.RenderUrlAsPdf("https://dashboard.example.com/q4-report");
pdf.SaveAs("revenue-chart-export.pdf");
```
La llamada `WaitFor.HtmlQuerySelector()` asegura que el widget exista en el DOM antes de que se ejecute el JavaScript. El tiempo de espera de 15 segundos acomoda llamadas API más lentas que completan los datos del tablero. El JavaScript luego reduce la página solo al widget.
Para páginas con dependencias CSS complejas, el enfoque `appendChild` (moviendo el nodo en lugar de copiar su `outerHTML`) preserva más estilos calculados porque el elemento conserva su posición en el CSSOM. El enfoque de reemplazo `innerHTML` del Enfoque 1 es más simple pero puede perder estilos que dependen de selectores ascendentes.
Cuando la página objetivo requiere autenticación, configure cookies en el renderer antes de llamar `RenderUrlAsPdf()`:
```cs
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
{ "session_id", "abc123" },
{ "auth_token", "bearer-xyz" }
};
```
La clase [`WaitFor`](https://ironpdf.com/how-to/waitfor/) ofrece estrategias de espera adicionales más allá de `HtmlQuerySelector()`. `NetworkIdle0()` espera hasta que todas las solicitudes de red completas con cero conexiones pendientes - útil para paneles de control que cargan datos de múltiples puntos finales API. `NetworkIdle2()` tolera hasta dos conexiones pendientes, que maneja páginas con conexiones persistentes de WebSocket o sondeo largo. `JavaScript()` espera a que la página llame a `window.ironpdf.notifyRender()` - la opción más precisa cuando controlamos la página objetivo y podemos señalar la preparación para renderizar explícitamente después de que todos los datos se carguen y se completen las animaciones.
Para exportaciones de tableros recurrentes (por ejemplo, generación nocturna de PDF para distribución de correos electrónicos a las partes interesadas), envuelva la renderización en un bucle de reintento que capture excepciones de tiempo de espera. Si `WaitFor` excede su `maxWaitTime`, IronPDF procede a renderizar cualquier contenido disponible, lo cual puede estar incompleto. Aumentar el tiempo de espera o cambiar a `NetworkIdle0()` generalmente resuelve fallas intermitentes en redes más lentas.
## Comparación de los Cuatro Enfoques
| Acercarse | Lo mejor para|Requiere HTML Fuente|Dependencia de JS| Complejidad |
|---|---|---|---|---|
|**Aislamiento del DOM con JavaScript**|Extracción de elementos de uso general desde cualquier fuente| No | Sí | Medium |
|**Inyección de CSS**|Ocultando secciones sin cambios en el DOM; layout `@media print`|Parcial (CustomCssUrl necesita `RenderHtmlAsPdf`)|No (a menos que se inyecte a través de JS para URLs)| Low |
|**Extracción de Fragmentos del Lado del Servidor**|Contenido de CMS, plantillas almacenadas, vistas previas de correos electrónicos| Sí | No |Bajo–Medio|
|**Renderización de URLs con Enfoque JavaScript**|Paneles en vivo, páginas de terceros, widgets SPA| No | Sí |Medio–Alto|
### Eligiendo el Enfoque Correcto
La decisión depende de dos factores: si tenemos acceso al HTML bruto, y si el contenido objetivo requiere JavaScript para renderizar.
la extracción de ítems de línea `Invoice` es el caso de uso más común. Cuando el HTML de la factura se genera del lado del servidor (vistas Razor, plantillas Handlebars, cadenas HTML almacenadas), el Enfoque 3 (extracción del lado del servidor) da el resultado más limpio sin costo de ejecución. Extraiga la tabla `#line-items`, envuélvala en una carcasa HTML con estilo y renderice.
la exportación de widget `Dashboard` requiere ejecución de JavaScript porque el contenido del widget es rellenado por llamadas API después de la carga inicial de la página. El Enfoque 1 (aislamiento del DOM con JS) maneja esto cuando el tablero se ejecuta localmente o detrás de una autenticación. El Enfoque 4 (renderización de URLs con enfoque JS) es necesario cuando el tablero es una aplicación alojada por terceros donde solo tenemos la URL.
la impresión de secciones `Form` - extrayendo una sección específica de un formulario de múltiples pasos para revisión del usuario o archivo de cumplimiento - se mapea naturalmente al Enfoque 2 (inyección CSS) cuando la aplicación ya define reglas `@media print`, o al Enfoque 3 cuando el HTML del formulario se ensambla del lado del servidor.
la renderización de vista previa de plantilla `Email` - generando una vista previa en PDF de una plantilla de correo electrónico HTML antes de enviar - es un escenario puro del Enfoque 3. El HTML de la plantilla es una cadena almacenada, los recursos externos (imágenes, fuentes) están alojados en URLs conocidas, y el parámetro `BaseUrlOrPath` en `RenderHtmlAsPdf()` resuelve todas las rutas relativas.
Para aplicaciones que necesitan soportar múltiples escenarios, encapsule la lógica de renderización detrás de una interfaz de servicio que acepte un parámetro de estrategia:
```cs
public enum ElementExtractionStrategy
{
JavaScriptIsolation,
CssInjection,
ServerSideExtraction,
UrlWithJsTargeting
}
```
Esto permite que el código que llama seleccione el enfoque apropiado basado en el tipo de entrada sin duplicar la configuración del renderizador.
## Casos de uso en facturación electrónica española: VERI*FACTU y Facturae
La capacidad de IronPDF para convertir elementos HTML específicos a PDF tiene aplicaciones directas en el ecosistema de facturación electrónica española:
### Generación de recibos VERI*FACTU desde elementos HTML
El sistema **VERI\*FACTU** de la **AEAT** exige que el software de facturación genere representaciones gráficas de las facturas. Cuando la factura se construye dinámicamente en HTML (por ejemplo, desde una plantilla Razor o una plantilla HTML con datos de la transacción), el **Enfoque 1 (aislamiento DOM de JavaScript)** permite extraer solo el elemento `<div id="factura-verifactu">` y renderizarlo como PDF:
```csharp
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.Javascript = @"
var factura = document.querySelector('#factura-verifactu');
document.body.innerHTML = factura.outerHTML;
";
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#factura-verifactu", 5000);
var pdf = renderer.RenderHtmlAsPdf(facturaHtml);
pdf.SaveAs("factura-verifactu.pdf");
```
### Exportación de secciones de facturas Facturae
Las facturas **Facturae** (formato XML B2G para la Administración Pública española) se acompañan habitualmente de una representación gráfica en PDF. El **Enfoque 3 (extracción del lado del servidor)** es el más eficiente para generar este PDF desde el HTML de la factura usando AngleSharp para extraer la sección relevante:
- Aísle el bloque de datos fiscales (`<section id="datos-facturacion">`) antes de renderizar.
- Aplique estilos corporativos y el pie de firma electrónica mediante CSS adicional.
- Renderice el fragmento extraído con `RenderHtmlAsPdf()` en un loop de procesamiento por lotes para generar cientos de facturas Facturae simultáneamente.
### Rendimiento en pipelines SII y TicketBAI
Para el **SII (Suministro Inmediato de Información)** — donde las facturas se procesan en lotes en tiempo real — y para **TicketBAI** en **Bizkaia**, **Gipuzkoa** y **Araba** — donde los tickets se generan de forma síncrona — el rendimiento es crítico. Como se indica en la sección de "Próximos pasos", la extracción del lado del servidor con `Parallel.ForEach` y múltiples instancias `ChromePdfRenderer` ofrece la mayor eficiencia para el procesamiento de alto volumen típico de estos sistemas.
## Próximos pasos
La aislación de elementos HTML en IronPDF es una preocupación en tiempo de renderizado, no una característica de API integrada. Los cuatro enfoques mencionados cubren todo el espectro, desde la extracción de plantillas del lado del servidor (cero JS, salida más limpia) hasta la orientación de URLs en vivo (ejecución completa de JS, maneja SPAs y contenido asíncrono). La tabla de comparación proporciona una referencia rápida, y los escenarios del mundo real mapean requerimientos comunes de negocio con la estrategia apropiada.
Algunas consideraciones adicionales para implementaciones en producción:
**Rendimiento**: La extracción del lado del servidor (Enfoque 3) es la más rápida porque omite por completo la ejecución de JavaScript. Los enfoques basados en JavaScript (1 y 4) agregan sobrecarga proporcional a la complejidad de la página y al tiempo de espera `WaitFor`. Para el procesamiento por lotes (por ejemplo, generando 500 PDFs de facturas), la extracción del lado del servidor con `Parallel.ForEach` y múltiples instancias `ChromePdfRenderer` proporciona el mejor rendimiento.
**Depuración**: cuando la salida del PDF está en blanco o falta contenido, habilite `EnableJavaScript = true` y aumente el tiempo de espera `WaitFor`. Si el elemento objetivo depende de datos asíncronos, `WaitFor.NetworkIdle0()` es más confiable que un `RenderDelay` fijo. La guía de [opciones de renderización](https://ironpdf.com/how-to/rendering-options/) cubre configuraciones de ancho de vista y ajuste de papel que afectan el diseño.
**Combinación de enfoques**: Nada impide mezclar estrategias. Podemos usar extracción del lado del servidor para construir un documento HTML compuesto a partir de múltiples fragmentos (encabezado de una fuente, tabla de datos de otra, SVG de gráficos de una tercera), y luego renderizar el documento ensamblado como un único PDF. El método [`RenderHtmlAsPdf(string Html, string BaseUrlOrPath)`](https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderer.html) resuelve rutas de activos relativas desde la URL base, lo que facilita componer documentos de fuentes heterogéneas.
Explore el [Cómo JavaScript a PDF](https://ironpdf.com/how-to/javascript-to-pdf/) para patrones avanzados de ejecución JS, la [documentación de WaitFor](https://ironpdf.com/how-to/waitfor/) para todas las estrategias de espera disponibles, la [guía de opciones de renderización](https://ironpdf.com/how-to/rendering-options/) para conocer toda la superficie `ChromePdfRenderOptions`, y el [ejemplo de código JavaScript personalizado](https://ironpdf.com/examples/execute-custom-javascript/) para fragmentos listos para ejecutar.
[Vea las opciones de licencia](https://ironpdf.com/licensing/) comenzando en `$liteLicense`. La [referencia API `ChromePdfRenderOptions`](https://ironpdf.com/object-reference/api/IronPdf.ChromePdfRenderOptions.html) y la [referencia API `WaitFor`](https://ironpdf.com/object-reference/api/IronPdf.Engines.Chrome.WaitFor.html) documentan cada propiedad y método.
## Marco normativo español para la extracción de elementos HTML a PDF
La extracción de secciones HTML específicas a PDF tiene implicaciones normativas directas en el mercado español que van más allá de la optimización técnica.
**Modelo de datos VeriFactu y representación gráfica**: El Real Decreto 1007/2023 establece que el software de facturación certificado bajo **VERI\*FACTU** debe generar una representación visual del registro de facturación que incluya la leyenda obligatoria `Factura verificable en la sede electrónica de la AEAT` y el código QR de verificación. Cuando la factura se construye como una página HTML con múltiples secciones (cabecera con datos del emisor NIF/CIF `B-28000001`, cuerpo con líneas de factura con importes en EUR, pie con el QR AEAT), el Enfoque 1 (aislamiento DOM) o el Enfoque 3 (extracción servidor) permiten generar el PDF con únicamente la sección de factura, sin incluir elementos de navegación ni encabezados de la interfaz de usuario.
**Facturae B2G y arquitectura de extracción**: Las facturas **Facturae** 3.2.2 para el portal **FACe** de la Administración General del Estado requieren que la representación gráfica PDF refleje exactamente los mismos datos que el fichero XML. El Enfoque 3 (AngleSharp o HtmlAgilityPack) es el más adecuado para extraer el bloque fiscal HTML (`#seccion-factura-completa`) desde el sistema de generación, garantizando una correspondencia exacta entre el XML y el PDF adjunto en el PDF/A-3 enviado a **FACe**.
**TicketBAI en Bizkaia, Gipuzkoa y Araba**: Los sistemas de punto de venta bajo **TicketBAI** en los tres territorios forales del País Vasco generan tiques en HTML con el código QR foral y el número de correlativo de huella XAdES encadenada. El Enfoque 3 con extracción del lado del servidor es el más eficiente para pipelines de alta frecuencia (p. ej., generación síncrona de PDFs de tique en **Bizkaia/BATUZ** durante horas punta de punto de venta), ya que no requiere ejecución de JavaScript ni navegador, y procesa los tickets a máxima velocidad.
**SII (Suministro Inmediato de Información) y protección de datos**: El **SII** de la **AEAT** exige la remisión en tiempo casi real de datos de facturas. Los PDFs de confirmación generados para el contribuyente contienen datos personales del emisor y receptor (NIF/CIF, datos de contacto), datos sujetos a la **LOPDGDD** supervisada por la **AEPD**. La extracción del lado del servidor (Enfoque 3) minimiza el riesgo de exposición de datos porque procesa el fragmento HTML sin almacenar la página completa con datos de sesión u otras secciones sensibles.
**Crea y Crece (Ley 18/2022) y representación visual EN 16931/CIUS-ES**: La Ley **Crea y Crece** establece factura electrónica B2B obligatoria bajo el estándar **EN 16931** con extensión española **CIUS-ES** a partir de 2027–2028. Los ISV que desarrollan plataformas de facturación necesitarán generar PDFs de representación visual que acompañen al fichero XML. La extracción de la sección de factura desde el HTML usando el Enfoque 3 es la arquitectura más escalable para generar estos PDFs en lotes de miles de facturas diarias.
### Resumen de enfoques para facturación electrónica española
Para equipos que desarrollan software de facturación en España, esta tabla resume qué enfoque usar según el sistema de facturación:
| Sistema | Enfoque recomendado | Razón |
|---------|---------------------|-------|
| **VERI\*FACTU** (AEAT) | Enfoque 1 (aislamiento JS) o Enfoque 3 (servidor) | Factura construida dinámicamente en HTML; extracción del elemento `#factura` antes de renderizar |
| **Facturae** B2G | Enfoque 3 (extracción servidor con AngleSharp) | HTML limpio disponible; mayor rendimiento en batch |
| **TicketBAI** (Bizkaia, Gipuzkoa, Araba) | Enfoque 3 (servidor) con `Parallel.ForEach` | Alto volumen síncrono; tickets generados en punto de venta |
| **SII** (grandes empresas AEAT) | Enfoque 3 con `Parallel.ForEach` | Procesamiento batch de facturas en tiempo real |
| Portal AEAT (extracción de documentos online) | Enfoque 4 (URL + JS targeting) | Página de terceros sin acceso al HTML fuente |
| **Crea y Crece** (B2B, **EN 16931 / CIUS-ES**) | Enfoque 3 (extracción servidor) | Facturas B2B generadas desde plantillas HTML estructuradas; extracción de sección de factura antes del archivado PDF/A |
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.
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.
1Install IronPDF with NuGet Package Manager
PM > Install-Package IronPdf
Install-Package IronPdf
2Copie 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");
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");
C#
3Despliegue para probar en su entorno real
Comienza a usar IronPDF en tu proyecto hoy mismo con una prueba gratuita
Flujo de Trabajo Mínimo (3 Pasos)
Instale IronPdf a través de NuGet: Install-Package IronPdf
¿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 elementrenderer.RenderingOptions.Javascript = @" var el = document.querySelector('#invoice-summary'); if (el) { document.body.innerHTML = el.outerHTML; }";// Wait for the target element to exist before JS executesrenderer.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");
ImportsIronPdfDim fullPageHtml AsString = "<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 elementrenderer.RenderingOptions.Javascript = " var el = document.querySelector('#invoice-summary'); if (el) { document.body.innerHTML = el.outerHTML; }"' Wait for the target element to exist before JS executesrenderer.RenderingOptions.WaitFor.HtmlQuerySelector("#invoice-summary", 10000)Dim pdf AsPdfDocument = 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")
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 directlyrenderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000);
// Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000);
' Alternative: wait by ID directlyrenderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000)
' Alternative: wait by ID directly
renderer.RenderingOptions.WaitFor.HtmlElementById("invoice-summary", 10000)
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; }"
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;
}
"
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.
¿Cómo aislar elementos con inyección de CSS?
La propiedad ChromePdfRenderOptions.CustomCssUrl acepta una ruta de archivo o URL a una hoja de estilo que IronPDF aplica antes de renderizar. En lugar de manipular el DOM, escondemos todo excepto el elemento objetivo usando CSS display: none. Esto preserva la estructura original del DOM y evita por completo la ejecución de JavaScript.
using IronPdf;// Create a CSS file that hides everything except #invoice-summarystring cssContent = @"body > *:not(#invoice-summary) { display: none !important;}#invoice-summary { display: block !important; margin: 0; padding: 20px;}";File.WriteAllText("isolate-element.css", cssContent);var renderer = new ChromePdfRenderer();renderer.RenderingOptions.CustomCssUrl = "isolate-element.css";PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);pdf.SaveAs("invoice-css-isolated.pdf");
using IronPdf;
// Create a CSS file that hides everything except #invoice-summary
string cssContent = @"
body > *:not(#invoice-summary) {
display: none !important;
}
#invoice-summary {
display: block !important;
margin: 0;
padding: 20px;
}
";
File.WriteAllText("isolate-element.css", cssContent);
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CustomCssUrl = "isolate-element.css";
PdfDocument pdf = renderer.RenderHtmlAsPdf(fullPageHtml);
pdf.SaveAs("invoice-css-isolated.pdf");
ImportsIronPdfImportsSystem.IO' Create a CSS file that hides everything except #invoice-summaryDim cssContent AsString = "body > *:not(#invoice-summary) { display: none !important;}#invoice-summary { display: block !important; margin: 0; padding: 20px;}"File.WriteAllText("isolate-element.css", cssContent)Dim renderer As New ChromePdfRenderer()renderer.RenderingOptions.CustomCssUrl = "isolate-element.css"Dim pdf AsPdfDocument = renderer.RenderHtmlAsPdf(fullPageHtml)pdf.SaveAs("invoice-css-isolated.pdf")
Imports IronPdf
Imports System.IO
' Create a CSS file that hides everything except #invoice-summary
Dim cssContent As String = "
body > *:not(#invoice-summary) {
display: none !important;
}
#invoice-summary {
display: block !important;
margin: 0;
padding: 20px;
}
"
File.WriteAllText("isolate-element.css", cssContent)
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.CustomCssUrl = "isolate-element.css"
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fullPageHtml)
pdf.SaveAs("invoice-css-isolated.pdf")
Nota: La propiedad CustomCssUrl solo funciona con RenderHtmlAsPdf() al renderizar desde cadenas HTML. Para renderizar desde URL, inserte la inyección CSS en la propiedad Javascript en su lugar:
Cuando controlamos el HTML fuente, las reglas @media print ofrecen la alternativa más liviana: sin dependencias externas, sin inyección en tiempo de ejecución:
Esto es ideal para escenarios de impresión de sección de formularios donde la aplicación ya define reglas @media print, o el Enfoque 3 cuando el HTML del formulario se ensambla del lado del servidor.
El enfoque CSS tiene una limitación importante: los elementos ocultos aún ocupan espacio en el flujo del documento si se usa display: none en el nivel de especificidad equivocado. Siempre use !important para anular estilos de framework (Bootstrap, Tailwind) que podrían volver a mostrar elementos en ciertos puntos de ruptura. Para objetivos profundamente anidados, un selector más preciso evita ocultamientos colaterales:
body > *:not(#target),
body > *:not(#target) ~ * {
display: none !important;
}
Text
¿Cómo extraer fragmentos HTML del lado del servidor?
Cuando tenemos acceso al HTML sin procesar - leyéndolo desde un archivo, una base de datos, un CMS, o una respuesta HTTP - el enfoque más limpio es extraer el elemento objetivo del lado del servidor usando un analizador HTML, luego pasar el fragmento a RenderHtmlAsPdf(). Sin JavaScript, sin inyección de CSS, sin manipulación del DOM en tiempo de ejecución.
AngleSharp es el analizador HTML estándar de .NET para este patrón:
using IronPdf;using AngleSharp;using AngleSharp.Html.Parser;string fullPageHtml = @"<html><head> <style> table { border-collapse: collapse; width: 100%; } td, th { border: 1px solid #ddd; padding: 8px; text-align: left; } </style></head><body> <header><h1>Dashboard</h1></header> <div id='revenue-widget'> <h3>Q4 Revenue</h3> <table> <tr><th>Month</th><th>Revenue</th></tr> <tr><td>October</td><td>$1.2M</td></tr> <tr><td>November</td><td>$1.5M</td></tr> <tr><td>December</td><td>$1.8M</td></tr> </table> </div> <div id='other-content'>Other widgets...</div></body></html>";// Parse and extract the target elementvar parser = new HtmlParser();var document = parser.ParseDocument(fullPageHtml);var targetElement = document.QuerySelector("#revenue-widget");if (targetElement is null){Console.WriteLine("Target element not found."); return;}// Wrap the fragment in a minimal HTML document to preserve stylesstring fragmentHtml = $@"<html><head> <style> table {{ border-collapse: collapse; width: 100%; }} td, th {{ border: 1px solid #ddd; padding: 8px; text-align: left; }} </style></head><body> {targetElement.OuterHtml}</body></html>";var renderer = new ChromePdfRenderer();PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);pdf.SaveAs("revenue-widget.pdf");
using IronPdf;
using AngleSharp;
using AngleSharp.Html.Parser;
string fullPageHtml = @"
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
td, th { border: 1px solid #ddd; padding: 8px; text-align: left; }
</style>
</head>
<body>
<header><h1>Dashboard</h1></header>
<div id='revenue-widget'>
<h3>Q4 Revenue</h3>
<table>
<tr><th>Month</th><th>Revenue</th></tr>
<tr><td>October</td><td>$1.2M</td></tr>
<tr><td>November</td><td>$1.5M</td></tr>
<tr><td>December</td><td>$1.8M</td></tr>
</table>
</div>
<div id='other-content'>Other widgets...</div>
</body>
</html>";
// Parse and extract the target element
var parser = new HtmlParser();
var document = parser.ParseDocument(fullPageHtml);
var targetElement = document.QuerySelector("#revenue-widget");
if (targetElement is null)
{
Console.WriteLine("Target element not found.");
return;
}
// Wrap the fragment in a minimal HTML document to preserve styles
string fragmentHtml = $@"
<html>
<head>
<style>
table {{ border-collapse: collapse; width: 100%; }}
td, th {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
</style>
</head>
<body>
{targetElement.OuterHtml}
</body>
</html>";
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);
pdf.SaveAs("revenue-widget.pdf");
ImportsIronPdfImportsAngleSharpImportsAngleSharp.Html.ParserDim fullPageHtml AsString = "<html><head> <style> table { border-collapse: collapse; width: 100%; } td, th { border: 1px solid #ddd; padding: 8px; text-align: left; } </style></head><body> <header><h1>Dashboard</h1></header> <div id='revenue-widget'> <h3>Q4 Revenue</h3> <table> <tr><th>Month</th><th>Revenue</th></tr> <tr><td>October</td><td>$1.2M</td></tr> <tr><td>November</td><td>$1.5M</td></tr> <tr><td>December</td><td>$1.8M</td></tr> </table> </div> <div id='other-content'>Other widgets...</div></body></html>"' Parse and extract the target elementDim parser As New HtmlParser()Dim document = parser.ParseDocument(fullPageHtml)Dim targetElement = document.QuerySelector("#revenue-widget")If targetElement Is Nothing ThenConsole.WriteLine("Target element not found.") ReturnEnd If' Wrap the fragment in a minimal HTML document to preserve stylesDim fragmentHtml AsString = $"<html><head> <style> table {{ border-collapse: collapse; width: 100%; }} td, th {{ border: 1px solid #ddd; padding: 8px; text-align: left; }} </style></head><body> {targetElement.OuterHtml}</body></html>"Dim renderer As New ChromePdfRenderer()Dim pdf AsPdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml)pdf.SaveAs("revenue-widget.pdf")
Imports IronPdf
Imports AngleSharp
Imports AngleSharp.Html.Parser
Dim fullPageHtml As String = "
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
td, th { border: 1px solid #ddd; padding: 8px; text-align: left; }
</style>
</head>
<body>
<header><h1>Dashboard</h1></header>
<div id='revenue-widget'>
<h3>Q4 Revenue</h3>
<table>
<tr><th>Month</th><th>Revenue</th></tr>
<tr><td>October</td><td>$1.2M</td></tr>
<tr><td>November</td><td>$1.5M</td></tr>
<tr><td>December</td><td>$1.8M</td></tr>
</table>
</div>
<div id='other-content'>Other widgets...</div>
</body>
</html>"
' Parse and extract the target element
Dim parser As New HtmlParser()
Dim document = parser.ParseDocument(fullPageHtml)
Dim targetElement = document.QuerySelector("#revenue-widget")
If targetElement Is Nothing Then
Console.WriteLine("Target element not found.")
Return
End If
' Wrap the fragment in a minimal HTML document to preserve styles
Dim fragmentHtml As String = $"
<html>
<head>
<style>
table {{ border-collapse: collapse; width: 100%; }}
td, th {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
</style>
</head>
<body>
{targetElement.OuterHtml}
</body>
</html>"
Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml)
pdf.SaveAs("revenue-widget.pdf")
El detalle clave es envolver el fragmento extraído en un documento HTML completo con las etiquetas <style> o <link> relevantes. Sin este contenedor, los estilos en línea se renderizan correctamente, pero se pierden hojas de estilo externas y reglas CSS heredadas. Para la renderización de vistas previas de plantillas de correo electrónico, donde el HTML de la plantilla ya está almacenado como una cadena, este patrón de extracción brinda resultados perfectos en píxeles porque controlamos cada aspecto del contenido renderizado.
El mismo patrón funciona con HtmlAgilityPack como un analizador alternativo:
using HtmlAgilityPack;using IronPdf;var htmlDoc = new HtmlDocument();htmlDoc.LoadHtml(fullPageHtml);var targetNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='revenue-widget']");if (targetNode is null){Console.WriteLine("Target element not found."); return;}string fragmentHtml = $"<html><body>{targetNode.OuterHtml}</body></html>";var renderer = new ChromePdfRenderer();PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);pdf.SaveAs("revenue-widget-hap.pdf");
using HtmlAgilityPack;
using IronPdf;
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(fullPageHtml);
var targetNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='revenue-widget']");
if (targetNode is null)
{
Console.WriteLine("Target element not found.");
return;
}
string fragmentHtml = $"<html><body>{targetNode.OuterHtml}</body></html>";
var renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml);
pdf.SaveAs("revenue-widget-hap.pdf");
ImportsHtmlAgilityPackImportsIronPdfDim htmlDoc As New HtmlDocument()htmlDoc.LoadHtml(fullPageHtml)Dim targetNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='revenue-widget']")If targetNode Is Nothing ThenConsole.WriteLine("Target element not found.") ReturnEnd IfDim fragmentHtml AsString = $"<html><body>{targetNode.OuterHtml}</body></html>"Dim renderer As New ChromePdfRenderer()Dim pdf AsPdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml)pdf.SaveAs("revenue-widget-hap.pdf")
Imports HtmlAgilityPack
Imports IronPdf
Dim htmlDoc As New HtmlDocument()
htmlDoc.LoadHtml(fullPageHtml)
Dim targetNode = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='revenue-widget']")
If targetNode Is Nothing Then
Console.WriteLine("Target element not found.")
Return
End If
Dim fragmentHtml As String = $"<html><body>{targetNode.OuterHtml}</body></html>"
Dim renderer As New ChromePdfRenderer()
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml)
pdf.SaveAs("revenue-widget-hap.pdf")
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml, @"C:\templates\assets\");
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml, @"C:\templates\assets\");
Dim pdf AsPdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml, "C:\templates\assets\")
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml, "C:\templates\assets\")
La elección entre AngleSharp y HtmlAgilityPack es principalmente una preferencia. AngleSharp usa selectores CSS (QuerySelector), que se alinean con los modelos mentales de los desarrolladores de frontend. HtmlAgilityPack usa XPath (SelectSingleNode), que es más familiar en bases de código .NET orientadas a XML.
Para la renderización previa de plantillas de correo electrónico — generando una vista previa en PDF de una plantilla de correo electrónico HTML antes de enviarlo — es un escenario puro del Enfoque 3. El HTML de la plantilla es una cadena almacenada, los recursos externos (imágenes, fuentes) están alojados en URLs conocidas, y el parámetro RenderHtmlAsPdf(string Html, string BaseUrlOrPath) en RenderHtmlAsPdf() resuelve todas las rutas relativas.
Cuando el HTML contiene <div id="app"></div> que una aplicación React o Vue completa en tiempo de ejecución, el fragmento extraído estará vacío. Para esos casos, use el Enfoque 1 o 4.
¿Cómo enfocar elementos al renderizar URLs en vivo?
Para URLs en vivo donde no podemos acceder al HTML fuente - paneles de terceros, informes externos, aplicaciones alojadas - combinamos RenderUrlAsPdf() con la propiedad Javascript y WaitFor para aislar una sección específica después de que se carga la página.
Este es el escenario de exportación de widgets de tablero: una herramienta de BI genera gráficos y tablas en una página web, y necesitamos exportar un solo widget como PDF para la distribución a las partes interesadas.
using IronPdf;var renderer = new ChromePdfRenderer();renderer.RenderingOptions.EnableJavaScript = true;// Wait for the dashboard widget to render (async content)renderer.RenderingOptions.WaitFor.HtmlQuerySelector("[data-widget='revenue-chart']", 15000);// Isolate the widget after it rendersrenderer.RenderingOptions.Javascript = @" var widget = document.querySelector('[data-widget=""revenue-chart""]'); if (widget) { // Preserve computed styles by cloning into a clean body document.body.innerHTML = ''; document.body.appendChild(widget); }";PdfDocument pdf = renderer.RenderUrlAsPdf("https://dashboard.example.com/q4-report");pdf.SaveAs("revenue-chart-export.pdf");
using IronPdf;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;
// Wait for the dashboard widget to render (async content)
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("[data-widget='revenue-chart']", 15000);
// Isolate the widget after it renders
renderer.RenderingOptions.Javascript = @"
var widget = document.querySelector('[data-widget=""revenue-chart""]');
if (widget) {
// Preserve computed styles by cloning into a clean body
document.body.innerHTML = '';
document.body.appendChild(widget);
}
";
PdfDocument pdf = renderer.RenderUrlAsPdf("https://dashboard.example.com/q4-report");
pdf.SaveAs("revenue-chart-export.pdf");
ImportsIronPdfDim renderer As New ChromePdfRenderer()renderer.RenderingOptions.EnableJavaScript = True' Wait for the dashboard widget to render (async content)renderer.RenderingOptions.WaitFor.HtmlQuerySelector("[data-widget='revenue-chart']", 15000)' Isolate the widget after it rendersrenderer.RenderingOptions.Javascript = " var widget = document.querySelector('[data-widget=""revenue-chart""]); if (widget) { // Preserve computed styles by cloning into a clean body document.body.innerHTML = ''; document.body.appendChild(widget); }"Dim pdf AsPdfDocument = renderer.RenderUrlAsPdf("https://dashboard.example.com/q4-report")pdf.SaveAs("revenue-chart-export.pdf")
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.EnableJavaScript = True
' Wait for the dashboard widget to render (async content)
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("[data-widget='revenue-chart']", 15000)
' Isolate the widget after it renders
renderer.RenderingOptions.Javascript = "
var widget = document.querySelector('[data-widget=""revenue-chart""]);
if (widget) {
// Preserve computed styles by cloning into a clean body
document.body.innerHTML = '';
document.body.appendChild(widget);
}
"
Dim pdf As PdfDocument = renderer.RenderUrlAsPdf("https://dashboard.example.com/q4-report")
pdf.SaveAs("revenue-chart-export.pdf")
La llamada WaitFor.HtmlQuerySelector() asegura que el widget exista en el DOM antes de que se ejecute el JavaScript. El tiempo de espera de 15 segundos acomoda llamadas API más lentas que completan los datos del tablero. El JavaScript luego reduce la página solo al widget.
Para páginas con dependencias CSS complejas, el enfoque appendChild (moviendo el nodo en lugar de copiar su outerHTML) preserva más estilos calculados porque el elemento conserva su posición en el CSSOM. El enfoque de reemplazo innerHTML del Enfoque 1 es más simple pero puede perder estilos que dependen de selectores ascendentes.
Cuando la página objetivo requiere autenticación, configure cookies en el renderer antes de llamar RenderUrlAsPdf():
ImportsSystem.Collections.Genericrenderer.RenderingOptions.CustomCookies = New Dictionary(OfString, String) From { {"session_id", "abc123"}, {"auth_token", "bearer-xyz"}}
Imports System.Collections.Generic
renderer.RenderingOptions.CustomCookies = New Dictionary(Of String, String) From {
{"session_id", "abc123"},
{"auth_token", "bearer-xyz"}
}
La clase WaitFor ofrece estrategias de espera adicionales más allá de HtmlQuerySelector(). NetworkIdle0() espera hasta que todas las solicitudes de red completas con cero conexiones pendientes - útil para paneles de control que cargan datos de múltiples puntos finales API. NetworkIdle2() tolera hasta dos conexiones pendientes, que maneja páginas con conexiones persistentes de WebSocket o sondeo largo. JavaScript() espera a que la página llame a window.ironpdf.notifyRender() - la opción más precisa cuando controlamos la página objetivo y podemos señalar la preparación para renderizar explícitamente después de que todos los datos se carguen y se completen las animaciones.
Para exportaciones de tableros recurrentes (por ejemplo, generación nocturna de PDF para distribución de correos electrónicos a las partes interesadas), envuelva la renderización en un bucle de reintento que capture excepciones de tiempo de espera. Si WaitFor excede su maxWaitTime, IronPDF procede a renderizar cualquier contenido disponible, lo cual puede estar incompleto. Aumentar el tiempo de espera o cambiar a NetworkIdle0() generalmente resuelve fallas intermitentes en redes más lentas.
Comparación de los Cuatro Enfoques
Acercarse
Lo mejor para
Requiere HTML Fuente
Dependencia de JS
Complejidad
Aislamiento del DOM con JavaScript
Extracción de elementos de uso general desde cualquier fuente
No
Sí
Medium
Inyección de CSS
Ocultando secciones sin cambios en el DOM; layout @media print
Parcial (CustomCssUrl necesita RenderHtmlAsPdf)
No (a menos que se inyecte a través de JS para URLs)
Low
Extracción de Fragmentos del Lado del Servidor
Contenido de CMS, plantillas almacenadas, vistas previas de correos electrónicos
Sí
No
Bajo–Medio
Renderización de URLs con Enfoque JavaScript
Paneles en vivo, páginas de terceros, widgets SPA
No
Sí
Medio–Alto
Eligiendo el Enfoque Correcto
La decisión depende de dos factores: si tenemos acceso al HTML bruto, y si el contenido objetivo requiere JavaScript para renderizar.
la extracción de ítems de línea Invoice es el caso de uso más común. Cuando el HTML de la factura se genera del lado del servidor (vistas Razor, plantillas Handlebars, cadenas HTML almacenadas), el Enfoque 3 (extracción del lado del servidor) da el resultado más limpio sin costo de ejecución. Extraiga la tabla #line-items, envuélvala en una carcasa HTML con estilo y renderice.
la exportación de widget Dashboard requiere ejecución de JavaScript porque el contenido del widget es rellenado por llamadas API después de la carga inicial de la página. El Enfoque 1 (aislamiento del DOM con JS) maneja esto cuando el tablero se ejecuta localmente o detrás de una autenticación. El Enfoque 4 (renderización de URLs con enfoque JS) es necesario cuando el tablero es una aplicación alojada por terceros donde solo tenemos la URL.
la impresión de secciones Form - extrayendo una sección específica de un formulario de múltiples pasos para revisión del usuario o archivo de cumplimiento - se mapea naturalmente al Enfoque 2 (inyección CSS) cuando la aplicación ya define reglas @media print, o al Enfoque 3 cuando el HTML del formulario se ensambla del lado del servidor.
la renderización de vista previa de plantilla Email - generando una vista previa en PDF de una plantilla de correo electrónico HTML antes de enviar - es un escenario puro del Enfoque 3. El HTML de la plantilla es una cadena almacenada, los recursos externos (imágenes, fuentes) están alojados en URLs conocidas, y el parámetro BaseUrlOrPath en RenderHtmlAsPdf() resuelve todas las rutas relativas.
Para aplicaciones que necesitan soportar múltiples escenarios, encapsule la lógica de renderización detrás de una interfaz de servicio que acepte un parámetro de estrategia:
public enum ElementExtractionStrategy{JavaScriptIsolation,CssInjection,ServerSideExtraction,UrlWithJsTargeting}
public enum ElementExtractionStrategy
{
JavaScriptIsolation,
CssInjection,
ServerSideExtraction,
UrlWithJsTargeting
}
Public Enum ElementExtractionStrategy
JavaScriptIsolation
CssInjection
ServerSideExtraction
UrlWithJsTargeting
End Enum
Esto permite que el código que llama seleccione el enfoque apropiado basado en el tipo de entrada sin duplicar la configuración del renderizador.
Mi biblioteca favorita de este tipo es IronPDF. Permite una manipulación rápida y eficiente de archivos PDF. También tiene muchas funciones valiosas, como exportar al formato PDF/A y firmar documentos PDF digitalmente.
IronOCR significa que podemos ahorrar $40,000 anualmente en el procesamiento manual, mientras mejoramos la productividad y liberamos recursos para tareas de alto impacto. Lo recomendaría encarecidamente.
El Iron Suite juega un papel crucial en nuestras operaciones. Estas son herramientas que aumentan la eficiencia en toda la empresa, incluyendo la creación de planos y la mejora en la gestión de inventario.
Casos de uso en facturación electrónica española: VERI*FACTU y Facturae
La capacidad de IronPDF para convertir elementos HTML específicos a PDF tiene aplicaciones directas en el ecosistema de facturación electrónica española:
Generación de recibos VERI*FACTU desde elementos HTML
El sistema VERI*FACTU de la AEAT exige que el software de facturación genere representaciones gráficas de las facturas. Cuando la factura se construye dinámicamente en HTML (por ejemplo, desde una plantilla Razor o una plantilla HTML con datos de la transacción), el Enfoque 1 (aislamiento DOM de JavaScript) permite extraer solo el elemento <div id="factura-verifactu"> y renderizarlo como PDF:
var renderer = new ChromePdfRenderer();renderer.RenderingOptions.EnableJavaScript = true;renderer.RenderingOptions.Javascript = @" var factura = document.querySelector('#factura-verifactu'); document.body.innerHTML = factura.outerHTML;";renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#factura-verifactu", 5000);var pdf = renderer.RenderHtmlAsPdf(facturaHtml);pdf.SaveAs("factura-verifactu.pdf");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.Javascript = @"
var factura = document.querySelector('#factura-verifactu');
document.body.innerHTML = factura.outerHTML;
";
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("#factura-verifactu", 5000);
var pdf = renderer.RenderHtmlAsPdf(facturaHtml);
pdf.SaveAs("factura-verifactu.pdf");
C#
Exportación de secciones de facturas Facturae
Las facturas Facturae (formato XML B2G para la Administración Pública española) se acompañan habitualmente de una representación gráfica en PDF. El Enfoque 3 (extracción del lado del servidor) es el más eficiente para generar este PDF desde el HTML de la factura usando AngleSharp para extraer la sección relevante:
Aísle el bloque de datos fiscales (<section id="datos-facturacion">) antes de renderizar.
Aplique estilos corporativos y el pie de firma electrónica mediante CSS adicional.
Renderice el fragmento extraído con RenderHtmlAsPdf() en un loop de procesamiento por lotes para generar cientos de facturas Facturae simultáneamente.
Rendimiento en pipelines SII y TicketBAI
Para el SII (Suministro Inmediato de Información) — donde las facturas se procesan en lotes en tiempo real — y para TicketBAI en Bizkaia, Gipuzkoa y Araba — donde los tickets se generan de forma síncrona — el rendimiento es crítico. Como se indica en la sección de "Próximos pasos", la extracción del lado del servidor con Parallel.ForEach y múltiples instancias ChromePdfRenderer ofrece la mayor eficiencia para el procesamiento de alto volumen típico de estos sistemas.
Próximos pasos
La aislación de elementos HTML en IronPDF es una preocupación en tiempo de renderizado, no una característica de API integrada. Los cuatro enfoques mencionados cubren todo el espectro, desde la extracción de plantillas del lado del servidor (cero JS, salida más limpia) hasta la orientación de URLs en vivo (ejecución completa de JS, maneja SPAs y contenido asíncrono). La tabla de comparación proporciona una referencia rápida, y los escenarios del mundo real mapean requerimientos comunes de negocio con la estrategia apropiada.
Algunas consideraciones adicionales para implementaciones en producción:
Rendimiento: La extracción del lado del servidor (Enfoque 3) es la más rápida porque omite por completo la ejecución de JavaScript. Los enfoques basados en JavaScript (1 y 4) agregan sobrecarga proporcional a la complejidad de la página y al tiempo de espera WaitFor. Para el procesamiento por lotes (por ejemplo, generando 500 PDFs de facturas), la extracción del lado del servidor con Parallel.ForEach y múltiples instancias ChromePdfRenderer proporciona el mejor rendimiento.
Depuración: cuando la salida del PDF está en blanco o falta contenido, habilite EnableJavaScript = true y aumente el tiempo de espera WaitFor. Si el elemento objetivo depende de datos asíncronos, WaitFor.NetworkIdle0() es más confiable que un RenderDelay fijo. La guía de opciones de renderización cubre configuraciones de ancho de vista y ajuste de papel que afectan el diseño.
Combinación de enfoques: Nada impide mezclar estrategias. Podemos usar extracción del lado del servidor para construir un documento HTML compuesto a partir de múltiples fragmentos (encabezado de una fuente, tabla de datos de otra, SVG de gráficos de una tercera), y luego renderizar el documento ensamblado como un único PDF. El método RenderHtmlAsPdf(string Html, string BaseUrlOrPath) resuelve rutas de activos relativas desde la URL base, lo que facilita componer documentos de fuentes heterogéneas.
Marco normativo español para la extracción de elementos HTML a PDF
La extracción de secciones HTML específicas a PDF tiene implicaciones normativas directas en el mercado español que van más allá de la optimización técnica.
Modelo de datos VeriFactu y representación gráfica: El Real Decreto 1007/2023 establece que el software de facturación certificado bajo VERI*FACTU debe generar una representación visual del registro de facturación que incluya la leyenda obligatoria Factura verificable en la sede electrónica de la AEAT y el código QR de verificación. Cuando la factura se construye como una página HTML con múltiples secciones (cabecera con datos del emisor NIF/CIF B-28000001, cuerpo con líneas de factura con importes en EUR, pie con el QR AEAT), el Enfoque 1 (aislamiento DOM) o el Enfoque 3 (extracción servidor) permiten generar el PDF con únicamente la sección de factura, sin incluir elementos de navegación ni encabezados de la interfaz de usuario.
Facturae B2G y arquitectura de extracción: Las facturas Facturae 3.2.2 para el portal FACe de la Administración General del Estado requieren que la representación gráfica PDF refleje exactamente los mismos datos que el fichero XML. El Enfoque 3 (AngleSharp o HtmlAgilityPack) es el más adecuado para extraer el bloque fiscal HTML (#seccion-factura-completa) desde el sistema de generación, garantizando una correspondencia exacta entre el XML y el PDF adjunto en el PDF/A-3 enviado a FACe.
TicketBAI en Bizkaia, Gipuzkoa y Araba: Los sistemas de punto de venta bajo TicketBAI en los tres territorios forales del País Vasco generan tiques en HTML con el código QR foral y el número de correlativo de huella XAdES encadenada. El Enfoque 3 con extracción del lado del servidor es el más eficiente para pipelines de alta frecuencia (p. ej., generación síncrona de PDFs de tique en Bizkaia/BATUZ durante horas punta de punto de venta), ya que no requiere ejecución de JavaScript ni navegador, y procesa los tickets a máxima velocidad.
SII (Suministro Inmediato de Información) y protección de datos: El SII de la AEAT exige la remisión en tiempo casi real de datos de facturas. Los PDFs de confirmación generados para el contribuyente contienen datos personales del emisor y receptor (NIF/CIF, datos de contacto), datos sujetos a la LOPDGDD supervisada por la AEPD. La extracción del lado del servidor (Enfoque 3) minimiza el riesgo de exposición de datos porque procesa el fragmento HTML sin almacenar la página completa con datos de sesión u otras secciones sensibles.
Crea y Crece (Ley 18/2022) y representación visual EN 16931/CIUS-ES: La Ley Crea y Crece establece factura electrónica B2B obligatoria bajo el estándar EN 16931 con extensión española CIUS-ES a partir de 2027–2028. Los ISV que desarrollan plataformas de facturación necesitarán generar PDFs de representación visual que acompañen al fichero XML. La extracción de la sección de factura desde el HTML usando el Enfoque 3 es la arquitectura más escalable para generar estos PDFs en lotes de miles de facturas diarias.
Resumen de enfoques para facturación electrónica española
Para equipos que desarrollan software de facturación en España, esta tabla resume qué enfoque usar según el sistema de facturación:
Sistema
Enfoque recomendado
Razón
VERI*FACTU (AEAT)
Enfoque 1 (aislamiento JS) o Enfoque 3 (servidor)
Factura construida dinámicamente en HTML; extracción del elemento #factura antes de renderizar
Facturae B2G
Enfoque 3 (extracción servidor con AngleSharp)
HTML limpio disponible; mayor rendimiento en batch
TicketBAI (Bizkaia, Gipuzkoa, Araba)
Enfoque 3 (servidor) con Parallel.ForEach
Alto volumen síncrono; tickets generados en punto de venta
SII (grandes empresas AEAT)
Enfoque 3 con Parallel.ForEach
Procesamiento batch de facturas en tiempo real
Portal AEAT (extracción de documentos online)
Enfoque 4 (URL + JS targeting)
Página de terceros sin acceso al HTML fuente
Crea y Crece (B2B, EN 16931 / CIUS-ES)
Enfoque 3 (extracción servidor)
Facturas B2B generadas desde plantillas HTML estructuradas; extracción de sección de factura antes del archivado PDF/A
Preguntas Frecuentes
¿Cuáles son los enfoques principales para convertir elementos HTML a PDF en C#?
Los enfoques principales incluyen aislamiento JS, ocultación CSS, extracción del lado del servidor y orientación de URL en vivo, todos los cuales pueden implementarse usando IronPDF.
¿Cómo funciona el aislamiento JS en el contexto de la conversión de HTML a PDF?
El aislamiento JS implica ejecutar JavaScript para manipular dinámicamente el documento HTML antes de convertirlo a PDF. Esto se puede lograr usando IronPDF para asegurar que solo se rendericen elementos específicos.
¿Qué es la ocultación CSS y cómo se usa en la conversión a PDF?
La ocultación CSS implica usar estilos CSS para ocultar elementos que no deben aparecer en el PDF. IronPDF soporta esto al permitir que los desarrolladores especifiquen hojas de estilo o reglas de estilo durante el proceso de conversión.
¿Puede IronPDF extraer elementos HTML específicos en el lado del servidor para la generación de PDF?
Sí, IronPDF puede extraer elementos HTML específicos en el lado del servidor, permitiendo un control preciso sobre qué partes de una página web se convierten en un PDF.
¿Cuál es la ventaja de la orientación de URL en vivo en la conversión de HTML a PDF?
La orientación de URL en vivo permite que IronPDF convierta elementos de una URL de página web en vivo directamente a PDF, asegurando que el contenido más actual se capture sin necesidad de archivos HTML locales.
¿Es posible convertir solo una sección de una página web a PDF usando IronPDF?
Sí, IronPDF proporciona funcionalidad para convertir secciones o elementos específicos de una página web a PDF, facilitando el enfoque en contenido relevante.
¿Cómo puede IronPDF manejar contenido dinámico durante la conversión de HTML a PDF?
IronPDF puede renderizar contenido dinámico ejecutando JavaScript durante la conversión, asegurando que los elementos que dependen de scripts del lado del cliente se representen con precisión en el PDF.
How do I maintain CSS styles when isolating HTML elements for PDF?