Comment convertir des éléments HTML et des sections partielles de page en PDF en C

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

IronPDF ne propose pas de méthode intégrée SelectElement ou SelectCss permettant de cibler des éléments HTML spécifiques. Le ChromePdfRenderer affiche des documents HTML complets : une page entière, une URL complète, une chaîne HTML complète. Pour produire un PDF à partir d'une section spécifique d'une page, nous isolons l'élément cible avant le rendu en utilisant l'une des quatre approches : manipulation du DOM JavaScript, injection CSS, extraction de fragments HTML côté serveur, ou rendu d'URL avec ciblage JS.

Chaque approche convient à une contrainte différente. L'isolation DOM JavaScript fonctionne lors du rendu d'URLs ou de pages complètes où nous devons supprimer tout sauf la cible. L'injection CSS cache le contenu indésirable sans altérer le DOM. L'extraction côté serveur fournit le résultat le plus propre lorsque nous avons accès au HTML brut. Le rendu d'URL avec ciblage JS gère les tableaux de bord en direct et les pages tierces où le HTML source n'est pas disponible.

Commencez un essai gratuit de 30 jours pour tester les quatre approches.

Démarrage rapide : extraire un élément HTML spécifique sous forme de PDF

Ciblez n'importe quel élément à l'aide d'un sélecteur CSS en utilisant l'isolation DOM JavaScript et WaitFor, puis générez uniquement ce fragment au format PDF.

  1. Installez IronPDF avec le Gestionnaire de Packages NuGet

    PM > Install-Package IronPdf
  2. Copiez et exécutez cet extrait de code.

    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. Déployez pour tester sur votre environnement de production.

    Commencez à utiliser IronPDF dans votre projet dès aujourd'hui avec un essai gratuit

    arrow pointer

Flux de travail minimal (3 étapes)

  1. Installez IronPdf via NuGet : Install-Package IronPdf
  2. Configurez ChromePdfRenderOptions.JavaScript pour isoler l'élément cible et WaitFor pour vous assurer qu'il existe
  3. Appelez RenderHtmlAsPdf() ou RenderUrlAsPdf() — le PDF ne contient que le contenu isolé

Comment isoler des éléments avec la manipulation du DOM JavaScript ?

La propriété ChromePdfRenderOptions.JavaScript accepte une chaîne JavaScript qui s'exécute après le chargement du code HTML mais avant le rendu du PDF. En remplaçant document.body.innerHTML par le outerHTML de l'élément cible, nous supprimons tout le reste de la page affichée. Il s'agit de l'approche la plus polyvalente : elle fonctionne à la fois avec RenderHtmlAsPdf() et RenderUrlAsPdf().

La méthode WaitFor.HtmlQuerySelector() garantit que l'élément cible existe dans le DOM avant l'exécution du JavaScript. C'est crucial pour les pages au contenu asynchrone — composants React, modèles Angular ou données pilotées par API qui se remplissent après le chargement initial de la page.

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

Le code JavaScript remplace l'intégralité du corps par le div #invoice-summary. Le PDF résultant ne contient que le tableau de facturation — pas d'en-tête, pas de navigation, pas de pied de page. La méthode WaitFor.HtmlElementById() offre une alternative plus simple pour le ciblage par 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

Pour les sélecteurs complexes (noms de classes, attributs de données, éléments imbriqués), HtmlQuerySelector() accepte toute chaîne de sélecteur CSS valide que document.querySelector() accepterait. D'autres méthodes pratiques WaitFor incluent HtmlElementByClassName(), HtmlElementByName() et HtmlElementByTagName() — chacune délègue en interne à HtmlQuerySelector() mais permet d'exprimer plus clairement l'intention dans le code.

Lorsque l'élément cible dépend de styles hérités de conteneurs parents, le remplacement outerHTML peut entraîner la perte de règles CSS qui s'appuient sur des sélecteurs d'ancêtres (par exemple, .dashboard .widget table { ...}). Pour les conserver, copiez les balises <style> et <link> pertinentes du <head> dans l'isolation 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

