
IronPDF vs EvoPdf : Quelle bibliothèque PDF .NET Offre la Meilleure Valeur en 2026 ?
Lors de la création d'applications .NET modernes nécessitant des fonctionnalités PDF, le choix de la bonne bibliothèque peut avoir un impact significatif sur la rapidité de développement, les performances de l’application et les coûts de maintenance à long terme. IronPDF et EvoPdf représentent deux approches distinctes de la génération et de la manipulation de PDF dans l’écosystème .NET, chacune avec des atouts uniques adaptés à différents scénarios de développement.
Cette comparaison examine les deux bibliothèques selon des critères essentiels tels que la précision du rendu, la conception de l’API, les considérations de performance, la compatibilité multiplateforme et le coût total de possession. Que vous construisiez un système de traitement de documents à haut volume, signiez des documents ou convertissiez simplement des rapports HTML en PDF, comprendre ces différences vous aidera à prendre une décision éclairée, alignée sur vos exigences techniques et vos contraintes budgétaires.
Comment IronPDF et EvoPdf se comparent-ils en un coup d’œil ?
Avant d’entrer dans les détails, voici un aperçu de la comparaison de ces bibliothèques selon les catégories clés qui comptent le plus pour les développeurs .NET :
| Catégorie | Fonctionnalité/Aspect | IronPDF | EvoPdf | Avantage clé |
|---|---|---|---|---|
| Architecture de base | Philosophie de conception | Simplicité avant tout, APIs intuitives | Contrôle granulaire des paramètres de conversion | Dépend des préférences de l’équipe |
| Complexité de l’API | Méthodes simples comme RenderHtmlAsPdf() | Classe Converter avec des méthodes comme ConvertHtml() | Les deux : conversion en un seul appel | |
| Compatibilité multiplateforme | Multiplateforme | Windows, Linux, macOS via des packages NuGet spécifiques à la plateforme | EvoPdf Next : Windows, Linux, macOS via des packages NuGet par plateforme ; EvoPdf Classic : Windows, plus un client multiplateforme qui appelle un serveur EVO PDF hébergé séparément | Les deux : rendu local multiplateforme (EvoPdf Next) |
| Versions .NET | .NET 10, 9, 8, 7, 6, 5, Core 3.1+, Standard 2.0, Framework 4.6.2+ | Next : .NET 10, 9, 8, 7, 6, Standard 2.0, Framework 4.6.2+ ; Classic : Framework 2.0+ | Les deux : prise en charge des frameworks modernes | |
| Systèmes d’exploitation | Windows, Linux, macOS, Docker, Azure, AWS | Windows, Linux, macOS, Docker, Azure (EvoPdf Next) | Les deux : support Docker et cloud | |
| HTML vers PDF | Moteur de rendu | Chromium (CEF 109 dans le package standard ; CEF 131 dans IronPdf.UpdatedChrome) | Chromium 142 (EvoPdf Next) ; moteur EVO propriétaire (EvoPdf Classic) | Les deux : basé sur Chromium |
| Support CSS3/HTML5 | Dépend de la version de Chromium embarquée : sous Windows, 109 dans le package standard et 131 dans IronPdf.UpdatedChrome (par ex. Tailwind CSS v4 nécessite Chrome 111 ou supérieur) | Next : flexbox, grid, ES2015+, polices web | Les deux : dépend de la version du moteur | |
| Exécution JavaScript | Support JavaScript avec délai de rendu | Support JavaScript avec délai de conversion | Les deux : contenu dynamique | |
| Sécurité & chiffrement | Niveaux de chiffrement | RC4-128, AES-128, AES-256 | RC4-40, RC4-128, AES-128, AES-256 | Les deux : AES-256 disponible |
| Options d’autorisations | Contrôles d’autorisations granulaires | Autorisations granulaires (impression, copie, édition, annotation, remplissage de formulaires, assemblage) | Les deux : contrôle granulaire | |
| Signatures numériques | Signatures intégrées, visuelles | Signatures visibles avec image et horodatage | Les deux : signatures visuelles | |
| Manipulation du contenu | Méthode de rédaction | Suppression réelle du contenu, API en une ligne | Aucune fonctionnalité de rédaction documentée | IronPDF : rédaction intégrée |
| Filigranage | Basé sur HTML/CSS, style complet | Modèles HTML pour filigranes et tampons | Les deux : basé sur HTML | |
| Tamponnage | Classes de tamponneurs unifiées | Tampons HTML via modèles | IronPDF : classes de tamponneurs dédiées | |
| Conversions de fichiers | DOCX vers PDF | Intégré DocxToPdfRenderer | Inclus dans EVO PDF Toolkit (depuis $650), non inclus dans la licence HTML vers PDF | IronPDF : inclus dans la licence de base |
| Expérience développeur | Exemples de code | 100+ exemples prêts à l’emploi | Exemples de code sur GitHub, démo en ligne | IronPDF : ressources étendues |
| Documentation | Tutoriels, guides pratiques, vidéos, référence API | Documentation, référence API, FAQ support | IronPDF : multiples parcours d’apprentissage | |
| Performance | Concurrence | Méthodes de rendu asynchrones | Méthodes asynchrones (EvoPdf Next) ; moteur persistant pour conversions parallèles | Les deux : charges de travail concurrentes |
| Licence & tarification | Niveau d’entrée | Lite : $999 (1 dev, 1 projet) | Déploiement : $450 (1 application sur 1 serveur, développeurs illimités, pas de redistribution) | EvoPdf : coût initial plus bas |
| Licence équipe | Plus : $1,499 (3 devs, 3 projets) | Aucun niveau ne compte les développeurs ; Entreprise : $1,200 (applications et serveurs illimités) | EvoPdf : prix indépendant de la taille de l’équipe | |
| Redistribution | +$1,999 sans redevance (OEM/SaaS) ; une API publique exposant IronPDF nécessite une licence SDK | Licence Entreprise uniquement ; pas en tant que service de conversion autonome ou SDK | EvoPdf : inclus dans la licence Entreprise | |
| Option suite | Iron Suite Lite : $2,998 (10 produits ; 1 développeur, 1 site, 1 projet) | EVO PDF Toolkit Entreprise : $1,400 | Périmètre différent : Iron Suite ajoute OCR, code-barres et outils Office | |
| Support | Support inclus | Oui : chat en direct 24/5 ; support 24/7 avec Support Premium (inclus pendant l’essai) | Oui, première année (standard ou prioritaire, selon la licence) | Les deux : support inclus |
| Idéal pour | Cas d’usage | Applications web modernes, PDF complexes, rédaction | HTML, Word et Excel vers PDF avec licence entreprise | Dépend du contexte |
Remarque. EvoPdf propose des tarifs compétitifs pour les grandes équipes. IronPDF inclut la rédaction intégrée et la conversion DOCX vers PDF dans sa licence de base.
Comprendre IronPDF et EvoPdf : forces et philosophie de base
Qu’est-ce qui distingue IronPDF sur le marché des bibliothèques PDF .NET ?
IronPDF est une bibliothèque PDF .NET conçue pour maximiser la productivité des développeurs. Construite sur une base de simplicité sans sacrifier la puissance, IronPDF permet aux développeurs .NET de créer, éditer et manipuler des documents PDF via des APIs intuitives qui reprennent les schémas familiers du développement web. La fonctionnalité phare de la bibliothèque est son moteur de rendu basé sur Chromium, qui exécute JavaScript et charge les polices web ; la prise en charge du CSS moderne dépend de la version de Chromium que vous déployez. Le package standard IronPdf embarque Chromium 109 pour la compatibilité avec les anciens serveurs Windows ; le package Windows-only IronPdf.UpdatedChrome embarque Chromium 131 et gère correctement les nouvelles fonctionnalités CSS telles que subgrid, mais il ne prend pas en charge les processus 32 bits, Windows Server 2012 ou le mode SingleProcess, donc les deux packages ne sont pas interchangeables sur toutes les cibles.
La bibliothèque vise les applications qui rendent des documents HTML, manipulent des PDF existants et protègent les documents par chiffrement, signatures et rédaction. Son ensemble de fonctionnalités étendu inclut non seulement la génération PDF de base, mais aussi des capacités avancées comme les signatures numériques, le remplissage de formulaires, l’intégration OCR via IronOCR, et les conversions de formats de documents tels que DOCX vers PDF. La compatibilité multiplateforme d’IronPDF va au-delà du simple support de framework, fonctionnant sous Windows, Linux, macOS, dans des conteneurs Docker et sur des plateformes cloud comme Azure et AWS.
En quoi l’approche d’EvoPdf pour la génération de PDF est-elle différente ?
EvoPdf se concentre sur la conversion HTML vers PDF avec un accent sur la personnalisation et le contrôle. La bibliothèque offre aux développeurs un contrôle granulaire sur le processus de conversion, permettant d’affiner les paramètres de rendu, la mise en page et les options de conversion. EvoPdf est disponible en deux éditions : EvoPdf Next, qui utilise un moteur de rendu basé sur Chromium (Chromium 142, selon EVO PDF) et fonctionne sous Windows, Linux et macOS, et EvoPdf Classic, qui utilise le moteur de rendu propriétaire d’EVO et fonctionne sous Windows. L’EVO PDF Toolkit ajoute la conversion Word, Excel, RTF et Markdown vers PDF ainsi que des composants de traitement PDF.
Un point fort notable d’EvoPdf est sa licence : aucun niveau de licence ne compte les développeurs, et la licence Entreprise couvre un nombre illimité d’applications et de serveurs et inclut la redistribution dans vos propres applications. Pour les charges serveur à haut volume, EvoPdf Next documente un mode de moteur persistant qui maintient le moteur de rendu actif entre les conversions. La bibliothèque prend également en charge les scénarios ASP.NET tels que la conversion de pages nécessitant des cookies d’authentification.
Comment les capacités multiplateformes des bibliothèques se comparent-elles ?
Architecture multiplateforme moderne d’IronPDF
IronPDF fonctionne sur plusieurs versions de .NET, systèmes d’exploitation et plateformes cloud :
- Support des versions .NET :
- .NET 10, 9, 8, 7, 6, 5 et Core 3.1+
- .NET Standard 2.0+
- .NET Framework 4.6.2+
- Prise en charge complète de C#, VB.NET et F#
- Compatibilité système d’exploitation :
- Windows (x64 ; x86 uniquement avec le package standard, car IronPdf.UpdatedChrome ne prend pas en charge les processus 32 bits)
- Linux (Ubuntu, Debian, CentOS ; Alpine via le conteneur IronPdfEngine)
- macOS (Intel et Apple Silicon)
- Conteneurs Docker avec images préconfigurées
- Intégration cloud :
- Azure App Service, Functions et VMs
- AWS Lambda et EC2
- Déploiements Kubernetes
IronPDF fournit ses binaires Chromium dans des packages NuGet spécifiques à la plateforme (IronPdf pour Windows, IronPdf.Linux, IronPdf.MacOs et IronPdf.MacOs.ARM). Sous Linux, IronPDF tente d’installer automatiquement les dépendances système manquantes par défaut ; cela nécessite des droits sudo, sinon les dépendances sont installées manuellement. Cela réduit les étapes de déploiement pour la plupart des environnements.
Support des plateformes par EvoPdf
EvoPdf prend en charge une gamme similaire de versions .NET, avec une compatibilité plateforme qui dépend de l’édition :
- Support du Framework .NET :
- EvoPdf Next : .NET 10, 9, 8, 7 et 6, .NET Standard 2.0, .NET Framework 4.6.2 à 4.8.1
- EvoPdf Classic : .NET 10 à 6, .NET Standard 2.0, .NET Framework 2.0 et supérieur
- Considérations plateforme :
- EvoPdf Next : Windows (x64, ARM64), Linux (x64, ARM64) et macOS (ARM64), avec un package NuGet par plateforme
- EvoPdf Next fonctionne dans Azure App Service, Azure Functions et Docker ; le moteur de rendu est hébergé dans le processus de l’application, sans navigateur à installer
- EvoPdf Classic : rendu local uniquement sous Windows
- Client EvoPdf Classic : fonctionne sous Windows, Linux et macOS et envoie les conversions à un serveur EVO PDF installé séparément (installé comme service cloud Azure, application IIS ou service Windows)
EvoPdf Next fournit un rendu local natif sous Windows, Linux et macOS. Une application basée sur EvoPdf Classic qui doit fonctionner sous Linux ou macOS peut soit migrer vers EvoPdf Next (EVO PDF publie un guide de migration Classic vers Next), soit conserver le rendu Classic sur un serveur EVO PDF séparé et l’appeler via la bibliothèque cliente.
Quelle bibliothèque offre la meilleure fonctionnalité PDF pour les tâches courantes ?
Chaque exemple de code de cet article est un programme console .NET 8 complet : créez un projet avec dotnet new console, ajoutez le package NuGet nommé dans le premier commentaire de l’exemple, et remplacez Program.cs par l’exemple. Les exemples déclarent leurs propres directives using, ils compilent donc avec ou sans usings implicites. Ils ont été compilés et exécutés avec IronPdf 2026.9.2, EvoPdf.HtmlToPdf 14.0.2 et EvoPdf.PdfSecurity 14.0.2. IronPDF nécessite une clé de licence, telle qu’une clé d’essai gratuite, à définir via IronPdf.License.LicenseKey ou une entrée IronPdf.LicenseKey dans appsettings.json. EvoPdf fonctionne sans clé et ajoute un filigrane d’évaluation à la sortie.
Conversion HTML vers PDF : qualité de rendu et performance
La fonctionnalité la plus fondamentale des deux bibliothèques est la conversion HTML vers PDF, et leurs APIs adoptent des approches différentes.
Exemple HTML vers PDF avec IronPDF
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using IronPdf.Rendering;
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
EnableJavaScript = true,
// Page margins in millimetres
MarginTop = 20,
MarginBottom = 20,
MarginLeft = 15,
MarginRight = 15,
CssMediaType = PdfCssMediaType.Print,
ViewPortWidth = 1920,
FitToPaperMode = FitToPaperModes.Automatic
}
};
// Render only after the page calls window.ironpdf.notifyRender(), or after 10 seconds at most
renderer.RenderingOptions.WaitFor.JavaScript(10000);
// The page loads Chart.js and a Google Font from their CDNs, so the renderer needs network access
var htmlContent = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'>
<style>
body { font-family: 'Roboto', sans-serif; }
.chart-container { width: 100%; height: 400px; }
@media print {
.no-print { display: none; }
}
</style>
<script src='https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js'></script>
</head>
<body>
<h1>Dynamic Sales Report</h1>
<div class='chart-container'>
<canvas id='salesChart'></canvas>
</div>
<script>
new Chart(document.getElementById('salesChart'), {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales 2025',
data: [65, 78, 90, 81, 96],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
},
// No animation, so the chart is fully drawn when the constructor returns
options: { animation: false }
});
window.ironpdf.notifyRender();
</script>
</body>
</html>";
using var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("sales-report.pdf");' NuGet: Install-Package IronPdf
Imports IronPdf
Imports IronPdf.Engines.Chrome
Imports IronPdf.Rendering
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.EnableJavaScript = True,
' Page margins in millimetres
.MarginTop = 20,
.MarginBottom = 20,
.MarginLeft = 15,
.MarginRight = 15,
.CssMediaType = PdfCssMediaType.Print,
.ViewPortWidth = 1920,
.FitToPaperMode = FitToPaperModes.Automatic
}
}
' Render only after the page calls window.ironpdf.notifyRender(), or after 10 seconds at most
renderer.RenderingOptions.WaitFor.JavaScript(10000)
' The page loads Chart.js and a Google Font from their CDNs, so the renderer needs network access
Dim htmlContent = "
<!DOCTYPE html>
<html>
<head>
<link href='https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap' rel='stylesheet'>
<style>
body { font-family: 'Roboto', sans-serif; }
.chart-container { width: 100%; height: 400px; }
@media print {
.no-print { display: none; }
}
</style>
<script src='https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js'></script>
</head>
<body>
<h1>Dynamic Sales Report</h1>
<div class='chart-container'>
<canvas id='salesChart'></canvas>
</div>
<script>
new Chart(document.getElementById('salesChart'), {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales 2025',
data: [65, 78, 90, 81, 96],
borderColor: 'rgb(75, 192, 192)',
tension: 0.4
}]
},
options: { animation: false }
});
window.ironpdf.notifyRender();
</script>
</body>
</html>"
Using pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("sales-report.pdf")
End UsingCet exemple IronPDF montre :
- Exécution JavaScript : Le JavaScript de la page (ici Chart.js) s’exécute avant le rendu
- Signal de rendu explicite :
WaitFor.JavaScript()attend que la page appellewindow.ironpdf.notifyRender()au lieu de deviner avec un délai fixe - Polices web : Les polices référencées par la page sont chargées et intégrées
- Media queries d’impression :
CssMediaType.Printapplique les règles@media printde la page
Exemple HTML vers PDF avec EvoPdf
// NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
using System.IO;
using EvoPdf;
HtmlToPdfConverter converter = new HtmlToPdfConverter();
// Production use needs a license key. Leave this line out to evaluate:
// the output then carries an evaluation watermark. An invalid key makes the conversion throw.
// converter.LicenseKey = "<your EvoPdf license key>";
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
converter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait;
// EvoPdf margins are in points (1/72 inch): 57 pt is about 20 mm, 43 pt about 15 mm,
// matching the IronPDF example above, whose margins are in millimetres
converter.PdfDocumentOptions.TopMargin = 57;
converter.PdfDocumentOptions.BottomMargin = 57;
converter.PdfDocumentOptions.LeftMargin = 43;
converter.PdfDocumentOptions.RightMargin = 43;
converter.JavaScriptEnabled = true;
converter.ConversionDelay = 2; // seconds
// For pages behind HTTP authentication, also set
// converter.AuthenticationOptions.Username and .Password
// Convert HTML string
string htmlString = @"
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; }
</style>
</head>
<body>
<h1>Invoice</h1>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr>
<td>Product A</td>
<td>5</td>
<td>$50.00</td>
</tr>
</table>
</body>
</html>";
// Perform conversion
byte[] pdfBytes = converter.ConvertHtml(htmlString, "");
// Save to file
File.WriteAllBytes("invoice.pdf", pdfBytes);' NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
Imports System.IO
Imports EvoPdf
Dim converter As New HtmlToPdfConverter()
' Production use needs a license key. Leave this line out to evaluate:
' the output then carries an evaluation watermark. An invalid key makes the conversion throw.
' converter.LicenseKey = "<your EvoPdf license key>"
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
converter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait
' EvoPdf margins are in points (1/72 inch): 57 pt is about 20 mm, 43 pt about 15 mm,
' matching the IronPDF example above, whose margins are in millimetres
converter.PdfDocumentOptions.TopMargin = 57
converter.PdfDocumentOptions.BottomMargin = 57
converter.PdfDocumentOptions.LeftMargin = 43
converter.PdfDocumentOptions.RightMargin = 43
converter.JavaScriptEnabled = True
converter.ConversionDelay = 2 ' seconds
' For pages behind HTTP authentication, also set
' converter.AuthenticationOptions.Username and .Password
' Convert HTML string
Dim htmlString As String = "
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; }
</style>
</head>
<body>
<h1>Invoice</h1>
<table>
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr>
<td>Product A</td>
<td>5</td>
<td>$50.00</td>
</tr>
</table>
</body>
</html>"
' Perform conversion
Dim pdfBytes() As Byte = converter.ConvertHtml(htmlString, "")
' Save to file
File.WriteAllBytes("invoice.pdf", pdfBytes)Le convertisseur EvoPdf suit un schéma configurer-puis-convertir : définissez les PdfDocumentOptions, puis appelez ConvertHtml() ou ConvertUrl(). Chaque exemple EvoPdf de cet article utilise l’API EvoPdf Classic (EvoPdf.HtmlToPdf), qui rend sous Windows. EvoPdf Next, l’édition basée sur Chromium, est une série distincte de packages NuGet avec sa propre API : par exemple, sa clé de licence se définit une fois par processus sur la propriété statique Licensing.LicenseKey. EVO documente le support dans Next pour flexbox, grid, JavaScript ES2015+ et polices web.
Sécurité et chiffrement PDF : protéger les documents sensibles
La sécurité est primordiale lors du traitement de documents sensibles. Les deux bibliothèques offrent la protection par mot de passe, le contrôle des autorisations et le chiffrement.
Implémentation avancée de la sécurité avec IronPDF
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Editing;
using IronPdf.Security;
using IronPdf.Signing;
using IronSoftware.Drawing;
using var pdf = PdfDocument.FromFile("confidential-report.pdf");
// Finish every content change before signing
pdf.ApplyWatermark("<h2 style='color:red; opacity:0.5;'>CONFIDENTIAL</h2>",
45, VerticalAlignment.Middle, HorizontalAlignment.Center);
// Descriptive document properties (these do not restrict access)
pdf.MetaData.Author = "Finance Team";
pdf.MetaData.Title = "Quarterly Report (Internal)";
pdf.MetaData.ModifiedDate = DateTime.UtcNow;
// Owner password: required to change the permissions below
pdf.SecuritySettings.OwnerPassword = "owner-password";
// User password: required to open the document
pdf.SecuritySettings.UserPassword = "user-password";
pdf.SecuritySettings.AllowUserCopyPasteContentForAccessibility = false;
pdf.SecuritySettings.AllowUserAnnotations = false;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserFormData = true;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.PrintLowQuality;
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256;
// Visible digital signature: image file, page index, and position/size on the page
var signature = new PdfSignature("certificate.pfx", "cert-password")
{
SigningReason = "Document Approval",
SigningLocation = "Head Office",
SigningContact = "security@example.com",
SignatureImage = new PdfSignatureImage("signature.png", 0, new Rectangle(100, 100, 200, 50))
};
pdf.Sign(signature);
// The signature is applied when the file is saved
pdf.SaveAs("secured-document.pdf");' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Imports IronPdf.Editing
Imports IronPdf.Security
Imports IronPdf.Signing
Imports IronSoftware.Drawing
Dim pdf = PdfDocument.FromFile("confidential-report.pdf")
' Finish every content change before signing
pdf.ApplyWatermark("<h2 style='color:red; opacity:0.5;'>CONFIDENTIAL</h2>", 45, VerticalAlignment.Middle, HorizontalAlignment.Center)
' Descriptive document properties (these do not restrict access)
pdf.MetaData.Author = "Finance Team"
pdf.MetaData.Title = "Quarterly Report (Internal)"
pdf.MetaData.ModifiedDate = DateTime.UtcNow
' Owner password: required to change the permissions below
pdf.SecuritySettings.OwnerPassword = "owner-password"
' User password: required to open the document
pdf.SecuritySettings.UserPassword = "user-password"
pdf.SecuritySettings.AllowUserCopyPasteContentForAccessibility = False
pdf.SecuritySettings.AllowUserAnnotations = False
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserFormData = True
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.PrintLowQuality
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256
' Visible digital signature: image file, page index, and position/size on the page
Dim signature = New PdfSignature("certificate.pfx", "cert-password") With {
.SigningReason = "Document Approval",
.SigningLocation = "Head Office",
.SigningContact = "security@example.com",
.SignatureImage = New PdfSignatureImage("signature.png", 0, New Rectangle(100, 100, 200, 50))
}
pdf.Sign(signature)
' The signature is applied when the file is saved
pdf.SaveAs("secured-document.pdf")Les fonctionnalités de sécurité d’IronPDF illustrées ici :
- Autorisations granulaires : Contrôle de la qualité d’impression, copie, annotations, remplissage de formulaires et modifications
- Signatures numériques visibles : Une signature avec motif, emplacement et image de signature
- Propriétés du document : Définir l’auteur, le titre et les dates (descriptif uniquement)
- Protection en couches : Combiner filigrane, chiffrement et signature sur un même document
Configuration de la sécurité avec EvoPdf
// NuGet: Install-Package EvoPdf.PdfSecurity
// (licensed with the EVO PDF Toolkit; not included in the standalone HTML to PDF license)
using EvoPdf.PdfSecurity;
PdfSecurityOptions securityOptions = new PdfSecurityOptions();
// Set basic security parameters
securityOptions.UserPassword = "user123";
securityOptions.OwnerPassword = "owner456";
securityOptions.EncryptionAlgorithm = EncryptionAlgorithm.AES;
securityOptions.KeySize = EncryptionKeySize.EncryptKey256Bit;
// Configure permissions
securityOptions.CanPrint = true;
securityOptions.CanCopyContent = false;
securityOptions.CanEditContent = false;
securityOptions.CanEditAnnotations = false;
securityOptions.CanFillFormFields = true;
securityOptions.CanAssembleDocument = false;
// Apply security to existing PDF
PdfSecurityManager securityManager = new PdfSecurityManager(securityOptions);
securityManager.SaveSecuredPdfToFile("input.pdf", "secured-output.pdf");' NuGet: Install-Package EvoPdf.PdfSecurity
' (licensed with the EVO PDF Toolkit; not included in the standalone HTML to PDF license)
Imports EvoPdf.PdfSecurity
Dim securityOptions As New PdfSecurityOptions()
' Set basic security parameters
securityOptions.UserPassword = "user123"
securityOptions.OwnerPassword = "owner456"
securityOptions.EncryptionAlgorithm = EncryptionAlgorithm.AES
securityOptions.KeySize = EncryptionKeySize.EncryptKey256Bit
' Configure permissions
securityOptions.CanPrint = True
securityOptions.CanCopyContent = False
securityOptions.CanEditContent = False
securityOptions.CanEditAnnotations = False
securityOptions.CanFillFormFields = True
securityOptions.CanAssembleDocument = False
' Apply security to existing PDF
Dim securityManager As New PdfSecurityManager(securityOptions)
securityManager.SaveSecuredPdfToFile("input.pdf", "secured-output.pdf")EvoPdf couvre les mêmes contrôles de base : mots de passe utilisateur et propriétaire, chiffrement, et autorisations pour impression, copie, édition, annotations, remplissage de formulaires et assemblage de documents. EVO documente l’algorithme (RC4 ou AES) et la taille de clé (40, 128 ou 256 bits) comme paramètres distincts ; lors de nos tests avec la version 14.0.2, RC4 avec clés 40 ou 128 bits et AES avec clés 128 ou 256 bits produisaient le chiffrement attendu, donc utilisez AES-128 ou AES-256 ; RC4 est un algorithme hérité. Avec la licence HTML vers PDF autonome, les PdfSecurityOptions du convertisseur appliquent la même protection lors de la génération du PDF, sans le composant PDF Security séparé.
Rédaction de contenu : suppression d’informations sensibles
Supprimer définitivement du texte sensible avant de partager un document est une exigence courante dans les applications traitant des données personnelles. La rédaction est un des éléments de cette tâche ; seule, elle ne rend pas une application conforme à des réglementations telles que le RGPD, HIPAA ou CCPA.
Exemple de rédaction avec IronPDF
// NuGet: Install-Package IronPdf
using IronPdf;
using IronSoftware.Drawing;
// This example expects a PDF with at least three pages
using var pdf = PdfDocument.FromFile("customer-records.pdf");
// 1. Redact a specific value on every page
pdf.RedactTextOnAllPages("123-45-6789");
// 2. Redact a word on specific pages (zero-based page indexes)
pdf.RedactTextOnPages(new[] { 0, 1, 2 }, "Confidential", CaseSensitive: false);
// 3. Redact a rectangular region on the first page
pdf.RedactRegionOnPage(0, new RectangleF(100, 200, 300, 50));
// 4. Replace a complete sensitive value with a label instead of drawing a black box
pdf.RedactTextOnAllPages("ACCT-0042-7781", DrawRectangles: false, ReplacementText: "[REDACTED]");
pdf.SaveAs("redacted-records.pdf");' NuGet: Install-Package IronPdf
Imports IronPdf
Imports IronSoftware.Drawing
' This example expects a PDF with at least three pages
Dim pdf = PdfDocument.FromFile("customer-records.pdf")
' 1. Redact a specific value on every page
pdf.RedactTextOnAllPages("123-45-6789")
' 2. Redact a word on specific pages (zero-based page indexes)
pdf.RedactTextOnPages(New Integer() {0, 1, 2}, "Confidential", CaseSensitive:=False)
' 3. Redact a rectangular region on the first page
pdf.RedactRegionOnPage(0, New RectangleF(100, 200, 300, 50))
' 4. Replace a complete sensitive value with a label instead of drawing a black box
pdf.RedactTextOnAllPages("ACCT-0042-7781", DrawRectangles:=False, ReplacementText:="[REDACTED]")
pdf.SaveAs("redacted-records.pdf")Les capacités de rédaction d’IronPDF incluent :
- Suppression du contenu : Le texte correspondant est supprimé du contenu de la page, il ne peut donc plus être extrait, et pas seulement masqué
- Options de correspondance : Sensible à la casse et correspondance sur mot entier
- Apparence de la rédaction : Dessiner des rectangles noirs ou insérer un texte de remplacement
- Rédaction sélective : Cibler des pages ou régions spécifiques
La rédaction de texte correspond au texte dans le contenu de la page. Le texte dans les images, comme une page scannée, n’est pas détecté ; une rédaction de région couvre une zone fixe quel que soit son contenu. EvoPdf ne documente pas de fonctionnalité de rédaction.
Gestion des formulaires : créer des PDF interactifs
Les deux bibliothèques prennent en charge les formulaires PDF, mais avec des approches différentes pour la création et la manipulation.
Exemple de formulaires avec IronPDF
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
// Create a new PDF with an HTML form
var html = @"
<html>
<body>
<h2>Employee Information Form</h2>
<form>
<label>Full Name:</label>
<input type='text' name='fullName' required />
<label>Email:</label>
<input type='email' name='email' required />
<label>Department:</label>
<select name='department'>
<option value=''>Select Department</option>
<option value='IT'>Information Technology</option>
<option value='HR'>Human Resources</option>
<option value='Sales'>Sales</option>
</select>
<label>Start Date:</label>
<input type='text' name='startDate' placeholder='YYYY-MM-DD' />
<label>
<input type='checkbox' name='agreement' />
I agree to the terms and conditions
</label>
<button type='submit'>Submit</button>
</form>
</body>
</html>";
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
CreatePdfFormsFromHtml = true // Enable form field creation
}
};
using var pdf = renderer.RenderHtmlAsPdf(html);
// Programmatically fill form fields
pdf.Form.FindFormField("fullName").Value = "John Doe";
pdf.Form.FindFormField("email").Value = "john.doe@example.com";
// A dropdown takes one of its displayed choices, not the HTML option value ("IT")
pdf.Form.FindFormField("department").Value = "Information Technology";
pdf.Form.FindFormField("startDate").Value = DateTime.Now.ToString("yyyy-MM-dd");
// "Yes" is the checkbox's checked state
pdf.Form.FindFormField("agreement").Value = "Yes";
// Make specific fields read-only
pdf.Form.FindFormField("email").ReadOnly = true;
// Save as fillable form
pdf.SaveAs("fillable-form.pdf");
// Or flatten the form (convert to static content)
pdf.Flatten();
pdf.SaveAs("completed-form.pdf");' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
' Create a new PDF with an HTML form
Dim html = "
<html>
<body>
<h2>Employee Information Form</h2>
<form>
<label>Full Name:</label>
<input type='text' name='fullName' required />
<label>Email:</label>
<input type='email' name='email' required />
<label>Department:</label>
<select name='department'>
<option value=''>Select Department</option>
<option value='IT'>Information Technology</option>
<option value='HR'>Human Resources</option>
<option value='Sales'>Sales</option>
</select>
<label>Start Date:</label>
<input type='text' name='startDate' placeholder='YYYY-MM-DD' />
<label>
<input type='checkbox' name='agreement' />
I agree to the terms and conditions
</label>
<button type='submit'>Submit</button>
</form>
</body>
</html>"
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.CreatePdfFormsFromHtml = True ' Enable form field creation
}
}
Using pdf = renderer.RenderHtmlAsPdf(html)
' Programmatically fill form fields
pdf.Form.FindFormField("fullName").Value = "John Doe"
pdf.Form.FindFormField("email").Value = "john.doe@example.com"
' A dropdown takes one of its displayed choices, not the HTML option value ("IT")
pdf.Form.FindFormField("department").Value = "Information Technology"
pdf.Form.FindFormField("startDate").Value = DateTime.Now.ToString("yyyy-MM-dd")
' "Yes" is the checkbox's checked state
pdf.Form.FindFormField("agreement").Value = "Yes"
' Make specific fields read-only
pdf.Form.FindFormField("email").ReadOnly = True
' Save as fillable form
pdf.SaveAs("fillable-form.pdf")
' Or flatten the form (convert to static content)
pdf.Flatten()
pdf.SaveAs("completed-form.pdf")
End UsingFonctionnalités de gestion des formulaires d’IronPDF :
- Génération automatique de formulaires : Convertit les formulaires HTML en formulaires PDF
- Manipulation programmatique : Remplir, lire et modifier les champs de formulaire via l’API
- Types de champs : Les champs texte (y compris email, nombre et téléphone) et les zones de texte deviennent des champs texte ; les cases à cocher, boutons radio et listes déroulantes conservent leur type. Les champs date HTML ne sont pas convertis en champs de formulaire, c’est pourquoi la date de début ci-dessus utilise un champ texte.
- Propriétés des champs : Définir les valeurs et les indicateurs lecture seule
- Aplatissement du formulaire : Convertir les formulaires remplis en PDF statiques
Considérations de performance
Les caractéristiques de performance varient fortement selon la complexité du document et le cas d’usage :
Chronométrer un lot de documents
// NuGet: Install-Package IronPdf
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using IronPdf;
// Timing harness for a batch of documents. Replace the generated HTML with your own templates.
const int documentCount = 100;
const int maxConcurrency = 4;
var htmlDocuments = Enumerable.Range(1, documentCount)
.Select(i => $"<html><body><h1>Invoice {i}</h1><p>Amount due: {i * 10} USD</p></body></html>")
.ToList();
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
EnableJavaScript = false // static content only
}
};
// Cap how many renders run at once instead of starting every render immediately
using var gate = new SemaphoreSlim(maxConcurrency);
var stopwatch = Stopwatch.StartNew();
var tasks = htmlDocuments.Select(async (html, index) =>
{
await gate.WaitAsync();
try
{
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
pdf.SaveAs($"invoice-{index + 1}.pdf");
}
finally
{
gate.Release();
}
});
await Task.WhenAll(tasks);
stopwatch.Stop();
Console.WriteLine($"Documents: {documentCount}, at most {maxConcurrency} at a time");
Console.WriteLine($"Total elapsed: {stopwatch.ElapsedMilliseconds} ms");
// Elapsed time divided by the document count: an amortized figure, not the latency of one request
Console.WriteLine($"Amortized time per document: {stopwatch.ElapsedMilliseconds / (double)documentCount:F1} ms");
// Resident memory of this process only, sampled once at the end; the Chromium helper
// processes are not included, and this is not the peak
Console.WriteLine($"Working set of this process at end: {Process.GetCurrentProcess().WorkingSet64 / 1024 / 1024} MB");' NuGet: Install-Package IronPdf
Imports System
Imports System.Diagnostics
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks
Imports IronPdf
' Timing harness for a batch of documents. Replace the generated HTML with your own templates.
Const documentCount As Integer = 100
Const maxConcurrency As Integer = 4
Dim htmlDocuments = Enumerable.Range(1, documentCount) _
.Select(Function(i) $"<html><body><h1>Invoice {i}</h1><p>Amount due: {i * 10} USD</p></body></html>") _
.ToList()
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.EnableJavaScript = False ' static content only
}
}
' Cap how many renders run at once instead of starting every render immediately
Using gate As New SemaphoreSlim(maxConcurrency)
Dim stopwatch = Stopwatch.StartNew()
Dim tasks = htmlDocuments.Select(Async Function(html, index)
Await gate.WaitAsync()
Try
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
pdf.SaveAs($"invoice-{index + 1}.pdf")
End Using
Finally
gate.Release()
End Try
End Function)
Await Task.WhenAll(tasks)
stopwatch.Stop()
Console.WriteLine($"Documents: {documentCount}, at most {maxConcurrency} at a time")
Console.WriteLine($"Total elapsed: {stopwatch.ElapsedMilliseconds} ms")
' Elapsed time divided by the document count: an amortized figure, not the latency of one request
Console.WriteLine($"Amortized time per document: {stopwatch.ElapsedMilliseconds / CDbl(documentCount):F1} ms")
' Resident memory of this process only, sampled once at the end; the Chromium helper
' processes are not included, and this is not the peak
Console.WriteLine($"Working set of this process at end: {Process.GetCurrentProcess().WorkingSet64 / 1024 / 1024} MB")
End UsingCet article ne présente pas de benchmark comparatif : les résultats dépendent des modèles, du matériel et du déploiement, donc mesurez avec les vôtres. Leviers documentés pour chaque bibliothèque :
- Version du moteur IronPDF : Pour les rendus lents de pages modernes, lourdes en JavaScript ou très imbriquées, y compris celles construites avec Bootstrap ou Tailwind, IronPDF recommande le package IronPdf.UpdatedChrome, qui embarque Chromium 131 au lieu de Chromium 109 dans le package standard
- Concurrence IronPDF : Méthodes de rendu asynchrones telles que
RenderHtmlAsPdfAsync, avec votre propre limite sur le nombre de rendus simultanés - Modes de rendu EvoPdf Next :
GlobalSettings.HtmlRendererModeréglé surPersistentProcess(par défaut) maintient un processus moteur de rendu entre les conversions, etProcessPerConversionen démarre un par conversion ; les conversions peuvent s’exécuter en parallèle, chacune avec son propre convertisseur, etGlobalSettings.MaxParallelConversionslimite combien s’exécutent simultanément - Méthodes asynchrones EvoPdf Next :
ConvertHtmlAsyncetConvertUrlAsyncpour le code async/await
Comment les modèles de tarification se comparent-ils selon la taille de l’équipe ?
Structure de licence IronPDF
IronPDF propose plusieurs options tarifaires, dont les licences Lite, Plus et Professionnelle, avec la possibilité de redistribution sans redevance. Le modèle de licence est conçu pour évoluer avec votre équipe et vos besoins projet (tarifs en septembre 2026) :
- Licence Lite : $999
- 1 développeur
- 1 site
- 1 projet
- Support par email
- Idéal pour : développeurs individuels, petits projets
- Licence Plus : $1,499
- 3 développeurs
- 3 sites
- 3 projets
- Support email (SLA 48h) et chat en direct
- Idéal pour : petites équipes, projets multiples
- Licence Professionnelle : $2,399
- 10 développeurs
- 10 sites
- 10 projets
- Support email (SLA 24h), chat en direct, téléphone et partage d’écran
- Idéal pour : équipes moyennes à grandes
- Options supplémentaires :
- Redistribution sans redevance (OEM/SaaS) : +$1,999, pour les logiciels commerciaux et SaaS où les utilisateurs finaux n’appellent pas directement les APIs d’IronPDF
- Licence SDK : requise lorsqu’un produit expose la fonctionnalité d’IronPDF à d’autres développeurs via une API publique
- Extensions de support et mises à jour : 1, 3 ou 5 ans, tarifées selon le niveau de licence
- Iron Suite : les 10 produits Iron Software, sous les mêmes niveaux de licence ; Iron Suite Lite (1 développeur, 1 site, 1 projet) est à $2,998
Options de licence EvoPdf
EVO PDF Toolkit et le convertisseur HTML vers PDF autonome proposent chacun deux niveaux de licence, Déploiement et Entreprise (tarifs en septembre 2026 ; vérifiez les tarifs actuels sur evopdf.com/buy). La licence HTML vers PDF couvre les convertisseurs Next et Classic ; les autres composants, comme PDF Security, ne sont inclus que dans le Toolkit.
- Licence Déploiement :
- EVO HTML to PDF : $450
- EVO PDF Toolkit : $650
- Une application déployée sur un serveur, utilisée par votre propre entreprise
- Développeurs illimités travaillant sur cette application
- Les déploiements load-balancés, conteneurisés ou autoscalés nécessitent une licence Entreprise
- Pas de redistribution
- Support standard la première année
- Licence Entreprise :
- EVO HTML to PDF : $1,200
- EVO PDF Toolkit : $1,400
- Développeurs, applications et serveurs illimités
- Redistribution à vos propres clients dans vos applications ; le contrat de licence n’autorise pas l’offre de la fonctionnalité de conversion comme service autonome, API hébergée ou SDK sans l’accord écrit d’EVO
- Support prioritaire la première année
Analyse du coût total de possession
Chaque scénario ci-dessous précise ses hypothèses de déploiement, car les deux éditeurs tarifient selon le périmètre ainsi que la taille de l’équipe :
Scénario 1 : Deux développeurs, une application interne sur un serveur
- IronPDF Plus : $1,499 (Lite couvre 1 développeur, donc une équipe de 2 nécessite Plus, qui couvre jusqu’à 3)
- EvoPdf Déploiement : $450 (une application sur un serveur ; les développeurs ne sont pas comptés)
- Si l’application fonctionne sur plusieurs serveurs, derrière un load balancer ou dans des conteneurs autoscalés, EvoPdf nécessite la licence Entreprise ($1,200)
- Coût de licence le plus bas : EvoPdf
Scénario 2 : Cinq développeurs, plusieurs applications internes
- IronPDF Professionnelle : $2,399 (jusqu’à 10 développeurs, 10 sites, 10 projets ; Plus ne couvre que 3 développeurs)
- EvoPdf Entreprise : $1,200 (plus d’une application nécessite la licence Entreprise)
- Coût de licence le plus bas : EvoPdf
Scénario 3 : Dix développeurs ayant besoin de PDF et d’autres outils documentaires
- Iron Suite Professionnelle : 10 développeurs, 10 sites, 10 projets, les 10 produits Iron Software (voir la page de licence Iron Suite pour le prix actuel)
- EVO PDF Toolkit Entreprise : $1,400 (développeurs, applications et serveurs illimités ; axé PDF, sans outils OCR ou code-barres)
- Périmètre différent : l’EVO PDF Toolkit coûte moins cher si vous n’avez besoin que d’outils PDF. Iron Suite ajoute OCR, code-barres, Excel, Word et autres bibliothèques, que le Toolkit ne remplace pas. Comparez les deux uniquement à périmètre développeur et déploiement équivalent.
Scénario 4 : Produit SaaS commercial qui génère des PDF pour ses clients
- IronPDF Professionnel + redistribution OEM : $2,399 + $1,999 (couvre les SaaS où les utilisateurs finaux n'appellent pas directement les API d'IronPDF)
- EvoPdf Entreprise : $1,200 (inclut la redistribution ; la génération de PDF doit être une fonctionnalité de votre produit et non un service de conversion généraliste)
- Coût de licence inférieur : EvoPdf, à condition que le produit n'expose pas la fonctionnalité de conversion comme un service ou une API publique ; les deux éditeurs licencient ce cas séparément
Comment les frameworks CSS modernes influencent-ils votre choix ?
Un facteur souvent sous-estimé dans le choix d'une bibliothèque PDF est la prise en charge des frameworks CSS modernes. Avec Bootstrap, Tailwind CSS et Foundation largement utilisés dans le développement web, la capacité de votre bibliothèque à gérer ces frameworks impacte directement l'efficacité du développement et la qualité du rendu.
IronPDF : la prise en charge des frameworks dépend de la version de Chromium
Le moteur Chromium d'IronPDF rend les frameworks CSS comme le fait la version de Chromium embarquée, il faut donc vérifier les prérequis navigateur d'un framework par rapport au package que vous déployez :
- Bootstrap 5 : Les mises en page Flexbox et CSS Grid sont prises en charge
- Tailwind CSS : Tailwind CSS v4 nécessite Chrome 111 ou supérieur, ce qui est plus récent que le Chromium 109 du package Windows standard ; sous Windows, les mises en page v4 nécessitent le package IronPdf.UpdatedChrome (Chromium 131). Tailwind recommande de rester sur la v3.4 si des navigateurs plus anciens doivent être pris en charge. Testez vos propres modèles avec le package que vous déployez.
- CSS3 moderne : Les transformations et propriétés personnalisées sont prises en charge
- La version du moteur compte : Certains CSS récents, comme
subgrid, les cas limites deoverflow: hiddenet les hauteurs de ligne personnalisées, ne s'affichent correctement qu'avec IronPdf.UpdatedChrome, recommandé également par IronPDF lorsque les pages Bootstrap ou Tailwind sont lentes à rendre. IronPdf.UpdatedChrome ne prend pas en charge les processus 32 bits, Windows Server 2012 ou le modeSingleProcess, vérifiez donc vos cibles de déploiement avant de basculer.
Exemple de code : composant Timeline Bootstrap
// NuGet: Install-Package IronPdf
using IronPdf;
var renderer = new ChromePdfRenderer();
string bootstrapTimeline = @"
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
<style>
.timeline { position: relative; padding: 20px 0; }
.timeline::before {
content: '';
position: absolute;
left: 50%;
width: 2px;
height: 100%;
background: #dee2e6;
}
.timeline-item { position: relative; margin: 20px 0; }
</style>
</head>
<body>
<div class='container py-5'>
<h2 class='text-center mb-5'>Project Timeline</h2>
<div class='timeline'>
<div class='timeline-item'>
<div class='row'>
<div class='col-md-6'>
<div class='card shadow-sm'>
<div class='card-body'>
<h5 class='card-title'>Phase 1: Planning</h5>
<p class='text-muted'>Q1 2025</p>
<p class='card-text'>Initial project scope and requirements gathering completed.</p>
<span class='badge bg-success'>Completed</span>
</div>
</div>
</div>
</div>
</div>
<!-- Additional timeline items... -->
</div>
</div>
</body>
</html>";
// The page loads Bootstrap from a CDN, so the renderer needs network access
using var pdf = renderer.RenderHtmlAsPdf(bootstrapTimeline);
pdf.SaveAs("project-timeline.pdf");' NuGet: Install-Package IronPdf
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim bootstrapTimeline As String = "
<!DOCTYPE html>
<html>
<head>
<link href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css' rel='stylesheet'>
<style>
.timeline { position: relative; padding: 20px 0; }
.timeline::before {
content: '';
position: absolute;
left: 50%;
width: 2px;
height: 100%;
background: #dee2e6;
}
.timeline-item { position: relative; margin: 20px 0; }
</style>
</head>
<body>
<div class='container py-5'>
<h2 class='text-center mb-5'>Project Timeline</h2>
<div class='timeline'>
<div class='timeline-item'>
<div class='row'>
<div class='col-md-6'>
<div class='card shadow-sm'>
<div class='card-body'>
<h5 class='card-title'>Phase 1: Planning</h5>
<p class='text-muted'>Q1 2025</p>
<p class='card-text'>Initial project scope and requirements gathering completed.</p>
<span class='badge bg-success'>Completed</span>
</div>
</div>
</div>
</div>
</div>
<!-- Additional timeline items... -->
</div>
</div>
</body>
</html>"
' The page loads Bootstrap from a CDN, so the renderer needs network access
Using pdf = renderer.RenderHtmlAsPdf(bootstrapTimeline)
pdf.SaveAs("project-timeline.pdf")
End UsingEvoPdf : Chromium dans Next, moteur EVO dans Classic
Les deux éditions d'EvoPdf gèrent différemment les CSS modernes :
- EvoPdf Next : Moteur basé sur Chromium (Chromium 142, selon EVO PDF) avec prise en charge documentée de flexbox, grid, JavaScript ES2015+ et polices web
- EvoPdf Classic : Moteur de rendu propriétaire EVO, décrit comme prenant en charge CSS3, SVG, polices web et JavaScript ; la New Edition ajoute ECMAScript 6, WOFF 2, HTTP/2 et TLS 1.3
Impact sur le développement : Si votre application utilise massivement Bootstrap ou Tailwind et que vous souhaitez des PDF fidèles à votre interface web, testez vos modèles réels avec la version d'essai de chaque bibliothèque. Avec des moteurs Chromium des deux côtés (IronPDF et EvoPdf Next), les différences proviendront surtout de la version du moteur et de la configuration, plus que du support du framework.
Pour plus d'informations sur la compatibilité avec les frameworks CSS, consultez le Guide Bootstrap & Flexbox CSS.
Quelles options de documentation et de support servent le mieux les développeurs ?
Les ressources développeur d'IronPDF
IronPDF propose documentation, chat en direct 24/5, support technique 24/7 avec le Support Premium, tutoriels vidéo et mises à jour régulières. L'écosystème de support inclut :
- Qualité de la documentation :
- Référence API
- Tutoriels pas à pas
- 100+ exemples de code
- Tutoriels vidéo sur YouTube
- Guides de migration depuis d'autres bibliothèques
- Canaux de support :
- Support technique 24/7 avec le Support Premium, disponible pour les licences payantes ; les utilisateurs en essai bénéficient du Support Premium pendant la période d'essai
- SLA de réponse par email : 48h (Plus), 24h (Professionnel), 12h (Illimité)
- Chat en direct sur tous les niveaux de licence, 24/5
- Support téléphonique pour les licences Professionnel et Illimité
- Partage d'écran pour les licences Professionnel et Illimité
- Ressources d'apprentissage :
- Guides de démarrage
- Guides d'optimisation des performances
- Bonnes pratiques de sécurité
- Guides de déploiement cloud
La structure de support d'EvoPdf
EvoPdf propose documentation et support via :
- Documentation :
- Documentation de référence API
- Exemples de code pour les scénarios courants, plus des exemples sur GitHub
- Application de démonstration en ligne
- FAQ de support couvrant la licence, le déploiement et la conversion
- Options de support :
- Support technique inclus la première année, et gratuit pendant l'évaluation
- Support standard (licence Deployment) ou support prioritaire (licence Company)
- Renouvellements de maintenance disponibles après la première année
La principale différence réside dans la richesse du contenu pédagogique d'IronPDF (tutoriels, guides pratiques et vidéos) ainsi que le chat en direct 24/5 et le support 24/7 avec le Support Premium.
Quels sont les meilleurs cas d'utilisation pour chaque bibliothèque ?
Quand choisir IronPDF
IronPDF excelle dans les scénarios nécessitant :
1. Intégration à des applications web modernes
- Plateformes SaaS générant des rapports dynamiques
- Sites e-commerce créant des factures avec graphiques
- Tableaux de bord de business intelligence exportés en PDF
- Applications utilisant React, Angular ou Vue.js
2. Documents à contenu sensible
- Suppression de données personnelles avant partage de documents
- Chiffrement et protection par mot de passe des rapports générés
- Signature de documents pour détecter toute modification ultérieure
- Gestion documentaire juridique avec caviardage
3. Traitement documentaire complexe
- Conversion multi-format (DOCX, HTML, images)
- OCR pour documents scannés via IronOCR
- Traitement par lots avec exécution parallèle
- Documents avec signatures numériques
4. Déploiement multiplateforme
- Applications conteneurisées Docker
- Déploiements cloud sous Linux
- Architectures microservices
- Fonctions serverless (AWS Lambda, Azure Functions)
Exemple : protection d'un rapport généré
// NuGet: Install-Package IronPdf
using System.Net;
using IronPdf;
using IronPdf.Security;
using IronPdf.Signing;
var patient = new PatientRecord("P-10442", "Jane <Q.> Doe & Family", "123-45-6789", "open-sesame");
// HTML-encode text values, so characters such as & and < print as text instead of changing the markup
var html = $@"
<html>
<body>
<h1>Patient Summary</h1>
<p>Patient ID: {WebUtility.HtmlEncode(patient.PatientId)}</p>
<p>Name: {WebUtility.HtmlEncode(patient.Name)}</p>
<p>SSN: {WebUtility.HtmlEncode(patient.Ssn)}</p>
</body>
</html>";
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(html);
// Remove the SSN from the page content wherever it appears
pdf.RedactTextOnAllPages(patient.Ssn);
// Descriptive document properties
pdf.MetaData.Author = "Records System";
pdf.MetaData.Title = $"Patient Summary {patient.PatientId}";
// Require a password to open the file, restrict copying, and encrypt with AES-256
pdf.SecuritySettings.UserPassword = patient.AccessCode;
pdf.SecuritySettings.OwnerPassword = "records-owner-password";
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256;
// Sign last, so changes made to the file after signing can be detected
pdf.Sign(new PdfSignature("records-cert.pfx", "password")
{
SigningReason = "Record export",
SigningLocation = "Records Department"
});
pdf.SaveAs("patient-summary.pdf");
record PatientRecord(string PatientId, string Name, string Ssn, string AccessCode);' NuGet: Install-Package IronPdf
Imports System.Net
Imports IronPdf
Imports IronPdf.Security
Imports IronPdf.Signing
Dim patient = New PatientRecord("P-10442", "Jane <Q.> Doe & Family", "123-45-6789", "open-sesame")
' HTML-encode text values, so characters such as & and < print as text instead of changing the markup
Dim html = $"
<html>
<body>
<h1>Patient Summary</h1>
<p>Patient ID: {WebUtility.HtmlEncode(patient.PatientId)}</p>
<p>Name: {WebUtility.HtmlEncode(patient.Name)}</p>
<p>SSN: {WebUtility.HtmlEncode(patient.Ssn)}</p>
</body>
</html>"
Dim renderer = New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(html)
' Remove the SSN from the page content wherever it appears
pdf.RedactTextOnAllPages(patient.Ssn)
' Descriptive document properties
pdf.MetaData.Author = "Records System"
pdf.MetaData.Title = $"Patient Summary {patient.PatientId}"
' Require a password to open the file, restrict copying, and encrypt with AES-256
pdf.SecuritySettings.UserPassword = patient.AccessCode
pdf.SecuritySettings.OwnerPassword = "records-owner-password"
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256
' Sign last, so changes made to the file after signing can be detected
pdf.Sign(New PdfSignature("records-cert.pfx", "password") With {
.SigningReason = "Record export",
.SigningLocation = "Records Department"
})
pdf.SaveAs("patient-summary.pdf")
End Using
Public Record PatientRecord(PatientId As String, Name As String, Ssn As String, AccessCode As String)Ce sont des briques de traitement documentaire. Le respect d'une réglementation comme HIPAA dépend aussi de la façon dont l'application stocke, transmet et contrôle l'accès aux données, ce qu'aucun paramètre PDF ne garantit à lui seul.
Quand choisir EvoPdf
EvoPdf est particulièrement adapté pour :
1. Conversion HTML vers PDF
- Rapports générés à partir de modèles HTML
- HTML, CSS et JavaScript modernes avec EvoPdf Next basé sur Chromium
- Factures et reçus
- Génération de documents en masse avec des modèles cohérents
2. Équipes soucieuses du budget
- Développeurs illimités sur une seule licence
- Coût d'entrée plus bas (licence Deployment $450)
- Projets n'ayant pas besoin de caviardage intégré
3. Environnements serveur spécifiques
- Applications .NET Framework héritées (EvoPdf Classic prend en charge .NET Framework 2.0 et supérieur)
- Licence par serveur pour une seule application
- Intégration à des systèmes anciens
4. Conversions à haut volume
- Génération de rapports statiques
- Systèmes de documentation
- Création de documents prêts à imprimer
Exemple réel : système de génération de factures
// NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
using System;
using System.Globalization;
using System.IO;
using System.Net;
using EvoPdf;
var invoice = new InvoiceData("INV-2026-0042", new DateTime(2026, 9, 1), "Smith & Sons <Ltd>", 1250.00m);
var converter = new HtmlToPdfConverter
{
// LicenseKey = "<your EvoPdf license key>",
JavaScriptEnabled = false, // not needed for static invoices
ConversionDelay = 0
};
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
converter.PdfDocumentOptions.TopMargin = 30; // points
converter.PdfDocumentOptions.BottomMargin = 30; // points
string template =
"<html><body><h1>Invoice {{InvoiceNumber}}</h1>" +
"<p>Date: {{Date}}</p><p>Customer: {{CustomerName}}</p><p>Total: {{Total}}</p></body></html>";
// HTML-encode text values, so characters such as & and < print as text instead of changing the markup
string html = template
.Replace("{{InvoiceNumber}}", WebUtility.HtmlEncode(invoice.InvoiceNumber))
.Replace("{{Date}}", invoice.Date.ToString("yyyy-MM-dd"))
.Replace("{{CustomerName}}", WebUtility.HtmlEncode(invoice.CustomerName))
.Replace("{{Total}}", invoice.Total.ToString("C", CultureInfo.GetCultureInfo("en-US")));
File.WriteAllBytes($"invoice-{invoice.InvoiceNumber}.pdf", converter.ConvertHtml(html, ""));
record InvoiceData(string InvoiceNumber, DateTime Date, string CustomerName, decimal Total);' NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
Imports System
Imports System.Globalization
Imports System.IO
Imports System.Net
Imports EvoPdf
Dim invoice = New InvoiceData("INV-2026-0042", New DateTime(2026, 9, 1), "Smith & Sons <Ltd>", 1250.00D)
Dim converter = New HtmlToPdfConverter With {
' LicenseKey = "<your EvoPdf license key>",
.JavaScriptEnabled = False, ' not needed for static invoices
.ConversionDelay = 0
}
converter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
converter.PdfDocumentOptions.TopMargin = 30 ' points
converter.PdfDocumentOptions.BottomMargin = 30 ' points
Dim template As String =
"<html><body><h1>Invoice {{InvoiceNumber}}</h1>" +
"<p>Date: {{Date}}</p><p>Customer: {{CustomerName}}</p><p>Total: {{Total}}</p></body></html>"
' HTML-encode text values, so characters such as & and < print as text instead of changing the markup
Dim html As String = template _
.Replace("{{InvoiceNumber}}", WebUtility.HtmlEncode(invoice.InvoiceNumber)) _
.Replace("{{Date}}", invoice.Date.ToString("yyyy-MM-dd")) _
.Replace("{{CustomerName}}", WebUtility.HtmlEncode(invoice.CustomerName)) _
.Replace("{{Total}}", invoice.Total.ToString("C", CultureInfo.GetCultureInfo("en-US")))
File.WriteAllBytes($"invoice-{invoice.InvoiceNumber}.pdf", converter.ConvertHtml(html, ""))
Public Class InvoiceData
Public Property InvoiceNumber As String
Public Property Date As DateTime
Public Property CustomerName As String
Public Property Total As Decimal
Public Sub New(invoiceNumber As String, [date] As DateTime, customerName As String, total As Decimal)
Me.InvoiceNumber = invoiceNumber
Me.Date = [date]
Me.CustomerName = customerName
Me.Total = total
End Sub
End ClassModèles d'implémentation avancés et bonnes pratiques
Optimiser les performances en production
Les deux bibliothèques bénéficient d'une configuration et de schémas d'utilisation adaptés :
Optimisation des performances IronPDF
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using IronPdf;
using IronPdf.Engines.Chrome;
using IronPdf.Rendering;
// Global engine settings: set once at startup, before the first render
Installation.ChromeGpuMode = ChromeGpuModes.Disabled; // servers usually have no GPU
// Set to false only if the Linux dependencies are already installed in your image
Installation.LinuxAndDockerDependenciesAutoConfig = false;
var service = new PdfService(maxConcurrency: 4);
var pages = Enumerable.Range(1, 8).Select(i => $"<h1>Report {i}</h1>");
byte[][] results = await Task.WhenAll(pages.Select(service.GeneratePdfAsync));
for (int i = 0; i < results.Length; i++)
File.WriteAllBytes($"report-{i + 1}.pdf", results[i]);
Console.WriteLine($"Generated {results.Length} PDFs");
public class PdfService
{
private readonly ChromePdfRenderer _renderer;
private readonly SemaphoreSlim _gate;
public PdfService(int maxConcurrency)
{
// Caps how many renders run at once
_gate = new SemaphoreSlim(maxConcurrency);
_renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
EnableJavaScript = false, // only if the pages need no JavaScript
CssMediaType = PdfCssMediaType.Screen,
Timeout = 30 // seconds
}
};
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
await _gate.WaitAsync();
try
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
finally
{
_gate.Release();
}
}
}Imports System
Imports System.IO
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks
Imports IronPdf
Imports IronPdf.Engines.Chrome
Imports IronPdf.Rendering
' Global engine settings: set once at startup, before the first render
Installation.ChromeGpuMode = ChromeGpuModes.Disabled ' servers usually have no GPU
' Set to false only if the Linux dependencies are already installed in your image
Installation.LinuxAndDockerDependenciesAutoConfig = False
Dim service = New PdfService(MaxConcurrency:=4)
Dim pages = Enumerable.Range(1, 8).Select(Function(i) $"<h1>Report {i}</h1>")
Dim results As Byte()() = Await Task.WhenAll(pages.Select(Function(page) service.GeneratePdfAsync(page)))
For i As Integer = 0 To results.Length - 1
File.WriteAllBytes($"report-{i + 1}.pdf", results(i))
Next
Console.WriteLine($"Generated {results.Length} PDFs")
Public Class PdfService
Private ReadOnly _renderer As ChromePdfRenderer
Private ReadOnly _gate As SemaphoreSlim
Public Sub New(maxConcurrency As Integer)
' Caps how many renders run at once
_gate = New SemaphoreSlim(maxConcurrency)
_renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.EnableJavaScript = False, ' only if the pages need no JavaScript
.CssMediaType = PdfCssMediaType.Screen,
.Timeout = 30 ' seconds
}
}
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Await _gate.WaitAsync()
Try
Using pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Using
Finally
_gate.Release()
End Try
End Function
End ClassSchémas de performance EvoPdf
// NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using EvoPdf;
var service = new EvoPdfService(maxConcurrency: 4);
var pages = Enumerable.Range(1, 8).Select(i => $"<h1>Report {i}</h1>");
byte[][] results = await Task.WhenAll(pages.Select(service.GeneratePdfAsync));
for (int i = 0; i < results.Length; i++)
File.WriteAllBytes($"evopdf-report-{i + 1}.pdf", results[i]);
Console.WriteLine($"Generated {results.Length} PDFs");
public class EvoPdfService
{
private readonly SemaphoreSlim _gate;
// Caps how many conversions run at once
public EvoPdfService(int maxConcurrency) => _gate = new SemaphoreSlim(maxConcurrency);
public async Task<byte[]> GeneratePdfAsync(string html)
{
await _gate.WaitAsync();
try
{
// A new converter for each conversion, as EVO documents for parallel conversions
var converter = new HtmlToPdfConverter
{
// LicenseKey = "<your EvoPdf license key>",
JavaScriptEnabled = false,
ConversionDelay = 0
};
// The Classic API is synchronous, so run it on a thread-pool thread
return await Task.Run(() => converter.ConvertHtml(html, ""));
}
finally
{
_gate.Release();
}
}
}Imports System
Imports System.IO
Imports System.Linq
Imports System.Threading
Imports System.Threading.Tasks
Imports EvoPdf
Dim service = New EvoPdfService(maxConcurrency:=4)
Dim pages = Enumerable.Range(1, 8).[Select](Function(i) $"<h1>Report {i}</h1>")
Dim results As Byte()() = Await Task.WhenAll(pages.[Select](Function(page) service.GeneratePdfAsync(page)))
For i As Integer = 0 To results.Length - 1
File.WriteAllBytes($"evopdf-report-{i + 1}.pdf", results(i))
Next
Console.WriteLine($"Generated {results.Length} PDFs")
Public Class EvoPdfService
Private ReadOnly _gate As SemaphoreSlim
' Caps how many conversions run at once
Public Sub New(maxConcurrency As Integer)
_gate = New SemaphoreSlim(maxConcurrency)
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte())
Await _gate.WaitAsync()
Try
' A new converter for each conversion, as EVO documents for parallel conversions
Dim converter = New HtmlToPdfConverter With {
' LicenseKey = "<your EvoPdf license key>",
.JavaScriptEnabled = False,
.ConversionDelay = 0
}
' The Classic API is synchronous, so run it on a thread-pool thread
Return Await Task.Run(Function() converter.ConvertHtml(html, ""))
Finally
_gate.Release()
End Try
End Function
End ClassLe sémaphore est ce qui limite la concurrence dans les deux exemples. Dans EvoPdf Next, GlobalSettings.MaxParallelConversions définit la même limite à l'intérieur de la bibliothèque, et le renderer persistant maintient le processus du moteur de rendu actif entre les conversions.
Gestion des erreurs et débogage
Le code en production doit gérer les échecs de rendu, comme une page qui ne peut pas être chargée :
Gestion des erreurs IronPDF
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using System.Threading.Tasks;
using IronPdf;
using IronPdf.Exceptions;
// Write IronPDF's own diagnostics to a log file
IronPdf.Logging.Logger.LogFilePath = "ironpdf.log";
IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All;
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.Timeout = 60; // seconds
byte[] page = await TryRenderUrlAsync(renderer, "https://example.com/");
if (page != null)
{
File.WriteAllBytes("example.pdf", page);
Console.WriteLine($"Rendered {page.Length} bytes");
}
// A host that does not resolve makes the render throw, which exercises the error path
byte[] missing = await TryRenderUrlAsync(renderer, "https://nonexistent.invalid/");
Console.WriteLine(missing == null ? "Second render failed and was handled" : "Second render succeeded");
// Returns the PDF bytes, or null if the page could not be rendered
static async Task<byte[]> TryRenderUrlAsync(ChromePdfRenderer renderer, string url)
{
try
{
using var pdf = await renderer.RenderUrlAsPdfAsync(url);
if (pdf.PageCount == 0)
{
Console.Error.WriteLine($"No pages rendered for {url}");
return null;
}
return pdf.BinaryData;
}
catch (IronPdfNativeException ex)
{
// Raised by the rendering engine, for example when the page cannot be loaded
Console.Error.WriteLine($"Rendering failed for {url}: {ex.Message}");
return null;
}
}' NuGet: Install-Package IronPdf
Imports System
Imports System.IO
Imports System.Threading.Tasks
Imports IronPdf
Imports IronPdf.Exceptions
' Write IronPDF's own diagnostics to a log file
IronPdf.Logging.Logger.LogFilePath = "ironpdf.log"
IronPdf.Logging.Logger.LoggingMode = IronPdf.Logging.Logger.LoggingModes.All
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.Timeout = 60 ' seconds
Dim page As Byte() = Await TryRenderUrlAsync(renderer, "https://example.com/")
If page IsNot Nothing Then
File.WriteAllBytes("example.pdf", page)
Console.WriteLine($"Rendered {page.Length} bytes")
End If
' A host that does not resolve makes the render throw, which exercises the error path
Dim missing As Byte() = Await TryRenderUrlAsync(renderer, "https://nonexistent.invalid/")
Console.WriteLine(If(missing Is Nothing, "Second render failed and was handled", "Second render succeeded"))
' Returns the PDF bytes, or null if the page could not be rendered
Private Shared Async Function TryRenderUrlAsync(renderer As ChromePdfRenderer, url As String) As Task(Of Byte())
Try
Using pdf = Await renderer.RenderUrlAsPdfAsync(url)
If pdf.PageCount = 0 Then
Console.Error.WriteLine($"No pages rendered for {url}")
Return Nothing
End If
Return pdf.BinaryData
End Using
Catch ex As IronPdfNativeException
' Raised by the rendering engine, for example when the page cannot be loaded
Console.Error.WriteLine($"Rendering failed for {url}: {ex.Message}")
Return Nothing
End Try
End FunctionExemples d'implémentation par secteur
Rapports financiers : relevés signés et en lecture seule
Un relevé qui ne doit pas être modifié après validation peut combiner un filigrane, des permissions restreintes et une signature :
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Editing;
using IronPdf.Security;
using IronPdf.Signing;
using IronSoftware.Drawing;
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderHtmlAsPdf(
"<h1>Quarterly Statement: Q3 2026</h1>" +
"<table><tr><td>Revenue</td><td>1,250,000</td></tr><tr><td>Expenses</td><td>980,000</td></tr></table>");
// Mark the document as a draft
pdf.ApplyWatermark(@"
<div style='color: rgba(0,0,0,0.1); font-size: 120px; transform: rotate(-45deg); font-family: Arial;'>
DRAFT
</div>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center);
// Descriptive document properties: useful for search and filing, not a record of who changed what
pdf.MetaData.Author = "Financial Reporting System";
pdf.MetaData.Keywords = "Quarterly Statement, Q3 2026";
pdf.MetaData.CustomProperties.Add("ReportPeriod", "2026-Q3");
pdf.MetaData.CustomProperties.Add("GeneratedAt", DateTime.UtcNow.ToString("O"));
// Restrict editing; the owner password is needed to change these permissions
pdf.SecuritySettings.OwnerPassword = "finance-owner-password";
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SecuritySettings.AllowUserCopyPasteContent = true;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256;
// Sign last: readers can then detect changes made after signing
pdf.Sign(new PdfSignature("financial-cert.pfx", "password")
{
SigningReason = "Statement approval",
SigningLocation = "Finance Department",
// Visible signature image on the first page
SignatureImage = new PdfSignatureImage("cfo-signature.png", 0, new Rectangle(50, 50, 200, 60))
});
pdf.SaveAs("quarterly-statement.pdf");' NuGet: Install-Package IronPdf
Imports System
Imports IronPdf
Imports IronPdf.Editing
Imports IronPdf.Security
Imports IronPdf.Signing
Imports IronSoftware.Drawing
Dim renderer = New ChromePdfRenderer()
Using pdf = renderer.RenderHtmlAsPdf(
"<h1>Quarterly Statement: Q3 2026</h1>" &
"<table><tr><td>Revenue</td><td>1,250,000</td></tr><tr><td>Expenses</td><td>980,000</td></tr></table>")
' Mark the document as a draft
pdf.ApplyWatermark("
<div style='color: rgba(0,0,0,0.1); font-size: 120px; transform: rotate(-45deg); font-family: Arial;'>
DRAFT
</div>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center)
' Descriptive document properties: useful for search and filing, not a record of who changed what
pdf.MetaData.Author = "Financial Reporting System"
pdf.MetaData.Keywords = "Quarterly Statement, Q3 2026"
pdf.MetaData.CustomProperties.Add("ReportPeriod", "2026-Q3")
pdf.MetaData.CustomProperties.Add("GeneratedAt", DateTime.UtcNow.ToString("O"))
' Restrict editing; the owner password is needed to change these permissions
pdf.SecuritySettings.OwnerPassword = "finance-owner-password"
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SecuritySettings.AllowUserCopyPasteContent = True
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.EncryptionType = PdfEncryptionType.Aes_256
' Sign last: readers can then detect changes made after signing
pdf.Sign(New PdfSignature("financial-cert.pfx", "password") With {
.SigningReason = "Statement approval",
.SigningLocation = "Finance Department",
' Visible signature image on the first page
.SignatureImage = New PdfSignatureImage("cfo-signature.png", 0, New Rectangle(50, 50, 200, 60))
})
pdf.SaveAs("quarterly-statement.pdf")
End UsingLa signature permet de détecter toute modification ultérieure et les permissions découragent l'édition ; aucune de ces mesures n'est, à elle seule, un contrôle de conformité ou une piste d'audit de qui a fait quoi.
E-commerce : génération dynamique de factures
Les plateformes e-commerce ont besoin d'une génération de factures rapide et fiable :
// NuGet: Install-Package IronPdf
using System;
using System.Globalization;
using System.Linq;
using System.Net;
using IronPdf;
using IronPdf.Rendering;
var order = new Order("INV-1001", new DateTime(2026, 9, 1), new[]
{
new OrderItem("Widget <Deluxe> & Co. edition", 2, 19.99m),
new OrderItem("Gift wrap", 1, 4.50m)
});
var renderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
MarginTop = 10, // millimetres
MarginBottom = 10,
PaperSize = PdfPaperSize.A4
}
};
var usd = CultureInfo.GetCultureInfo("en-US");
// HTML-encode text values, so characters such as & and < print as text instead of changing the markup
string rows = string.Concat(order.Items.Select(item => $@"
<tr>
<td>{WebUtility.HtmlEncode(item.Name)}</td>
<td>{item.Quantity}</td>
<td>{item.Price.ToString("C", usd)}</td>
<td>{item.Total.ToString("C", usd)}</td>
</tr>"));
var html = $@"
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; }}
.invoice-header {{ background: #f0f0f0; padding: 20px; }}
table {{ width: 100%; border-collapse: collapse; }}
th, td {{ padding: 10px; border-bottom: 1px solid #ddd; text-align: left; }}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{WebUtility.HtmlEncode(order.InvoiceNumber)}</h1>
<p>Date: {order.Date:yyyy-MM-dd}</p>
</div>
<table>
<tr><th>Item</th><th>Quantity</th><th>Price</th><th>Total</th></tr>
{rows}
<tr><td colspan='3'><strong>Total</strong></td><td><strong>{order.Total.ToString("C", usd)}</strong></td></tr>
</table>
<p>Thank you for your business!</p>
</body>
</html>";
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
pdf.SaveAs($"invoice-{order.InvoiceNumber}.pdf");
record OrderItem(string Name, int Quantity, decimal Price)
{
public decimal Total => Price * Quantity;
}
record Order(string InvoiceNumber, DateTime Date, OrderItem[] Items)
{
public decimal Total => Items.Sum(item => item.Total);
}' NuGet: Install-Package IronPdf
Imports System
Imports System.Globalization
Imports System.Linq
Imports System.Net
Imports IronPdf
Imports IronPdf.Rendering
Dim order = New Order("INV-1001", New DateTime(2026, 9, 1), {
New OrderItem("Widget <Deluxe> & Co. edition", 2, 19.99D),
New OrderItem("Gift wrap", 1, 4.5D)
})
Dim renderer = New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.MarginTop = 10, ' millimetres
.MarginBottom = 10,
.PaperSize = PdfPaperSize.A4
}
}
Dim usd = CultureInfo.GetCultureInfo("en-US")
' HTML-encode text values, so characters such as & and < print as text instead of changing the markup
Dim rows As String = String.Concat(order.Items.Select(Function(item) $"
<tr>
<td>{WebUtility.HtmlEncode(item.Name)}</td>
<td>{item.Quantity}</td>
<td>{item.Price.ToString("C", usd)}</td>
<td>{item.Total.ToString("C", usd)}</td>
</tr>"))
Dim html = $"
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; }}
.invoice-header {{ background: #f0f0f0; padding: 20px; }}
table {{ width: 100%; border-collapse: collapse; }}
th, td {{ padding: 10px; border-bottom: 1px solid #ddd; text-align: left; }}
</style>
</head>
<body>
<div class='invoice-header'>
<h1>Invoice #{WebUtility.HtmlEncode(order.InvoiceNumber)}</h1>
<p>Date: {order.Date:yyyy-MM-dd}</p>
</div>
<table>
<tr><th>Item</th><th>Quantity</th><th>Price</th><th>Total</th></tr>
{rows}
<tr><td colspan='3'><strong>Total</strong></td><td><strong>{order.Total.ToString("C", usd)}</strong></td></tr>
</table>
<p>Thank you for your business!</p>
</body>
</html>"
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
pdf.SaveAs($"invoice-{order.InvoiceNumber}.pdf")
End Using
Public Record OrderItem(Name As String, Quantity As Integer, Price As Decimal)
Public ReadOnly Property Total As Decimal
Get
Return Price * Quantity
End Get
End Property
End Record
Public Record Order(InvoiceNumber As String, [Date] As DateTime, Items As OrderItem())
Public ReadOnly Property Total As Decimal
Get
Return Items.Sum(Function(item) item.Total)
End Get
End Property
End RecordStratégies de migration : passer d'une bibliothèque à l'autre
Si vous envisagez de changer de bibliothèque, voici une approche de migration :
Migrer d'EvoPdf vers IronPDF
// NuGet: Install-Package EvoPdf.HtmlToPdf (EvoPdf Classic, Windows)
// NuGet: Install-Package IronPdf
using System.IO;
using EvoPdf;
using IronPdf;
using IronPdf.Rendering;
string url = "https://example.com/";
// EvoPdf pattern
HtmlToPdfConverter evoPdfConverter = new HtmlToPdfConverter();
evoPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
File.WriteAllBytes("evopdf.pdf", evoPdfConverter.ConvertUrl(url));
// Equivalent IronPDF pattern
var ironPdfRenderer = new ChromePdfRenderer
{
RenderingOptions = new ChromePdfRenderOptions
{
PaperSize = PdfPaperSize.A4
}
};
using (var pdf = ironPdfRenderer.RenderUrlAsPdf(url))
{
File.WriteAllBytes("ironpdf.pdf", pdf.BinaryData);
}
// During a gradual migration, both libraries can sit behind one interface
IPdfConverter converter = new IronPdfAdapter();
File.WriteAllBytes("adapter.pdf", converter.ConvertUrlToPdf(url));
public interface IPdfConverter
{
byte[] ConvertHtmlToPdf(string html);
byte[] ConvertUrlToPdf(string url);
}
public class IronPdfAdapter : IPdfConverter
{
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();
public byte[] ConvertHtmlToPdf(string html)
{
using var pdf = _renderer.RenderHtmlAsPdf(html);
return pdf.BinaryData;
}
public byte[] ConvertUrlToPdf(string url)
{
using var pdf = _renderer.RenderUrlAsPdf(url);
return pdf.BinaryData;
}
}
public class EvoPdfAdapter : IPdfConverter
{
private readonly HtmlToPdfConverter _converter = new HtmlToPdfConverter();
public byte[] ConvertHtmlToPdf(string html)
{
return _converter.ConvertHtml(html, "");
}
public byte[] ConvertUrlToPdf(string url)
{
return _converter.ConvertUrl(url);
}
}Imports System.IO
Imports EvoPdf
Imports IronPdf
Imports IronPdf.Rendering
Dim url As String = "https://example.com/"
' EvoPdf pattern
Dim evoPdfConverter As New HtmlToPdfConverter()
evoPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4
File.WriteAllBytes("evopdf.pdf", evoPdfConverter.ConvertUrl(url))
' Equivalent IronPDF pattern
Dim ironPdfRenderer As New ChromePdfRenderer With {
.RenderingOptions = New ChromePdfRenderOptions With {
.PaperSize = PdfPaperSize.A4
}
}
Using pdf = ironPdfRenderer.RenderUrlAsPdf(url)
File.WriteAllBytes("ironpdf.pdf", pdf.BinaryData)
End Using
' During a gradual migration, both libraries can sit behind one interface
Dim converter As IPdfConverter = New IronPdfAdapter()
File.WriteAllBytes("adapter.pdf", converter.ConvertUrlToPdf(url))
Public Interface IPdfConverter
Function ConvertHtmlToPdf(html As String) As Byte()
Function ConvertUrlToPdf(url As String) As Byte()
End Interface
Public Class IronPdfAdapter
Implements IPdfConverter
Private ReadOnly _renderer As New ChromePdfRenderer()
Public Function ConvertHtmlToPdf(html As String) As Byte() Implements IPdfConverter.ConvertHtmlToPdf
Using pdf = _renderer.RenderHtmlAsPdf(html)
Return pdf.BinaryData
End Using
End Function
Public Function ConvertUrlToPdf(url As String) As Byte() Implements IPdfConverter.ConvertUrlToPdf
Using pdf = _renderer.RenderUrlAsPdf(url)
Return pdf.BinaryData
End Using
End Function
End Class
Public Class EvoPdfAdapter
Implements IPdfConverter
Private ReadOnly _converter As New HtmlToPdfConverter()
Public Function ConvertHtmlToPdf(html As String) As Byte() Implements IPdfConverter.ConvertHtmlToPdf
Return _converter.ConvertHtml(html, "")
End Function
Public Function ConvertUrlToPdf(url As String) As Byte() Implements IPdfConverter.ConvertUrlToPdf
Return _converter.ConvertUrl(url)
End Function
End ClassConclusion : faire le bon choix pour votre projet
IronPDF et EvoPdf jouent tous deux un rôle important dans l'écosystème des bibliothèques PDF .NET, mais ils ciblent des cas d'usage et des philosophies de développement différents.
Choisissez IronPDF si vous avez besoin de :
- Prise en charge des standards web modernes (CSS3, frameworks JavaScript)
- Manipulation PDF au-delà de la génération, comme la fusion, les formulaires, le caviardage et la signature
- Fonctionnalités de sécurité telles que chiffrement, signatures et caviardage
- Flexibilité de déploiement multiplateforme
- Documentation étendue et support technique direct
- Intégration avec d'autres outils de traitement documentaire
Choisissez EvoPdf si vous avez besoin de :
- Conversion HTML vers PDF à un coût de licence inférieur
- Licence par application (Deployment) ou licence entreprise (Company), avec redistribution dans vos propres applications incluse dans la licence Company
- Licences ne comptant pas le nombre de développeurs
- Choix entre un moteur basé sur Chromium (EvoPdf Next) et un moteur Windows compatible .NET Framework 2.0 et supérieur (EvoPdf Classic)
La décision dépendra en fin de compte de vos besoins spécifiques, de vos contraintes budgétaires et de vos exigences de montée en charge à long terme. Pour les applications modernes nécessitant des manipulations PDF avancées, comme le caviardage intégré et la conversion DOCX, l'ensemble de fonctionnalités et la documentation d'IronPDF en font un investissement solide. EvoPdf est également une option pertinente, notamment pour les équipes qui apprécient sa licence entreprise et la redistribution incluse.
Envisagez de commencer par la version d'essai gratuite de 30 jours d'IronPDF pour évaluer ses capacités dans votre cas d'usage. L'essai donne accès aux fonctionnalités d'IronPDF, vous permettant de prendre une décision éclairée sur la base des performances réelles dans votre environnement.
N'oubliez pas que le coût réel d'une bibliothèque PDF va au-delà du prix de la licence : prenez en compte le temps de développement, la maintenance et le besoin potentiel de fonctionnalités supplémentaires à mesure que votre application évolue. Choisissez la bibliothèque qui répond non seulement à vos besoins actuels, mais qui pourra évoluer avec vos exigences futures.

Jacob Mellor est directeur de la technologie chez Iron Software et un ingénieur visionnaire pionnier de la technologie C# PDF. En tant que développeur à l'origine de la base de code centrale d'Iron Software, il a façonné l'architecture des produits de l'entreprise depuis sa création, la transformant aux côtés du PDG Cameron Rimington en une entreprise de plus de 50 personnes au service de la NASA, de Tesla et d'agences gouvernementales mondiales.
Articles connexes


