Comment dessiner des lignes et des rectangles sur des PDFs
Le SDK Adobe PDF Library (APDFL) est distribué par Datalogics sous licence d'Adobe et partage le code source principal avec le moteur Acrobat. Il est puissant, mais son modèle de tarification dirigé par les ventes, son empreinte d'exécution native, le manque d'un moteur de rendu HTML intégré et le design de l'API à bas niveau poussent de nombreuses équipes .NET à envisager des alternatives. Ce guide offre un chemin de migration étape par étape du SDK Adobe PDF Library vers IronPDF— une bibliothèque PDF .NET moderne supportant de .NET Framework 4.6.2 à .NET 9.
Pourquoi envisager de passer à une autre solution que le kit de développement logiciel (SDK) Adobe PDF Library ?
Bien que l'APDFL offre le moteur PDF dérivé d'Acrobat, plusieurs facteurs incitent les équipes de développement à explorer des alternatives pour HTML en PDF, la manipulation de documents et la génération de rapports.
Tarification Personnalisée, Dirigée par les Ventes
Datalogics ne publie pas de prix indicatifs pour l'APDFL. Selon les pages de tarification de Datalogics, les plans d'utilisation interne commencent à environ 5 999 $/an, et les déploiements OEM, ISV et SaaS négocient des frais par plateforme en plus des redevances ou du partage des revenus. Le coût total est généralement hors de portée pour les équipes de taille petite à moyenne et nécessite presque toujours une conversation commerciale.
Intégration complexe du SDK natif
L'APDFL encapsule un moteur natif C/C++ qui partage sa lignée avec Acrobat. La liaison .NET (Datalogics.PDFL) nécessite des binaires d'exécution spécifiques à la plateforme — le package NuGet Adobe.PDF.Library.LM.NET livre des charges utiles ARM x64 pour Windows, Linux, et macOS — une gestion attentive de la mémoire, et un cycle de vie explicite Library pour chaque point d'entrée. Cela ajoute de la charge de développement et complique les pipelines CI/CD.
Pas de Rendeur HTML Intégré
La liste de conversion documentée de l'APDFL couvre PDF/A, PDF/X, ZUGFeRD, EPS, PS, XPS, et les formats Office, mais pas HTML. Produire un PDF à partir d'une chaîne HTML avec l'APDFL seul signifie construire manuellement des pages, des polices, et des exécutions de contenu, ou coupler l'APDFL avec un moteur de rendu HTML distinct.
Conception d'API de bas niveau
Créer des PDF avec l'APDFL implique de construire programmétiquement des pages, des flux de contenu, des séries de texte et des polices. Des tâches simples comme le rendu d'une chaîne HTML deviennent des opérations multi-étapes nécessitant des calculs de coordonnées, l'intégration des polices, et la gestion manuelle des éléments de contenu.
Gestion du cycle de vie des bibliothèques : frais généraux
Chaque point d'entrée nécessite d'encadrer le code dans using (var lib = new Library()) (ou des appels appariés Library.Initialize() / Library.Terminate()) avec une élimination attentive de chaque objet PDF créé à l'intérieur. Un nettoyage manqué peut produire des fuites de ressources.
Trop Encombrant pour De Nombreux Projets
Pour les applications ayant principalement besoin de conversion HTML en PDF, de manipulation de document de base ou de génération de rapports, le moteur complet dérivé d'Acrobat est souvent plus que la charge de travail ne nécessite.
Bibliothèque Adobe PDF SDKvs.IronPDF: Principales différences
La compréhension des différences architecturales fondamentales entre ces bibliothèques permet de planifier une stratégie de migration efficace.
| Aspect | Bibliothèque Adobe PDF SDK | IronPDF |
|---|---|---|
| Tarification | Dirigé par les ventes; Usage interne à partir de ~5 999 $/an, redevances OEM/SaaS en supplément | Transparent par développeur / par déploiement |
| Installation | Adobe.PDF.Library.LM.NET envoie des runtimes natifs par plateforme |
Simple Paquet NuGet |
| Création de documents | Construction de pages/contenus de bas niveau | Rendu HTML/CSS |
| HTML à PDF | Non intégré | ChromePdfRenderer.RenderHtmlAsPdf |
| Initialisation | using (Library lib = new Library()) requis |
Automatique |
| Système de coordonnées | Points PostScript, origine en bas à gauche | Mise en page basée sur les CSS |
| Traitement des polices | Intégration manuelle requise | Automatique |
| Gestion de la mémoire | Élimination manuelle de chaque objet PDF | Modèle standard IDisposable |
| Support asynchrone | Non disponible | Prise en charge complète de l'asynchronisme et de l'attente |
Préparation de la migration
Prérequis
Assurez-vous que votre environnement répond à ces exigences avant de commencer la migration :
- .NET Framework 4.6.2+ ou .NET Core 3.1 / .NET 5-9
- Visual Studio 2019+ ou JetBrains Rider
- Accès au Package Manager NuGet
- Clé de licence IronPDF(essai gratuit disponible sur ironpdf.com)
Audit de l'utilisation de la bibliothèque Adobe PDF SDK
Exécutez ces commandes dans votre répertoire de solutions pour identifier toutes les références à Bibliothèque Adobe PDF SDK:
grep -r "using Datalogics" --include="*.cs" .
grep -r "Adobe.PDF.Library" --include="*.csproj" .
grep -r "Library.Initialize\|Library.Terminate" --include="*.cs" .
grep -r "using Datalogics" --include="*.cs" .
grep -r "Adobe.PDF.Library" --include="*.csproj" .
grep -r "Library.Initialize\|Library.Terminate" --include="*.cs" .
Modifications importantes à prévoir
| Catégorie | Bibliothèque Adobe PDF SDK | IronPDF | Action de migration |
|---|---|---|---|
| Initialisation | Library.Initialize() / Terminate() |
Automatique | Supprimer le code du cycle de vie |
| Création de documents | new Document() avec construction de page |
ChromePdfRenderer |
Utiliser le rendu HTML |
| Système de coordonnées | Points PostScript, origine en bas à gauche | Mise en page basée sur les CSS | Utiliser HTML/CSS |
| Traitement des polices | Création et intégration manuelles Font |
Automatique | Supprimer le code de police |
| Gestion de la mémoire | Élimination manuelle des objets COM | IDisposable standard | Utilisez des déclarations using |
| Construction de la page | CreatePage(), AddContent() |
Automatique à partir de HTML | Simplifier considérablement |
Processus de migration étape par étape
Étape 1 : Mise à jour des paquets NuGet
Supprimez le kit SDK de la bibliothèque Adobe PDF et installez IronPDF:
# Remove Adobe PDF Library (.NET 6/7/8 projects)
dotnet remove package Adobe.PDF.Library.LM.NET
# .NET Framework projects use the LM.NETFramework variant
dotnet remove package Adobe.PDF.Library.LM.NETFramework
# Install IronPDF
dotnet add package IronPdf
# Remove Adobe PDF Library (.NET 6/7/8 projects)
dotnet remove package Adobe.PDF.Library.LM.NET
# .NET Framework projects use the LM.NETFramework variant
dotnet remove package Adobe.PDF.Library.LM.NETFramework
# Install IronPDF
dotnet add package IronPdf
Étape 2 : configuration de la clé de licence
Remplacez la licence Adobe par la clé de licence IronPDF basée sur le code :
// Replace Adobe's Library.LicenseKey with IronPDF license
// Add at application startup, before any IronPDF operations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Verify license status
bool isLicensed = IronPdf.License.IsLicensed;
// Replace Adobe's Library.LicenseKey with IronPDF license
// Add at application startup, before any IronPDF operations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Verify license status
bool isLicensed = IronPdf.License.IsLicensed;
' Replace Adobe's Library.LicenseKey with IronPDF license
' Add at application startup, before any IronPDF operations
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
' Verify license status
Dim isLicensed As Boolean = IronPdf.License.IsLicensed
Étape 3 : mise à jour des références aux espaces de noms
Effectuez une recherche et un remplacement globaux dans votre solution :
| Recherche | Remplacer par |
|---|---|
using Datalogics.PDFL; |
using IronPdf; |
APDFL expose un seul espace de noms racine, Datalogics.PDFL. Document, Page, Content, Font, et Color sont toutes des classes à l'intérieur de cet espace de noms, donc il y a juste une directive using à échanger.
Etape 4 : Supprimer le code du cycle de vie de la bibliothèque
L'une des simplifications les plus importantes consiste à supprimer les modèles d'initialisation et de terminaison :
// Bibliothèque Adobe PDF SDK- REMOVE THIS PATTERN
Library.Initialize();
try
{
// PDF operations
}
finally
{
Library.Terminate(); // Must always terminate
}
//IronPDF- Just use directly
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Bibliothèque Adobe PDF SDK- REMOVE THIS PATTERN
Library.Initialize();
try
{
// PDF operations
}
finally
{
Library.Terminate(); // Must always terminate
}
//IronPDF- Just use directly
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
Imports IronPdf
' Bibliothèque Adobe PDF SDK- REMOVE THIS PATTERN
Library.Initialize()
Try
' PDF operations
Finally
Library.Terminate() ' Must always terminate
End Try
' IronPDF- Just use directly
Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
Référence complète de migration des API
Méthodes de cycle de vie des bibliothèques
| Méthode Adobe | Équivalent d'IronPDF |
|---|---|
Library.Initialize() |
Pas nécessaire |
Library.Terminate() |
Pas nécessaire |
Library.LicenseKey = "KEY" |
IronPdf.License.LicenseKey = "KEY" |
using (Library lib = new Library()) |
Pas nécessaire |
Méthodes de création de documents
| Méthode Adobe | Méthode IronPDF |
|---|---|
new Document() |
new ChromePdfRenderer() |
new Document(path) |
PdfDocument.FromFile(path) |
doc.CreatePage(index, rect) |
Automatique à partir de HTML |
doc.Save(SaveFlags.Full, path) |
pdf.SaveAs(path) |
doc.NumPages |
pdf.PageCount |
doc.GetPage(index) |
pdf.Pages[index] |
doc.InsertPages(insertAfter, src, start, count, flags) |
PdfDocument.Merge(pdfs) |
Création de contenu (changement de paradigme majeur)
Adobe PDF Library SDK nécessite une construction de contenu de bas niveau.IronPDF utilise HTML/CSS :
| Méthode Adobe | Méthode IronPDF |
|---|---|
new Text() |
Utilisez HTML <p>, <h1>, etc. |
text.AddRun(textRun) |
Utiliser HTML |
new TextRun(text, font, size, point) |
Style CSS |
new Font(name, flags) |
CSS font-family |
new Image(path) |
Balise HTML <img> |
content.AddElement(...) |
Contenu HTML |
page.UpdateContent() |
Pas nécessaire |
Filigrane et méthodes de sécurité
| Méthode Adobe | Méthode IronPDF |
|---|---|
doc.Watermark(textParams, wmParams) |
pdf.ApplyWatermark(html) |
WatermarkParams.Opacity (0.0-1.0) |
Paramètre opacity (0-100) ou CSS opacity |
new EncryptionHandler(user, owner, perms) |
pdf.SecuritySettings |
PermissionFlags.PrintDoc |
AllowUserPrinting |
Extraction de texte
| Méthode Adobe | Méthode IronPDF |
|---|---|
new WordFinder(doc, config) |
pdf.ExtractAllText() |
wordFinder.GetWordList() |
pdf.Pages[i].Text |
| Itération de mots/caractères complexes | Appel de méthode unique |
Exemples de migration de code
Conversion HTML en PDF
L'APDFL ne dispose pas d'un meneur HTML intégré. Le plus proche équivalent consiste à construire des pages et des exécutions de contenu à la main pour imiter le layout qu'un document HTML produirait - ou à coupler l'APDFL avec un moteur HTML-to-PDF distinct.
Mise en œuvre de la bibliothèque SDK d'Adobe PDF:
// Bibliothèque Adobe PDF SDK(Datalogics APDFL)
// NuGet: Adobe.PDF.Library.LM.NET — namespace Datalogics.PDFL
using Datalogics.PDFL;
using System;
class AdobeHtmlToPdf
{
static void Main()
{
using (Library lib = new Library())
using (Document doc = new Document())
{
// US Letter in points (8.5 x 11 inches @ 72 DPI)
Rect pageRect = new Rect(0, 0, 612, 792);
using (Page page = doc.CreatePage(Document.BeforeFirstPage, pageRect))
{
Content content = page.Content;
Font font = new Font("Helvetica", FontCreateFlags.Embedded);
Text text = new Text();
text.AddRun(new TextRun("Hello World", font, 24, new Point(72, 720)));
content.AddElement(text);
page.UpdateContent();
}
doc.Save(SaveFlags.Full, "output.pdf");
}
}
}
// Bibliothèque Adobe PDF SDK(Datalogics APDFL)
// NuGet: Adobe.PDF.Library.LM.NET — namespace Datalogics.PDFL
using Datalogics.PDFL;
using System;
class AdobeHtmlToPdf
{
static void Main()
{
using (Library lib = new Library())
using (Document doc = new Document())
{
// US Letter in points (8.5 x 11 inches @ 72 DPI)
Rect pageRect = new Rect(0, 0, 612, 792);
using (Page page = doc.CreatePage(Document.BeforeFirstPage, pageRect))
{
Content content = page.Content;
Font font = new Font("Helvetica", FontCreateFlags.Embedded);
Text text = new Text();
text.AddRun(new TextRun("Hello World", font, 24, new Point(72, 720)));
content.AddElement(text);
page.UpdateContent();
}
doc.Save(SaveFlags.Full, "output.pdf");
}
}
}
Imports Datalogics.PDFL
Imports System
Class AdobeHtmlToPdf
Shared Sub Main()
Using lib As New Library()
Using doc As New Document()
' US Letter in points (8.5 x 11 inches @ 72 DPI)
Dim pageRect As New Rect(0, 0, 612, 792)
Using page As Page = doc.CreatePage(Document.BeforeFirstPage, pageRect)
Dim content As Content = page.Content
Dim font As New Font("Helvetica", FontCreateFlags.Embedded)
Dim text As New Text()
text.AddRun(New TextRun("Hello World", font, 24, New Point(72, 720)))
content.AddElement(text)
page.UpdateContent()
End Using
doc.Save(SaveFlags.Full, "output.pdf")
End Using
End Using
End Sub
End Class
Mise en œuvre d'IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfHtmlToPdf
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
// Convert HTML to PDF with simple API
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfHtmlToPdf
{
static void Main()
{
var renderer = new ChromePdfRenderer();
string htmlContent = "<html><body><h1>Hello World</h1></body></html>";
// Convert HTML to PDF with simple API
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}
Imports IronPdf
Imports System
Class IronPdfHtmlToPdf
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"
' Convert HTML to PDF with simple API
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
End Sub
End Class
IronPDF élimine l'enveloppe du cycle de vie de la bibliothèque, les objets de paramètres de conversion et l'élimination explicite. Le ChromePdfRenderer utilise un moteur basé sur Chromium pour un support CSS et JavaScript au pixel près. Pour les scénarios avancés, consultez la documentation HTML vers PDF.
Fusionner plusieurs fichiers PDF
La fusion des PDF montre clairement la différence de complexité des API.
Mise en œuvre de la bibliothèque SDK d'Adobe PDF:
// Bibliothèque Adobe PDF SDK(Datalogics APDFL)
using Datalogics.PDFL;
using System;
class AdobeMergePdfs
{
static void Main()
{
using (Library lib = new Library())
using (Document doc1 = new Document("document1.pdf"))
using (Document doc2 = new Document("document2.pdf"))
{
// InsertPages(insertAfter, sourceDoc, sourceStartPage, pageCount, flags)
doc1.InsertPages(
Document.LastPage,
doc2,
0,
Document.AllPages,
PageInsertFlags.Bookmarks | PageInsertFlags.Threads);
doc1.Save(SaveFlags.Full, "merged.pdf");
}
}
}
// Bibliothèque Adobe PDF SDK(Datalogics APDFL)
using Datalogics.PDFL;
using System;
class AdobeMergePdfs
{
static void Main()
{
using (Library lib = new Library())
using (Document doc1 = new Document("document1.pdf"))
using (Document doc2 = new Document("document2.pdf"))
{
// InsertPages(insertAfter, sourceDoc, sourceStartPage, pageCount, flags)
doc1.InsertPages(
Document.LastPage,
doc2,
0,
Document.AllPages,
PageInsertFlags.Bookmarks | PageInsertFlags.Threads);
doc1.Save(SaveFlags.Full, "merged.pdf");
}
}
}
Imports Datalogics.PDFL
Imports System
Class AdobeMergePdfs
Shared Sub Main()
Using lib As New Library()
Using doc1 As New Document("document1.pdf")
Using doc2 As New Document("document2.pdf")
' InsertPages(insertAfter, sourceDoc, sourceStartPage, pageCount, flags)
doc1.InsertPages(Document.LastPage, doc2, 0, Document.AllPages, PageInsertFlags.Bookmarks Or PageInsertFlags.Threads)
doc1.Save(SaveFlags.Full, "merged.pdf")
End Using
End Using
End Using
End Sub
End Class
Mise en œuvre d'IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfMergePdfs
{
static void Main()
{
// Load PDF documents
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
// Merge PDFs with simple method
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
class IronPdfMergePdfs
{
static void Main()
{
// Load PDF documents
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
// Merge PDFs with simple method
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}
Imports IronPdf
Imports System
Class IronPdfMergePdfs
Shared Sub Main()
' Load PDF documents
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
' Merge PDFs with simple method
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")
End Sub
End Class
L'approche d'Adobe nécessite une itération page par page avec des paramètres d'insertion.IronPDF fournit une méthode Merge unique qui accepte plusieurs documents.
Ajouter des filigranes
Le filigrane illustre la façon dont IronPDF tire parti de HTML/CSS pour la flexibilité du style.
Mise en œuvre de la bibliothèque SDK d'Adobe PDF:
// Bibliothèque Adobe PDF SDK(Datalogics APDFL)
using Datalogics.PDFL;
using System;
class AdobeAddWatermark
{
static void Main()
{
using (Library lib = new Library())
using (Document doc = new Document("input.pdf"))
{
WatermarkParams watermarkParams = new WatermarkParams();
watermarkParams.Opacity = 0.5; // 0.0 - 1.0
watermarkParams.Rotation = 45.0;
watermarkParams.Scale = -1; // auto-fit
WatermarkTextParams textParams = new WatermarkTextParams();
textParams.Text = "CONFIDENTIAL";
textParams.Color = new Color(0.8, 0.8, 0.8);
textParams.TextAlign = HorizontalAlignment.Center;
// Apply via Document.Watermark(textParams, wmParams)
doc.Watermark(textParams, watermarkParams);
doc.Save(SaveFlags.Full, "watermarked.pdf");
}
}
}
// Bibliothèque Adobe PDF SDK(Datalogics APDFL)
using Datalogics.PDFL;
using System;
class AdobeAddWatermark
{
static void Main()
{
using (Library lib = new Library())
using (Document doc = new Document("input.pdf"))
{
WatermarkParams watermarkParams = new WatermarkParams();
watermarkParams.Opacity = 0.5; // 0.0 - 1.0
watermarkParams.Rotation = 45.0;
watermarkParams.Scale = -1; // auto-fit
WatermarkTextParams textParams = new WatermarkTextParams();
textParams.Text = "CONFIDENTIAL";
textParams.Color = new Color(0.8, 0.8, 0.8);
textParams.TextAlign = HorizontalAlignment.Center;
// Apply via Document.Watermark(textParams, wmParams)
doc.Watermark(textParams, watermarkParams);
doc.Save(SaveFlags.Full, "watermarked.pdf");
}
}
}
Imports Datalogics.PDFL
Imports System
Class AdobeAddWatermark
Shared Sub Main()
Using lib As New Library()
Using doc As New Document("input.pdf")
Dim watermarkParams As New WatermarkParams()
watermarkParams.Opacity = 0.5 ' 0.0 - 1.0
watermarkParams.Rotation = 45.0
watermarkParams.Scale = -1 ' auto-fit
Dim textParams As New WatermarkTextParams()
textParams.Text = "CONFIDENTIAL"
textParams.Color = New Color(0.8, 0.8, 0.8)
textParams.TextAlign = HorizontalAlignment.Center
' Apply via Document.Watermark(textParams, wmParams)
doc.Watermark(textParams, watermarkParams)
doc.Save(SaveFlags.Full, "watermarked.pdf")
End Using
End Using
End Sub
End Class
Mise en œuvre d'IronPDF:
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
using System;
class IronPdfAddWatermark
{
static void Main()
{
var pdf = PdfDocument.FromFile("input.pdf");
// Apply text watermark with simple API
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.5;'>CONFIDENTIAL</h1>",
rotation: 45,
verticalAlignment: VerticalAlignment.Middle,
horizontalAlignment: HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");
}
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
using System;
class IronPdfAddWatermark
{
static void Main()
{
var pdf = PdfDocument.FromFile("input.pdf");
// Apply text watermark with simple API
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.5;'>CONFIDENTIAL</h1>",
rotation: 45,
verticalAlignment: VerticalAlignment.Middle,
horizontalAlignment: HorizontalAlignment.Center);
pdf.SaveAs("watermarked.pdf");
}
}
Imports IronPdf
Imports IronPdf.Editing
Imports System
Class IronPdfAddWatermark
Shared Sub Main()
Dim pdf = PdfDocument.FromFile("input.pdf")
' Apply text watermark with simple API
pdf.ApplyWatermark("<h1 style='color:red; opacity:0.5;'>CONFIDENTIAL</h1>",
rotation:=45,
verticalAlignment:=VerticalAlignment.Middle,
horizontalAlignment:=HorizontalAlignment.Center)
pdf.SaveAs("watermarked.pdf")
End Sub
End Class
Le filigrane basé sur HTML d'IronPDF permet un contrôle complet de la conception grâce au style CSS, ce qui élimine le besoin d'objets de paramètres distincts.
Protection et chiffrement des mots de passe
Mise en œuvre de la bibliothèque SDK d'Adobe PDF:
using Datalogics.PDFL;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
Library.Initialize();
try
{
using (Document doc = new Document(inputPath))
{
PermissionFlags permissions =
PermissionFlags.PrintDoc |
PermissionFlags.PrintFidelity;
EncryptionHandler encHandler = new EncryptionHandler(
password, // User password
password, // Owner password
permissions,
EncryptionMethod.AES256);
doc.SetEncryptionHandler(encHandler);
doc.Save(SaveFlags.Full | SaveFlags.Encrypted, outputPath);
}
}
finally
{
Library.Terminate();
}
}
using Datalogics.PDFL;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
Library.Initialize();
try
{
using (Document doc = new Document(inputPath))
{
PermissionFlags permissions =
PermissionFlags.PrintDoc |
PermissionFlags.PrintFidelity;
EncryptionHandler encHandler = new EncryptionHandler(
password, // User password
password, // Owner password
permissions,
EncryptionMethod.AES256);
doc.SetEncryptionHandler(encHandler);
doc.Save(SaveFlags.Full | SaveFlags.Encrypted, outputPath);
}
}
finally
{
Library.Terminate();
}
}
Imports Datalogics.PDFL
Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
Library.Initialize()
Try
Using doc As New Document(inputPath)
Dim permissions As PermissionFlags = PermissionFlags.PrintDoc Or PermissionFlags.PrintFidelity
Dim encHandler As New EncryptionHandler(
password, ' User password
password, ' Owner password
permissions,
EncryptionMethod.AES256)
doc.SetEncryptionHandler(encHandler)
doc.Save(SaveFlags.Full Or SaveFlags.Encrypted, outputPath)
End Using
Finally
Library.Terminate()
End Try
End Sub
Mise en œuvre d'IronPDF:
using IronPdf;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.SecuritySettings.UserPassword = password;
pdf.SecuritySettings.OwnerPassword = password;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs(outputPath);
}
using IronPdf;
public void ProtectPdf(string inputPath, string outputPath, string password)
{
using var pdf = PdfDocument.FromFile(inputPath);
pdf.SecuritySettings.UserPassword = password;
pdf.SecuritySettings.OwnerPassword = password;
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub ProtectPdf(inputPath As String, outputPath As String, password As String)
Using pdf = PdfDocument.FromFile(inputPath)
pdf.SecuritySettings.UserPassword = password
pdf.SecuritySettings.OwnerPassword = password
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
pdf.SecuritySettings.AllowUserCopyPasteContent = False
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit
pdf.SaveAs(outputPath)
End Using
End Sub
IronPDF utilise des propriétés fortement typées au lieu de drapeaux de permission en bits et d'objets de gestion du chiffrement.
Extraction de texte
Mise en œuvre de la bibliothèque SDK d'Adobe PDF:
using Datalogics.PDFL;
public string ExtractText(string pdfPath)
{
string extractedText = "";
Library.Initialize();
try
{
using (Document doc = new Document(pdfPath))
{
WordFinderConfig config = new WordFinderConfig();
config.IgnoreCharGaps = true;
for (int i = 0; i < doc.NumPages; i++)
{
using (WordFinder wordFinder = new WordFinder(doc, i, config))
{
IList<Word> words = wordFinder.GetWordList();
foreach (Word word in words)
{
extractedText += word.Text + " ";
}
extractedText += "\n";
}
}
}
}
finally
{
Library.Terminate();
}
return extractedText;
}
using Datalogics.PDFL;
public string ExtractText(string pdfPath)
{
string extractedText = "";
Library.Initialize();
try
{
using (Document doc = new Document(pdfPath))
{
WordFinderConfig config = new WordFinderConfig();
config.IgnoreCharGaps = true;
for (int i = 0; i < doc.NumPages; i++)
{
using (WordFinder wordFinder = new WordFinder(doc, i, config))
{
IList<Word> words = wordFinder.GetWordList();
foreach (Word word in words)
{
extractedText += word.Text + " ";
}
extractedText += "\n";
}
}
}
}
finally
{
Library.Terminate();
}
return extractedText;
}
Imports Datalogics.PDFL
Public Function ExtractText(ByVal pdfPath As String) As String
Dim extractedText As String = ""
Library.Initialize()
Try
Using doc As New Document(pdfPath)
Dim config As New WordFinderConfig()
config.IgnoreCharGaps = True
For i As Integer = 0 To doc.NumPages - 1
Using wordFinder As New WordFinder(doc, i, config)
Dim words As IList(Of Word) = wordFinder.GetWordList()
For Each word As Word In words
extractedText &= word.Text & " "
Next
extractedText &= vbLf
End Using
Next
End Using
Finally
Library.Terminate()
End Try
Return extractedText
End Function
Mise en œuvre d'IronPDF:
using IronPdf;
public string ExtractText(string pdfPath)
{
using var pdf = PdfDocument.FromFile(pdfPath);
return pdf.ExtractAllText();
}
using IronPdf;
public string ExtractText(string pdfPath)
{
using var pdf = PdfDocument.FromFile(pdfPath);
return pdf.ExtractAllText();
}
Imports IronPdf
Public Function ExtractText(pdfPath As String) As String
Using pdf = PdfDocument.FromFile(pdfPath)
Return pdf.ExtractAllText()
End Using
End Function
L'itération mot à mot d'Adobe se transforme en un simple appel de méthode avec IronPDF.
En-têtes et pieds de page
Mise en œuvre de la bibliothèque SDK d'Adobe PDF:
using Datalogics.PDFL;
public void AddHeaderFooter(string inputPath, string outputPath)
{
Library.Initialize();
try
{
using (Document doc = new Document(inputPath))
{
Font font = new Font("Helvetica", FontCreateFlags.None);
for (int i = 0; i < doc.NumPages; i++)
{
using (Page page = doc.GetPage(i))
{
Content content = page.Content;
// Add header
Text header = new Text();
header.AddRun(new TextRun("Document Header",
font, 10, new Point(72, page.MediaBox.Top - 36)));
content.AddElement(header);
// Add footer with page number
Text footer = new Text();
footer.AddRun(new TextRun($"Page {i + 1} of {doc.NumPages}",
font, 10, new Point(72, 36)));
content.AddElement(footer);
page.UpdateContent();
}
}
doc.Save(SaveFlags.Full, outputPath);
}
}
finally
{
Library.Terminate();
}
}
using Datalogics.PDFL;
public void AddHeaderFooter(string inputPath, string outputPath)
{
Library.Initialize();
try
{
using (Document doc = new Document(inputPath))
{
Font font = new Font("Helvetica", FontCreateFlags.None);
for (int i = 0; i < doc.NumPages; i++)
{
using (Page page = doc.GetPage(i))
{
Content content = page.Content;
// Add header
Text header = new Text();
header.AddRun(new TextRun("Document Header",
font, 10, new Point(72, page.MediaBox.Top - 36)));
content.AddElement(header);
// Add footer with page number
Text footer = new Text();
footer.AddRun(new TextRun($"Page {i + 1} of {doc.NumPages}",
font, 10, new Point(72, 36)));
content.AddElement(footer);
page.UpdateContent();
}
}
doc.Save(SaveFlags.Full, outputPath);
}
}
finally
{
Library.Terminate();
}
}
Imports Datalogics.PDFL
Public Sub AddHeaderFooter(inputPath As String, outputPath As String)
Library.Initialize()
Try
Using doc As New Document(inputPath)
Dim font As New Font("Helvetica", FontCreateFlags.None)
For i As Integer = 0 To doc.NumPages - 1
Using page As Page = doc.GetPage(i)
Dim content As Content = page.Content
' Add header
Dim header As New Text()
header.AddRun(New TextRun("Document Header", font, 10, New Point(72, page.MediaBox.Top - 36)))
content.AddElement(header)
' Add footer with page number
Dim footer As New Text()
footer.AddRun(New TextRun($"Page {i + 1} of {doc.NumPages}", font, 10, New Point(72, 36)))
content.AddElement(footer)
page.UpdateContent()
End Using
Next
doc.Save(SaveFlags.Full, outputPath)
End Using
Finally
Library.Terminate()
End Try
End Sub
Mise en œuvre d'IronPDF:
using IronPdf;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Document Header",
FontSize = 10,
FontFamily = "Helvetica"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10,
FontFamily = "Helvetica"
};
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void CreatePdfWithHeaderFooter(string html, string outputPath)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Document Header",
FontSize = 10,
FontFamily = "Helvetica"
};
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "Page {page} of {total-pages}",
FontSize = 10,
FontFamily = "Helvetica"
};
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub CreatePdfWithHeaderFooter(html As String, outputPath As String)
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "Document Header",
.FontSize = 10,
.FontFamily = "Helvetica"
}
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.CenterText = "Page {page} of {total-pages}",
.FontSize = 10,
.FontFamily = "Helvetica"
}
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs(outputPath)
End Using
End Sub
IronPDF gère automatiquement l'itération des pages et supporte les jetons de type {page} et {total-pages}. Pour des mises en page plus avancées, consultez la documentation sur les en-têtes et les pieds de page.
Conversion d'URL en PDF
Adobe PDF Library SDK n'intègre pas de fonction de rendu d'URL.IronPDF assure la prise en charge native :
using IronPdf;
public void ConvertUrlToPdf(string url, string outputPath)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs(outputPath);
}
using IronPdf;
public void ConvertUrlToPdf(string url, string outputPath)
{
var renderer = new ChromePdfRenderer();
using var pdf = renderer.RenderUrlAsPdf(url);
pdf.SaveAs(outputPath);
}
Imports IronPdf
Public Sub ConvertUrlToPdf(url As String, outputPath As String)
Dim renderer As New ChromePdfRenderer()
Using pdf = renderer.RenderUrlAsPdf(url)
pdf.SaveAs(outputPath)
End Using
End Sub
Pour connaître l'ensemble des options de conversion d'URL, consultez la documentation sur les URL au format PDF.
Intégration d'ASP.NET Core
Le modèle d'initialisation statique d'Adobe PDF Library SDK crée des frictions avec l'injection de dépendances.IronPDFs'intègre naturellement aux architectures .NET modernes.
Adobe Pattern (problématique pour DI):
public class AdobePdfService
{
public byte[] Generate(string content)
{
Library.Initialize();
try
{
// Document complexeconstruction...
return bytes;
}
finally
{
Library.Terminate();
}
}
}
public class AdobePdfService
{
public byte[] Generate(string content)
{
Library.Initialize();
try
{
// Document complexeconstruction...
return bytes;
}
finally
{
Library.Terminate();
}
}
}
Public Class AdobePdfService
Public Function Generate(content As String) As Byte()
Library.Initialize()
Try
' Document complex construction...
Return bytes
Finally
Library.Terminate()
End Try
End Function
End Class
Modèle IronPDF(DI-Friendly):
public interface IPdfService
{
Task<byte[]> GeneratePdfAsync(string html);
}
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
}
// Register in Program.cs (.NET 6+):
builder.Services.AddSingleton<IPdfService, IronPdfService>();
public interface IPdfService
{
Task<byte[]> GeneratePdfAsync(string html);
}
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public async Task<byte[]> GeneratePdfAsync(string html)
{
using var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
return pdf.BinaryData;
}
}
// Register in Program.cs (.NET 6+):
builder.Services.AddSingleton<IPdfService, IronPdfService>();
Imports System.Threading.Tasks
Public Interface IPdfService
Function GeneratePdfAsync(html As String) As Task(Of Byte())
End Interface
Public Class IronPdfService
Implements IPdfService
Private ReadOnly _renderer As ChromePdfRenderer
Public Sub New()
_renderer = New ChromePdfRenderer()
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
End Sub
Public Async Function GeneratePdfAsync(html As String) As Task(Of Byte()) Implements IPdfService.GeneratePdfAsync
Using pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
Return pdf.BinaryData
End Using
End Function
End Class
' Register in Program.vb (.NET 6+):
builder.Services.AddSingleton(Of IPdfService, IronPdfService)()
Support asynchrone
Adobe PDF Library SDK ne prend pas en charge les opérations asynchrones.IronPDF offre des fonctionnalités asynchrones/await complètes, essentielles pour les applications web évolutives :
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
Imports System.Threading.Tasks
Imports Microsoft.AspNetCore.Mvc
Public Class ReportController
Inherits Controller
Public Async Function GenerateReport() As Task(Of IActionResult)
Dim renderer As New ChromePdfRenderer()
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return File(pdf.BinaryData, "application/pdf")
End Using
End Function
End Class
Optimisation des performances
Comparaison de l'utilisation de la mémoire
| Scénario | Bibliothèque Adobe PDF SDK | IronPDF |
|---|---|---|
| PDF simple | ~100 MB | ~50 MB |
| Document complexe | ~200 MB | ~80 MB |
| Lot (100 PDF) | Haut (mémoire native) | ~100 MB |
Conseils d'optimisation
Réutiliser les instances de rendu :
// Good: Reuse renderer for batch operations
var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{i}.pdf");
}
// Good: Reuse renderer for batch operations
var renderer = new ChromePdfRenderer();
foreach (var html in htmlList)
{
using var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs($"output_{i}.pdf");
}
' Good: Reuse renderer for batch operations
Dim renderer = New ChromePdfRenderer()
For Each html In htmlList
Using pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs($"output_{i}.pdf")
End Using
Next
Utiliser Async dans les applications Web:
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
public async Task<IActionResult> GenerateReport()
{
var renderer = new ChromePdfRenderer();
using var pdf = await renderer.RenderHtmlAsPdfAsync(html);
return File(pdf.BinaryData, "application/pdf");
}
Imports System.Threading.Tasks
Imports Microsoft.AspNetCore.Mvc
Public Class ReportController
Inherits Controller
Public Async Function GenerateReport() As Task(Of IActionResult)
Dim renderer As New ChromePdfRenderer()
Using pdf = Await renderer.RenderHtmlAsPdfAsync(html)
Return File(pdf.BinaryData, "application/pdf")
End Using
End Function
End Class
Dépannage des problèmes de migration courants
Sujet : Le positionnement par coordonnées ne fonctionne pas
Adobe utilise les coordonnées de points PostScript.IronPDF utilise le positionnement CSS :
// Adobe: Point-based
new TextRun("Hello", font, 12, new Point(100, 700));
// IronPDF: CSS-based
string html = "<p style='position:absolute; left:100px; top:92px;'>Hello</p>";
// Adobe: Point-based
new TextRun("Hello", font, 12, new Point(100, 700));
// IronPDF: CSS-based
string html = "<p style='position:absolute; left:100px; top:92px;'>Hello</p>";
' Adobe: Point-based
New TextRun("Hello", font, 12, New Point(100, 700))
' IronPDF: CSS-based
Dim html As String = "<p style='position:absolute; left:100px; top:92px;'>Hello</p>"
Sujet : Différences de taille de page
Adobe utilise des points PostScript.IronPDF utilise des enums ou des dimensions personnalisées :
// Adobe: Points
Rect(0, 0, 612, 792) // Letter
// IronPDF: Enum or custom
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom:
renderer.RenderingOptions.SetCustomPaperSizeInInches(8.5, 11);
// Adobe: Points
Rect(0, 0, 612, 792) // Letter
// IronPDF: Enum or custom
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
// Or custom:
renderer.RenderingOptions.SetCustomPaperSizeInInches(8.5, 11);
' Adobe: Points
Rect(0, 0, 612, 792) ' Letter
' IronPDF: Enum or custom
renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
' Or custom:
renderer.RenderingOptions.SetCustomPaperSizeInInches(8.5, 11)
Problème : Police introuvable
Adobe exige l'intégration manuelle des polices.IronPDF gère automatiquement les polices de caractères :
// IronPDF: Use web fonts if needed
string html = @"
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', sans-serif; }
</style>";
// IronPDF: Use web fonts if needed
string html = @"
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', sans-serif; }
</style>";
' IronPDF: Use web fonts if needed
Dim html As String = "
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body { font-family: 'Roboto', sans-serif; }
</style>"
Sujet : SaveFlags non disponible
Adobe utilise des combinaisons de drapeaux de sauvegarde.IronPDF utilise l'enregistrement direct :
// Adobe
doc.Save(SaveFlags.Full | SaveFlags.Incremental, path);
//IronPDF- full save is default
pdf.SaveAs(path);
// Adobe
doc.Save(SaveFlags.Full | SaveFlags.Incremental, path);
//IronPDF- full save is default
pdf.SaveAs(path);
Liste de contrôle post-migration
Après avoir effectué la migration du code, vérifiez les points suivants :
- Exécuter tous les tests unitaires et d'intégration existants
- Comparer visuellement les fichiers PDF générés avec les versions précédentes
- Tester tous les flux de travail PDF dans un environnement de test
- Vérifiez que la licence fonctionne correctement (
IronPdf.License.IsLicensed) - Évaluation comparative des performances par rapport à l'implémentation précédente
- Supprimer la configuration de licence Adobe
- Mettre à jour les dépendances du pipeline CI/CD
- Supprimez toutes les DLL de la bibliothèque Adobe PDF du projet
- Documentez les nouveaux modèles pour votre équipe de développement
Ressources supplémentaires
Passer de l'APDFL à IronPDF peut simplifier la base de code typique de génération de PDF en .NET, notamment pour les équipes dont le besoin principal est la conversion HTML en PDF ou la manipulation de documents plutôt que la surface complète des fonctionnalités dérivées d'Acrobat. Le passage de la construction de pages à bas niveau au rendu HTML/CSS élimine la plupart des calculs de coordonnées, de la gestion des polices, et du code de gestion du cycle de vie Library, et la licence transparente d'IronPDF par développeur est généralement plus facile à budgétiser que le modèle basé sur les ventes, OEM/SaaS-royalty d'APDFL.