Cela permet de conserver le contenu original <head> (feuilles de style, polices, balises méta) tout en ne remplaçant que le corps du texte. Les guides pratiques " JavaScript to PDF " et " WaitFor " couvrent des options de configuration supplémentaires, notamment NetworkIdle0() pour les pages comportant plusieurs sources de données asynchrones.

Comment isoler des éléments avec l'injection CSS ?

La propriété ChromePdfRenderOptions.CustomCssUrl accepte un chemin d'accès ou une URL vers une feuille de style qu'IronPDF applique avant le rendu. Au lieu de manipuler le DOM, nous masquons tout sauf l'élément cible à l'aide de CSS display: none. Cela préserve la structure DOM originale et évite entièrement l'exécution de JavaScript.

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");
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");
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")
$vbLabelText   $csharpLabel

Remarque : la propriété CustomCssUrl ne fonctionne qu'avec RenderHtmlAsPdf() lors du rendu à partir de chaînes HTML. Pour le rendu des URL, intégrez plutôt l'injection CSS dans la propriété JavaScript :

renderer.RenderingOptions.JavaScript = @"
    var style = document.createElement('style');
    style.textContent = 'body > *:not(#invoice-summary) { display: none !important; }';
    document.head.appendChild(style);
";
renderer.RenderingOptions.JavaScript = @"
    var style = document.createElement('style');
    style.textContent = 'body > *:not(#invoice-summary) { display: none !important; }';
    document.head.appendChild(style);
";
renderer.RenderingOptions.JavaScript = "
    var style = document.createElement('style');
    style.textContent = 'body > *:not(#invoice-summary) { display: none !important; }';
    document.head.appendChild(style);
"
$vbLabelText   $csharpLabel

Lorsque nous contrôlons le code HTML source, les règles @media print offrent l'alternative la plus légère — aucune dépendance externe, aucune injection à l'exécution :

@media print {
    header, nav, footer, .sidebar { display: none !important; }
    #invoice-summary { width: 100%; margin: 0; }
}

Définissez CssMediaType sur PdfCssMediaType.Print dans le moteur de rendu pour activer ces règles :

renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print
$vbLabelText   $csharpLabel

Cette solution est idéale pour les scénarios d'impression de sections de formulaire où l'application définit déjà des règles @media print, ou pour l'approche 3 lorsque le code HTML du formulaire est généré côté serveur.

L'approche CSS présente une limitation importante : les éléments masqués occupent toujours de l'espace dans le flux du document si display: none est utilisé à un niveau de spécificité inapproprié. Utilisez toujours !important pour remplacer les styles du framework (Bootstrap, Tailwind) qui pourraient réafficher des éléments à certains points de rupture. Pour les cibles fortement imbriquées, un sélecteur plus précis évite de masquer par inadvertance.

