Comment ajouter une table des matières en C# | IronPDF
wkhtmltopdf a été un outil largement utilisé pour convertir des documents HTML en PDF en utilisant Qt 4.8 + QtWebKit. Malgré sa popularité auprès des développeurs pour ses fonctionnalités en ligne de commande et sa licence gratuite, le projet présente aujourd'hui des risques de sécurité critiques qui ne peuvent plus être ignorés. Le dépôt GitHub a été archivé le 2 janvier 2023 ; la dernière version en amont est 0.12.6 du 11 juin 2020 ; et CVE-2022-35583 (CVSS 9.8, SSRF) reste non corrigé.
Ce guide fournit un chemin de migration complet de wkhtmltopdf vers IronPDF, avec des instructions étape par étape, des comparaisons de code et des exemples pratiques pour les développeurs professionnels .NET qui ont besoin d'éliminer ce risque de sécurité de leurs applications.
Avertissement de sécurité critique : CVE-2022-35583
wkhtmltopdf contient une faille de sécurité critique qui ne sera jamais corrigée :
| Problème | Détail | Statut |
|---|---|---|
| CVE-2022-35583 (SSRF, CWE-918) | CRITIQUE (CVSS 9.8) | NON CORRIGÉ — contesté par les mainteneurs |
| Dépôt GitHub archivé | Lecture seule | 2 janvier 2023 |
| Dernière version en amont | 0.12.6 | 11 juin 2020 |
| Moteur sous-jacent | Qt 4.8 + QtWebKit (Qt 4.8 EOL 2015) | OBSOLETE |
| Support de la grille CSS | None | Rupture |
| Support Flexbox | Partiel | Rupture |
| ES6+ JavaScript | Limité | Rupture |
Comment fonctionne l'attaque du SSRF
La vulnérabilité Server-Side Request Forgery permet aux attaquants d'accéder à des services internes, de voler des informations d'identification, de scanner votre réseau interne et d'exfiltrer des données sensibles par le biais d'un code HTML élaboré :
<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>
<iframe src="http://169.254.169.254/latest/meta-data/iam/security-credentials/"></iframe>
<img src="http://internal-database:5432/admin"/>
Lorsque wkhtmltopdf rend ce HTML, il récupère ces URL à partir du contexte réseau de votre serveur, en contournant les pare-feux et les contrôles de sécurité.
Bibliothèques Wrapper affectées
Chaque wrapper .NET intègre ou exécute le même binaire natif wkhtmltopdf, donc ils héritent tous de son exposition CVE indépendamment de l'activité du wrapper lui-même :
| Bibliothèque Wrapper | Dernier NuGet | Risque de sécurité |
|---|---|---|
| DinkToPdf | 1.0.8 (avril 2017) — abandonné | Hérite de CVE-2022-35583 |
| Rotativa.AspNetCore (fork par webgio) | 1.4.0 (novembre 2023) — wrapper mis à jour, binaire figé | Hérite de CVE-2022-35583 |
| TuesPechkin | 2.1.1 (janvier 2015) — abandonné | Hérite de CVE-2022-35583 |
Haukcode.WkHtmlToPdfDotNet (formerly WkHtmlToPdf-DotNet) |
1.5.95 (octobre 2024) — wrapper mis à jour, binaire figé | Hérite de CVE-2022-35583 |
| NReco.PdfGenerator | wrapper mis à jour, intègre wkhtmltopdf | Hérite de CVE-2022-35583 |
Si vous utilisez l'une de ces bibliothèques, votre application est exposée à CVE-2022-35583 sauf si vous assainissez tout l'entrée HTML.
IronPDF vs wkhtmltopdf : Comparaison des fonctionnalités
La compréhension des différences architecturales aide les décideurs techniques à évaluer l'investissement dans la migration :
| Fonction | wkhtmltopdf | IronPDF |
|---|---|---|
| Licence | LGPLv3 (Gratuit) | Commercial |
| Moteur de rendu | Qt 4.8 + QtWebKit (Qt 4.8 EOL 2015) | Moteur Chromium actuel |
| Vulnérabilités de sécurité | CVE-2022-35583 (CVSS 9.8) non corrigé, contesté | Aucun CVE critique signalé |
| Maintenance active | Dépôt GitHub archivé le 2 janvier 2023 ; dernière version juin 2020 | Mise à jour active avec des versions régulières |
| Soutien aux normes Web modernes | Limité (flexbox cassé, pas de grille CSS) | Prise en charge |
| Intégration et support | Limité aux forums communautaires | Documentation complète et assistance dédiée |
| CSS Grid | ❌ Non pris en charge | ✅ Pris en charge |
| Flexbox | ⚠ Cassé | ✅ Pris en charge |
| ES6+ JavaScript | ❌ Non pris en charge | ✅ Pris en charge |
| Async/Await | ❌ Non pris en charge | ✅ Pris en charge |
| Manipulation de PDF | ❌ Non pris en charge | ✅ Pris en charge |
| Signatures numériques | ❌ Non pris en charge | ✅ Pris en charge |
| Conformité PDF/A | ❌ Non pris en charge | ✅ Pris en charge |
Démarrage rapide : migration de wkhtmltopdf vers IronPDF
La migration peut commencer immédiatement grâce à ces étapes fondamentales.
Étape 1 : Supprimer les paquets et les binaires de wkhtmltopdf
Supprimez tous les paquets wrapper wkhtmltopdf :
# Remove wkhtmltopdf wrapper (whichever you're using)
dotnet remove package Haukcode.WkHtmlToPdfDotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator
# Remove wkhtmltopdf binary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
# Remove wkhtmltopdf wrapper (whichever you're using)
dotnet remove package Haukcode.WkHtmlToPdfDotNet
dotnet remove package DinkToPdf
dotnet remove package TuesPechkin
dotnet remove package Rotativa
dotnet remove package Rotativa.AspNetCore
dotnet remove package NReco.PdfGenerator
# Remove wkhtmltopdf binary from your deployment
# Delete wkhtmltopdf.exe, wkhtmltox.dll, etc.
Étape 2 : Installer IronPDF
# Add IronPDF(secure, modern alternative)
dotnet add package IronPdf
# Add IronPDF(secure, modern alternative)
dotnet add package IronPdf
Étape 3 : Mise à jour des espaces de noms
Remplacez les espaces de noms wkhtmltopdf par l'espace de nom IronPDF:
// Before (wkhtmltopdf)
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
// After (IronPDF)
using IronPdf;
// Before (wkhtmltopdf)
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
// After (IronPDF)
using IronPdf;
Imports IronPdf
Étape 4 : initialisation de la licence
Ajouter l'initialisation de la licence au démarrage de l'application :
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
Exemples de migration de code
Conversion de HTML en PDF
L'opération la plus fondamentale révèle la différence de complexité entre ces approches PDF .NET.
wkhtmltopdf Approche:
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4
},
Objects = {
new ObjectSettings()
{
HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4
},
Objects = {
new ObjectSettings()
{
HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("output.pdf", pdf);
}
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.WkHtmlToPdfDotNet.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter As New SynchronizedConverter(New PdfTools())
Dim doc As New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Portrait,
.PaperSize = PaperKind.A4
},
.Objects = New List(Of ObjectSettings) From {
New ObjectSettings() With {
.HtmlContent = "<h1>Hello World</h1><p>This is a PDF from HTML.</p>"
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("output.pdf", pdf)
End Sub
End Module
Approche IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>");
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a PDF from HTML.</p>")
pdf.SaveAs("output.pdf")
End Sub
End Class
wkhtmltopdf nécessite de créer un SynchronizedConverter avec PdfTools, de construire un HtmlToPdfDocument avec GlobalSettings et Objects, de définir des propriétés comme ColorMode, Orientation et PaperSize, d'appeler converter.Convert() pour obtenir des octets bruts, et d'écrire manuellement dans un fichier avec File.WriteAllBytes().
IronPDF élimine entièrement ce cérémonial—créez un ChromePdfRenderer, appelez RenderHtmlAsPdf(), et utilisez la méthode intégrée SaveAs().
Pour les scénarios avancés de conversion de HTML en PDF, voir le guide de conversion de HTML en PDF.
Conversion des URL en PDF
La conversion d'URL en PDF présente des schémas de complexité similaires.
wkhtmltopdf Approche:
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4
},
Objects = {
new ObjectSettings()
{
Page = "https://www.example.com"
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("webpage.pdf", pdf);
}
}
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Portrait,
PaperSize = PaperKind.A4
},
Objects = {
new ObjectSettings()
{
Page = "https://www.example.com"
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("webpage.pdf", pdf);
}
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.WkHtmlToPdfDotNet.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter As New SynchronizedConverter(New PdfTools())
Dim doc As New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Portrait,
.PaperSize = PaperKind.A4
},
.Objects = New List(Of ObjectSettings) From {
New ObjectSettings() With {
.Page = "https://www.example.com"
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("webpage.pdf", pdf)
End Sub
End Module
Approche IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
}
}
Imports IronPdf
Imports System
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Class
wkhtmltopdf utilise la propriété Page dans ObjectSettings pour spécifier une URL, nécessitant le même modèle de construction de document.IronPDF fournit une méthode dédiée RenderUrlAsPdf() qui exprime clairement l'intention.
Explorez la URL vers la documentation PDF pour l'authentification et les options d'en-tête personnalisées.
Paramètres personnalisés : Fichiers HTML avec configuration de la page
La configuration de l'orientation, des marges et de la taille du papier nécessite différentes approches.
wkhtmltopdf Approche:
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.A4,
Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
},
Objects = {
new ObjectSettings()
{
Page = "input.html",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("custom-output.pdf", pdf);
}
}
// NuGet: Install-Package Haukcode.WkHtmlToPdfDotNet
using Haukcode.WkHtmlToPdfDotNet;
using Haukcode.WkHtmlToPdfDotNet.Contracts;
using System.IO;
class Program
{
static void Main()
{
var converter = new SynchronizedConverter(new PdfTools());
var doc = new HtmlToPdfDocument()
{
GlobalSettings = {
ColorMode = ColorMode.Color,
Orientation = Orientation.Landscape,
PaperSize = PaperKind.A4,
Margins = new MarginSettings() { Top = 10, Bottom = 10, Left = 10, Right = 10 }
},
Objects = {
new ObjectSettings()
{
Page = "input.html",
WebSettings = { DefaultEncoding = "utf-8" }
}
}
};
byte[] pdf = converter.Convert(doc);
File.WriteAllBytes("custom-output.pdf", pdf);
}
}
Imports Haukcode.WkHtmlToPdfDotNet
Imports Haukcode.WkHtmlToPdfDotNet.Contracts
Imports System.IO
Module Program
Sub Main()
Dim converter = New SynchronizedConverter(New PdfTools())
Dim doc = New HtmlToPdfDocument() With {
.GlobalSettings = New GlobalSettings() With {
.ColorMode = ColorMode.Color,
.Orientation = Orientation.Landscape,
.PaperSize = PaperKind.A4,
.Margins = New MarginSettings() With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
},
.Objects = {
New ObjectSettings() With {
.Page = "input.html",
.WebSettings = New WebSettings() With {.DefaultEncoding = "utf-8"}
}
}
}
Dim pdf As Byte() = converter.Convert(doc)
File.WriteAllBytes("custom-output.pdf", pdf)
End Sub
End Module
Approche IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
var pdf = renderer.RenderHtmlFileAsPdf("input.html");
pdf.SaveAs("custom-output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
using System;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
var pdf = renderer.RenderHtmlFileAsPdf("input.html");
pdf.SaveAs("custom-output.pdf");
}
}
Imports IronPdf
Imports IronPdf.Rendering
Imports System
Class Program
Shared Sub Main()
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
renderer.RenderingOptions.MarginTop = 10
renderer.RenderingOptions.MarginBottom = 10
renderer.RenderingOptions.MarginLeft = 10
renderer.RenderingOptions.MarginRight = 10
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
Dim pdf = renderer.RenderHtmlFileAsPdf("input.html")
pdf.SaveAs("custom-output.pdf")
End Sub
End Class
wkhtmltopdf imbrique les paramètres à l'intérieur de GlobalSettings et Objects, avec MarginSettings comme un objet distinct.IronPDF fournit des propriétés RenderingOptions directes avec des noms clairs tels que PaperOrientation, MarginTop et PaperSize.
wkhtmltopdf API to IronPDF Mapping Reference (Référence de mappage de l'API vers IronPDF)
Cette cartographie accélère la migration en indiquant les équivalents directs des API :
CLI to IronPDF Mapping (en anglais)
| option CLI de wkhtmltopdf | Équivalent d'IronPDF |
|---|---|
wkhtmltopdf input.html output.pdf |
renderer.RenderHtmlFileAsPdf() |
wkhtmltopdf URL output.pdf |
renderer.RenderUrlAsPdf() |
--page-size A4 |
RenderingOptions.PaperSize = PdfPaperSize.A4 |
--page-size Letter |
RenderingOptions.PaperSize = PdfPaperSize.Letter |
--orientation Landscape |
RenderingOptions.PaperOrientation = Landscape |
--margin-top 10mm |
RenderingOptions.MarginTop = 10 |
--margin-bottom 10mm |
RenderingOptions.MarginBottom = 10 |
--margin-left 10mm |
RenderingOptions.MarginLeft = 10 |
--margin-right 10mm |
RenderingOptions.MarginRight = 10 |
--header-html header.html |
RenderingOptions.HtmlHeader |
--footer-center "[page]" |
{page} placeholder |
--footer-center "[toPage]" |
{total-pages} placeholder |
--enable-javascript |
Activé par défaut |
--javascript-delay 500 |
RenderingOptions.WaitFor.RenderDelay = 500 |
--dpi 300 |
RenderingOptions.Dpi = 300 |
--grayscale |
RenderingOptions.GrayScale = true |
Correspondance de l'API Wrapper C
| wkhtmltopdf Wrapper | IronPDF |
|---|---|
SynchronizedConverter |
ChromePdfRenderer |
HtmlToPdfDocument |
RenderingOptions |
GlobalSettings.Out |
pdf.SaveAs() |
GlobalSettings.PaperSize |
RenderingOptions.PaperSize |
GlobalSettings.Orientation |
RenderingOptions.PaperOrientation |
GlobalSettings.Margins |
RenderingOptions.Margin* |
ObjectSettings.Page |
RenderHtmlFileAsPdf() |
ObjectSettings.HtmlContent |
RenderHtmlAsPdf() |
converter.Convert(doc) |
renderer.RenderHtmlAsPdf() |
Migration de la syntaxe des espaces réservés
| wkhtmltopdf Placeholder | IronPDF Placeholder |
|---|---|
[page] |
{page} |
[toPage] |
{total-pages} |
[date] |
{date} |
[time] |
{time} |
[title] |
{html-title} |
[url] |
{url} |
Problèmes de migration courants et solutions
Enjeu 1 : Syntaxe de l'en-tête/du pied de page
wkhtmltopdf : Utilise une syntaxe de crochets carrés comme [page] et [toPage].
Solution: Mise à jour des caractères de remplacement des accolades d'IronPDF :
// Before (wkhtmltopdf)
FooterSettings = { Left = "Page [page] of [toPage]" }
// After (IronPDF)
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
MaxHeight = 25
};
// Before (wkhtmltopdf)
FooterSettings = { Left = "Page [page] of [toPage]" }
// After (IronPDF)
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
MaxHeight = 25
};
' Before (wkhtmltopdf)
FooterSettings = New With {.Left = "Page [page] of [toPage]"}
' After (IronPDF)
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
.HtmlFragment = "<div style='text-align:left;'>Page {page} of {total-pages}</div>",
.MaxHeight = 25
}
Edition 2 : Configuration du délai JavaScript
wkhtmltopdf : Utilise la propriété JavaScriptDelay avec une fiabilité limitée.
Solution:IronPDF propose plusieurs options :
renderer.RenderingOptions.EnableJavaScript = true;
// Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500);
// Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");
// Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true");
renderer.RenderingOptions.EnableJavaScript = true;
// Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500);
// Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded");
// Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true");
renderer.RenderingOptions.EnableJavaScript = True
' Option 1: Fixed delay
renderer.RenderingOptions.WaitFor.RenderDelay(500)
' Option 2: Wait for specific element (more reliable)
renderer.RenderingOptions.WaitFor.HtmlElementById("content-loaded")
' Option 3: Wait for JavaScript condition
renderer.RenderingOptions.WaitFor.JavaScript("window.renderComplete === true")
Édition 3 : CSS moderne sans rendu
Symptôme: Les mises en page CSS Grid et Flexbox s'affichent de manière incorrecte dans wkhtmltopdf.
Solution:Le moteur Chromium d'IronPDF gère correctement les feuilles de style CSS modernes :
// This CSS now works with IronPDF
var html = @"
<style>
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
// This CSS now works with IronPDF
var html = @"
<style>
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>";
var pdf = renderer.RenderHtmlAsPdf(html);
Dim html As String = "
<style>
.grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.flex { display: flex; justify-content: space-between; align-items: center; }
</style>
<div class='grid'>
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
Edition 4 : Rendu synchrone ou asynchrone
wkhtmltopdf: Les wrappers sont synchrones et bloquent les threads.
Solution:IronPDF prend en charge le rendu asynchrone :
public async Task<byte[]> GeneratePdfAsync(string html)
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
Imports System.Threading.Tasks
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Dim renderer As New ChromePdfRenderer()
Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Function
wkhtmltopdf Liste de contrôle pour la migration
Tâches préalables à la migration
Auditez votre base de code pour identifier toute utilisation de wkhtmltopdf :
# Find all wkhtmltopdf references
grep -r "Haukcode.WkHtmlToPdfDotNet\|WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa\|NReco.PdfGenerator" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
# Find all wkhtmltopdf references
grep -r "Haukcode.WkHtmlToPdfDotNet\|WkHtmlToPdfDotNet\|DinkToPdf\|TuesPechkin\|Rotativa\|NReco.PdfGenerator" --include="*.cs" .
grep -r "wkhtmltopdf" --include="*.yml" --include="*.yaml" --include="Dockerfile" .
Localiser et documenter les fichiers binaires wkhtmltopdf pour les supprimer. Documenter les paramètres actuels (taille du papier, marges, en-têtes/pieds de page).
Tâches de mise à jour du code
- Supprimer tous les paquets NuGet de wrapper wkhtmltopdf
- Supprimer les binaires de wkhtmltopdf (wkhtmltopdf.exe, wkhtmltox.dll)
- Installez le package NuGet IronPDF
- Mettez à jour les imports de namespace de
Haukcode.WkHtmlToPdfDotNet(ou de l'encapsuleur que vous avez utilisé) àIronPdf - Remplacez
SynchronizedConverterparChromePdfRenderer - Convertissez les modèles
HtmlToPdfDocumenten méthodes de rendu direct - Mettez à jour les configurations
GlobalSettingsversRenderingOptions - Convertissez les configurations de marge de
MarginSettingsvers des propriétés individuelles - Mettez à jour la syntaxe des placeholders (
[page]→{page},[toPage]→{total-pages}) - Ajouter l'initialisation de la licence IronPDF au démarrage
Test de post-migration
Après la migration, vérifiez ces aspects :
- Comparaison visuelle de la sortie PDF (devrait s'améliorer avec un support CSS moderne)
- Vérifier le rendu CSS moderne (CSS Grid et Flexbox fonctionnent désormais)
- Tester les pages à forte teneur en JavaScript
- Analyse de sécurité pour confirmer qu'il ne reste plus de binaires wkhtmltopdf
- Test de charge pour la comparaison des performances
Vérification de sécurité
# Scan for any remaining wkhtmltopdf artifacts
find /var/www/ -name "*wkhtmlto*" 2>/dev/null
find /usr/local/bin/ -name "*wkhtmlto*" 2>/dev/null
docker images | grep wkhtmltopdf
# Check if any process is still using it
ps aux | grep wkhtmltopdf
# Scan for any remaining wkhtmltopdf artifacts
find /var/www/ -name "*wkhtmlto*" 2>/dev/null
find /usr/local/bin/ -name "*wkhtmlto*" 2>/dev/null
docker images | grep wkhtmltopdf
# Check if any process is still using it
ps aux | grep wkhtmltopdf
Avantages clés de la migration vers IronPDF
Le passage de wkhtmltopdf à IronPDF présente plusieurs avantages décisifs :
Sécurité : La vulnérabilité CVE-2022-35583 et toutes les vulnérabilités wkhtmltopdf ont été éliminées.IronPDF n'a pas de CVE connu et reçoit régulièrement des mises à jour de sécurité.
Moteur de rendu moderne :IronPDF utilise le moteur Chromium actuel, garantissant une prise en charge complète de CSS3, CSS Grid, Flexbox et JavaScript ES6+. Les frameworks modernes sont correctement restitués.
API simplifiée : les méthodes de rendu direct remplacent les modèles de construction de documents. Les méthodes intégrées SaveAs() éliminent la gestion manuelle des octets.
Fonctionnalités étendues : la manipulation de fichiers PDF, les signatures numériques, la conformité PDF/A, les filigranes et les opérations de fusion/séparation sont des fonctionnalités intégrées que wkhtmltopdf ne pouvait pas fournir.
Développement actif : les mises à jour régulières d'IronPDF suivent les versions .NET actuelles, de sorte que les versions modernes de .NET et du langage C# sont prises en charge dès leur sortie.
Prise en charge asynchrone : évitez le blocage des threads dans les applications Web à forte charge grâce à la prise en charge native d'async/await.

