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 n'expose pas de méthode intégrée SelectElement ou SelectCss pour cibler des éléments HTML spécifiques. Le ChromePdfRenderer rend 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 par sélecteur CSS en utilisant l'isolation du DOM JavaScript et WaitFor, puis ne rendez que ce fragment en 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 contient uniquement le contenu isolé

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

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

La méthode WaitFor.HtmlQuerySelector() garantit que l'élément cible existe dans le DOM avant que le JavaScript ne s'exécute. 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 JavaScript remplace l'ensemble du corps par #invoice-summary du div outerHTML. 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 lors du 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 data, éléments imbriqués), HtmlQuerySelector() accepte toute chaîne de sélecteur CSS valide que document.querySelector() accepterait. Des méthodes de commodité WaitFor supplémentaires incluent HtmlElementByClassName(), HtmlElementByName(), et HtmlElementByTagName() — chacune délègue en interne à HtmlQuerySelector() mais offre une intention plus claire dans le code.

Lorsque l'élément cible dépend de styles hérités des conteneurs parents, le remplacement outerHTML peut faire perdre des règles CSS qui reposent sur des sélecteurs ancêtres (par ex., .dashboard .widget table { ... }). Pour les préserver, copiez les balises <style> et <link> pertinentes de <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 conserve le contenu <head> original (feuilles de style, polices, balises meta) tout en remplaçant uniquement le corps. Le guide JavaScript to PDF et le guide WaitFor couvrent des options de configuration supplémentaires, y compris NetworkIdle0() pour les pages avec plusieurs sources de données asynchrones.

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

La propriété ChromePdfRenderOptions.CustomCssUrl accepte un chemin de fichier ou une URL vers une feuille de style qu'IronPDF applique avant de rendre. Au lieu de manipuler le DOM, nous cachons tout sauf l'élément cible en utilisant 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 depuis des chaînes HTML. Pour le rendu d'URL, intégrez l'injection CSS dans la propriété JavaScript à la place :

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 HTML source, les règles @media print offrent l'alternative la plus légère — pas de dépendances externes, pas d'injection au moment de l'exécution :

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

Définissez CssMediaType sur PdfCssMediaType.Print sur 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

C'est idéal pour les scénarios d'impression de sections de formulaire où l'application définit déjà des mises en page spécifiques à l'impression. Les formulaires de réclamation d'assurance, les assistants multi-étapes, et les résumés de commande utilisent couramment des règles @media print pour masquer la navigation et les indicateurs de progression tout en élargissant la section de contenu pertinente à pleine largeur.

L'approche CSS a une limitation importante : les éléments cachés occupent toujours de l'espace dans le flux de document si display: none est utilisé au mauvais niveau de spécificité. Utilisez toujours !important pour surcharger les styles de 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 ?

Lorsqu'on a accès au HTML brut — en le lisant à 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 en utilisant un parseur HTML, puis à passer 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 détail clé est d'envelopper le fragment extrait dans un document HTML complet avec les balises <style> ou <link> pertinentes. 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

Le choix entre AngleSharp et HtmlAgilityPack est principalement une question de préférence. AngleSharp utilise des sélecteurs CSS (QuerySelector), ce qui s'aligne avec les modèles mentaux des développeurs frontend. HtmlAgilityPack utilise XPath (SelectSingleNode), qui est plus familier dans les bases de code .NET orientées XML.

Pour le rendu de l'aperçu des modèles d'email — où le HTML du modèle est stocké sous forme de chaîne dans une base de données ou un CMS — l'extraction côté serveur donne des résultats précis au pixel près parce que nous contrôlons chaque aspect du contenu rendu. Nous pouvons également utiliser RenderHtmlAsPdf(string Html, string BaseUrlOrPath) avec le second paramètre pointant vers un répertoire d'assets local, garantissant que les images et les feuilles de style référencées par des chemins relatifs se résolvent correctement :

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 compromis par rapport à l'isolation du DOM JavaScript est que l'extraction côté serveur ne peut pas gérer le contenu qui nécessite un rendu côté client (éléments générés par JavaScript, composants SPA, données récupérées par API). Si le HTML contient <div id="app"></div> qu'une application React ou Vue remplit à 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 URLs en direct où nous ne pouvons pas accéder au 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 après le chargement de la page.

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 que le JavaScript s'exécute. 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 avec des dépendances CSS complexes, l'approche appendChild (déplacer le nœud plutôt que de copier son outerHTML) préserve plus 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 perdre des styles qui dépendent de sélecteurs 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 en plus de HtmlQuerySelector(). NetworkIdle0() attend jusqu'à ce que toutes les requêtes réseau soient terminées avec zéro connexion en cours — utile pour les tableaux de bord qui chargent des données à partir de plusieurs points d'extrémité API. NetworkIdle2() tolère jusqu'à deux connexions en cours, ce qui gère les pages avec des connexions WebSocket persistantes ou des longues requêtes d'interrogation. 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 après 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 son maxWaitTime, IronPDF poursuit le rendu avec le contenu disponible — qui peut être incomplet. Augmenter le délai ou passer à NetworkIdle0() résout généralement 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 Moyen
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) Faible
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.

Extraction de lignes d'élément de facture 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. Extrayez le tableau #line-items, enveloppez-le dans une coque HTML stylisée et rendez.

Exportation de widget de tableau de bord nécessite l'exécution de JavaScript car le contenu du widget est rempli par des appels d'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.

Impression de section de formulaire — extraire une section spécifique d'un formulaire multi-étapes pour une vérification utilisateur ou une archive de conformité — se mappe naturellement à l'Approche 2 (injection CSS) lorsque l'application définit déjà des règles @media print, ou l'Approche 3 lorsque le HTML du formulaire est assemblé côté serveur.

Rendu d'aperçu de modèle d'e-mail — générer un aperçu PDF d'un modèle d'e-mail HTML avant l'envoi — est un pur scénario d'Approche 3. Le HTML du modèle 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 WaitFor. Pour le traitement par lots (par exemple, générer 500 PDF de factures), l'extraction côté serveur avec Parallel.ForEach et plusieurs instances ChromePdfRenderer offre le meilleur débit.

Debugging : Lorsque la sortie PDF est vide ou manque de contenu, activez EnableJavaScript = true et augmentez le délai 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'actifs relatifs à partir de l'URL de base, ce qui facilite la composition de documents à partir de sources hétérogènes.

Explorez le guide JavaScript to PDF pour 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 la surface complète ChromePdfRenderOptions, et l' exemple de code JavaScript personnalisé pour des extraits prêt à l'emploi.

Voir les options de licence à partir de 749 $. La référence de l'API ChromePdfRenderOptions et la référence de l'API WaitFor documentent chaque propriété et 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 18,332,619 | Version : 2026.4 vient de sortir
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.