body > *:not(#target),
body > *:not(#target) ~ * {
    display: none !important;
}

Comment extraire des fragments HTML côté serveur ?

Lorsque nous avons accès au code HTML brut — qu'il soit lu à partir d'un fichier, d'une base de données, d'un CMS ou d'une réponse HTTP —, l'approche la plus propre consiste à extraire l'élément cible côté serveur à l'aide d'un analyseur HTML, puis à transmettre le fragment à RenderHtmlAsPdf(). Pas de JavaScript, pas d'injection CSS, pas de manipulation du DOM au moment de l'exécution.

AngleSharp est le parseur HTML .NET standard pour ce modèle :

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");
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");
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")
$vbLabelText   $csharpLabel

Le point essentiel est d'encapsuler le fragment extrait dans un document HTML complet avec les balises <style> ou <link> appropriées. Sans cet emballage, les styles en ligne se rendent correctement, mais les feuilles de style externes et les règles CSS héritées sont perdues. Pour le rendu de l'aperçu de modèle d'email — où le HTML du modèle est déjà stocké sous forme de chaîne — ce modèle d'extraction donne des résultats précises au pixel près car nous contrôlons chaque aspect du contenu rendu.

Le même modèle fonctionne avec HtmlAgilityPack comme parseur alternatif :

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");
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")
$vbLabelText   $csharpLabel
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml, @"C:\templates\assets\");
PdfDocument pdf = renderer.RenderHtmlAsPdf(fragmentHtml, @"C:\templates\assets\");
Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf(fragmentHtml, "C:\templates\assets\")
$vbLabelText   $csharpLabel

Le choix entre AngleSharp et HtmlAgilityPack est principalement une question de préférence. AngleSharp utilise des sélecteurs CSS (QuerySelector), ce qui correspond aux modèles mentaux des développeurs front-end. HtmlAgilityPack utilise XPath (SelectSingleNode), qui est plus courant dans les bases de code .NET à forte intensité XML.

Pour le rendu de prévisualisation de modèle d'e-mail — générer un aperçu PDF d'un modèle d'e-mail HTML avant envoi — est un scénario pur Approche 3. Le modèle HTML est une chaîne stockée, les ressources externes (images, polices) sont hébergées à des URL connues, et le paramètre RenderHtmlAsPdf(string Html, string BaseUrlOrPath) sur RenderHtmlAsPdf() résout tous les chemins relatifs.

Lorsque le code HTML contient <div id="app"></div> qu'une application React ou Vue remplit lors de l'exécution, le fragment extrait sera vide. Pour ces cas, utilisez l'Approche 1 ou 4.

Comment cibler des éléments lors du rendu d'URLs en direct ?

Pour les URL actives où nous ne pouvons pas accéder au code HTML source (tableaux de bord tiers, rapports externes, applications hébergées), nous combinons RenderUrlAsPdf() avec la propriété JavaScript et WaitFor pour isoler une section spécifique une fois la page chargée.

C'est le scénario d'exportation de widget de tableau de bord : un outil BI rend des graphiques et des tableaux sur une page web, et nous devons exporter un seul widget sous forme de PDF pour la distribution aux parties prenantes.

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");
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");
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")
$vbLabelText   $csharpLabel

L'appel WaitFor.HtmlQuerySelector() garantit que le widget existe dans le DOM avant l'exécution du JavaScript. Le délai de 15 secondes s'adapte aux appels d'API plus lents qui remplissent les données de tableau de bord. Le JavaScript réduit ensuite la page au widget uniquement.

Pour les pages présentant des dépendances CSS complexes, l'approche appendChild (déplacer le nœud plutôt que de copier son outerHTML) préserve davantage de styles calculés, car l'élément conserve sa position dans le CSSOM. L'approche de remplacement innerHTML de l'approche 1 est plus simple, mais peut entraîner la perte de styles dépendant de sélecteurs d'ancêtres.

Lorsque la page cible nécessite une authentification, configurez les cookies sur le moteur de rendu avant d'appeler RenderUrlAsPdf() :

renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "session_id", "abc123" },
    { "auth_token", "bearer-xyz" }
};
renderer.RenderingOptions.CustomCookies = new Dictionary<string, string>
{
    { "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"}
}
$vbLabelText   $csharpLabel

La classe WaitFor offre des stratégies d'attente supplémentaires par rapport à HtmlQuerySelector(). NetworkIdle0() attend que toutes les requêtes réseau soient terminées sans aucune connexion en attente — utile pour les tableaux de bord qui chargent des données à partir de plusieurs points de terminaison API. NetworkIdle2() tolère jusqu'à deux connexions actives, ce qui permet de gérer les pages utilisant des connexions WebSocket persistantes ou le long polling. JavaScript() attend que la page appelle window.ironpdf.notifyRender() — l'option la plus précise lorsque nous contrôlons la page cible et pouvons signaler explicitement que le rendu est prêt une fois que toutes les données sont chargées et que les animations sont terminées.

Pour les exportations de tableaux de bord récurrentes (par exemple, génération de PDF nocturne pour la distribution d'emails aux parties prenantes), encapsulez le rendu dans une boucle de tentative qui intercepte les exceptions de délai. Si WaitFor dépasse sa maxWaitTime, IronPDF procède au rendu du contenu disponible, qui peut être incomplet. Augmenter le délai d'expiration ou passer à NetworkIdle0() permet généralement de résoudre les échecs intermittents sur les réseaux plus lents.

Comparaison des quatre approches

Approche Meilleur pour Nécessite le HTML source Dépendance JS Complexité
Isolement DOM JavaScript Extraction d'éléments à usage général à partir de n'importe quelle source Non Oui Medium
Injection CSS Masquage des sections sans modifications du DOM ; @media print mises en page Partiel (CustomCssUrl nécessite RenderHtmlAsPdf) Non (sauf en injectant via JS pour les URLs) Low
Extraction de fragments côté serveur Contenu CMS, modèles stockés, aperçus de courriels Oui Non Bas–Moyen
Rendu d'URL avec ciblage JS Tableaux de bord en direct, pages tierces, widgets SPA Non Oui Moyen–Haut

Choisir la bonne approche

La décision dépend de deux facteurs : si nous avons accès au HTML brut, et si le contenu cible nécessite JavaScript pour être rendu.

Invoice L'extraction de lignes d'articles est le cas d'utilisation le plus courant. Lorsque le HTML de la facture est généré côté serveur (vues Razor, modèles Handlebars, chaînes HTML stockées), l'Approche 3 (extraction côté serveur) donne le résultat le plus propre avec zéro surcharge au moment de l'exécution. Extraire le tableau #line-items, l'intégrer dans une balise HTML stylisée et l'afficher.

Dashboard L'exportation du widget nécessite l'exécution de JavaScript car le contenu du widget est renseigné par des appels API après le chargement initial de la page. L'approche 1 (isolement DOM JS) gère cela lorsque le tableau de bord s'exécute localement ou derrière une authentification. L'approche 4 (rendu d'URL avec ciblage JS) est nécessaire lorsque le tableau de bord est une application hébergée par un tiers où nous n'avons que l'URL.

L'impression de sections Form — extraction d'une section spécifique d'un formulaire en plusieurs étapes à des fins de révision par l'utilisateur ou d'archivage de conformité — correspond naturellement à l'approche 2 (injection CSS) lorsque l'application définit déjà des règles @media print, ou à l'approche 3 lorsque le code HTML du formulaire est assemblé côté serveur.

Email Le rendu de l'aperçu du modèle — génération d'un aperçu PDF d'un modèle d'e-mail HTML avant l'envoi — est un scénario relevant purement de l'approche 3. Le modèle HTML est une chaîne stockée, les ressources externes (images, polices) sont hébergées à des URL connues, et le paramètre BaseUrlOrPath sur RenderHtmlAsPdf() résout tous les chemins relatifs.

Pour les applications qui doivent prendre en charge plusieurs scénarios, encapsulez la logique de rendu derrière une interface de service qui accepte un paramètre de stratégie :

public enum ElementExtractionStrategy
{
    JavaScriptIsolation,
    CssInjection,
    ServerSideExtraction,
    UrlWithJsTargeting
}
public enum ElementExtractionStrategy
{
    JavaScriptIsolation,
    CssInjection,
    ServerSideExtraction,
    UrlWithJsTargeting
}
Public Enum ElementExtractionStrategy
    JavaScriptIsolation
    CssInjection
    ServerSideExtraction
    UrlWithJsTargeting
End Enum
$vbLabelText   $csharpLabel

Cela permet au code appelant de sélectionner l'approche appropriée en fonction du type de saisie sans dupliquer la configuration du moteur de rendu.

Prochaines étapes

L'isolement des éléments HTML dans IronPDF est une préoccupation au moment du rendu, pas une fonctionnalité d'API intégrée. Les quatre approches ci-dessus couvrent tout le spectre — de l'extraction de modèles côté serveur (zéro JS, sortie la plus propre) au ciblage d'URLs en direct (exécution complète de JS, gère les SPAs et le contenu asynchrone). Le tableau de comparaison fournit une référence rapide, et les scénarios du monde réel mappent les exigences commerciales courantes à la stratégie appropriée.

Quelques considérations supplémentaires pour les déploiements en production :

Performance : L'extraction côté serveur (Approche 3) est la plus rapide car elle évite complètement l'exécution de JavaScript. Les approches basées sur JavaScript (1 et 4) ajoutent une surcharge proportionnelle à la complexité de la page et au délai d'expiration WaitFor. Pour le traitement par lots (par exemple, la génération de 500 factures au format PDF), l'extraction côté serveur avec Parallel.ForEach et plusieurs instances ChromePdfRenderer offre le meilleur débit.

Débogage : lorsque le fichier PDF généré est vide ou qu'il manque du contenu, activez EnableJavaScript = true et augmentez le délai d'attente WaitFor. Si l'élément cible dépend de données asynchrones, WaitFor.NetworkIdle0() est plus fiable qu'un RenderDelay fixe. Le guide des options de rendu couvre les configurations de largeur de vue et d'ajustement du papier qui affectent la mise en page.

Combinaison d'approches : Rien n'empêche de mélanger les stratégies. Nous pouvons utiliser l'extraction côté serveur pour construire un document HTML composite à partir de plusieurs fragments (en-tête d'une source, tableau de données d'une autre, SVG de graphique d'une troisième), puis rendre le document assemblé en un seul PDF. La méthode RenderHtmlAsPdf(string Html, string BaseUrlOrPath) résout les chemins d'accès relatifs aux ressources à partir de l'URL de base, ce qui facilite la composition de documents à partir de sources hétérogènes.

Consultez le guide pratique JavaScript vers PDF pour découvrir des modèles d'exécution JS avancés, la documentation WaitFor pour toutes les stratégies d'attente disponibles, le guide des options de rendu pour l'interface complète ChromePdfRenderOptions, et l'exemple de code JavaScript personnalisé pour des extraits de code prêts à l'emploi.

Consultez les options de licence à partir de $999. La référence API ChromePdfRenderOptions et la référence API WaitFor documentent chaque propriété et chaque méthode.

Questions Fréquemment Posées

Quelles sont les principales approches pour convertir des éléments HTML en PDF en C# ?

Les principales approches incluent l'isolement JS, le masquage CSS, l'extraction côté serveur, et le ciblage d'URL en direct, toutes pouvant être mises en œuvre en using IronPDF.

Comment fonctionne l'isolement JS dans le contexte de la conversion HTML en PDF ?

L'isolement JS implique l'exécution de JavaScript pour manipuler dynamiquement le document HTML avant de le convertir en PDF. Cela peut être réalisé en using IronPDF pour s'assurer que seuls les éléments spécifiques sont rendus.

Qu'est-ce que le masquage CSS et comment est-il utilisé dans la conversion en PDF ?

Le masquage CSS implique l'utilisation de styles CSS pour masquer les éléments qui ne doivent pas apparaître dans le PDF. IronPDF prend en charge cela en permettant aux développeurs de spécifier des feuilles de style ou des règles de style au cours du processus de conversion.

IronPDF peut-il extraire des éléments HTML spécifiques côté serveur pour la génération de PDF ?

Oui, IronPDF peut extraire des éléments HTML spécifiques côté serveur, permettant un contrôle précis sur les parties d'une page web qui sont converties en PDF.

Quel est l'avantage du ciblage d'URL en direct dans la conversion HTML en PDF ?

Le ciblage d'URL en direct permet à IronPDF de convertir des éléments à partir d'une URL de page web en direct directement en PDF, assurant la capture du contenu le plus actuel sans besoin de fichiers HTML locaux.

Est-il possible de convertir uniquement une section d'une page web en PDF en using IronPDF ?

Oui, IronPDF fournit la fonctionnalité de convertir des sections ou éléments spécifiques d'une page web en PDF, facilitant la focalisation sur le contenu pertinent.

Comment IronPDF gère-t-il le contenu dynamique lors de la conversion HTML en PDF ?

IronPDF peut rendre du contenu dynamique en exécutant JavaScript lors de la conversion, assurant que les éléments qui dépendent de scripts côté client sont représentés avec précision dans le PDF.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite
Prêt à commencer?
Nuget Téléchargements 19,014,616 | Version : 2026.5 just released
Still Scrolling Icon

Vous faites encore défiler ?

Vous voulez une preuve rapidement ? PM > Install-Package IronPdf
exécuter un échantillon Regardez votre code HTML se transformer en PDF.