How to Migrate from Adobe PDF Library SDK to IronPDF
The Adobe PDF Library SDK (APDFL) is distributed by Datalogics under license from Adobe and shares core source code with the Acrobat engine. It is powerful, but its sales-led pricing model, native runtime footprint, lack of a built-in HTML-to-PDF renderer, and low-level API design lead many .NET teams to look at alternatives. This guide offers a step-by-step migration path from Adobe PDF Library SDK to IronPDF — a modern .NET PDF library supporting .NET Framework 4.6.2 through .NET 9.
Why Consider Moving Away from Adobe PDF Library SDK?
While APDFL offers the Acrobat-derived PDF engine, several factors lead development teams to explore alternatives for HTML-to-PDF, document manipulation, and report generation.
Sales-Led, Bespoke Pricing
Datalogics does not publish list pricing for APDFL. Per Datalogics' pricing pages, internal-use plans start around $5,999/year, and OEM, ISV, and SaaS deployments negotiate per-platform fees plus royalties or revenue-share on top. The total cost is typically out of reach for small to mid-sized teams and almost always requires a sales conversation.
Complex Native SDK Integration
APDFL wraps a native C/C++ engine that shares lineage with Acrobat. The .NET binding (Datalogics.PDFL) requires platform-specific runtime binaries — the Adobe.PDF.Library.LM.NET NuGet package ships x64 Windows, Linux, and macOS ARM payloads — careful memory management, and an explicit Library lifecycle on every entry point. This adds development overhead and complicates CI/CD pipelines.
No Built-in HTML Renderer
APDFL's documented conversion list covers PDF/A, PDF/X, ZUGFeRD, EPS, PS, XPS, and Office formats, but not HTML. Producing a PDF from an HTML string with APDFL alone means hand-building pages, fonts, and content runs, or pairing APDFL with a separate HTML rendering engine.
Low-Level API Design
Creating PDFs with APDFL involves constructing pages, content streams, text runs, and fonts programmatically. Simple tasks like rendering an HTML string become multi-step operations involving coordinate calculations, font embedding, and manual content element management.
Library Lifecycle Management Overhead
Every entry point requires wrapping code in using (var lib = new Library()) (or paired Library.Initialize() / Library.Terminate() calls) with careful disposal of every PDF object created inside. Missed cleanup can produce resource leaks.
Overkill for Many Projects
For applications primarily needing HTML-to-PDF conversion, basic document manipulation, or report generation, the full Acrobat-derived engine is often more than the workload requires.
Adobe PDF Library SDK vs. IronPDF: Key Differences
Understanding the fundamental architectural differences between these libraries helps plan an effective migration strategy.
| Aspect | Adobe PDF Library SDK | IronPDF |
|---|---|---|
| Pricing | Sales-led; internal-use from ~$5,999/year, OEM/SaaS royalties on top | Transparent per-developer / per-deployment |
| Installation | Adobe.PDF.Library.LM.NET ships native runtimes per platform |
Simple NuGet package |
| Document Creation | Low-level page/content construction | HTML/CSS rendering |
| HTML to PDF | Not built-in | ChromePdfRenderer.RenderHtmlAsPdf |
| Initialization | using (Library lib = new Library()) required |
Automatic |
| Coordinate System | PostScript points, bottom-left origin | CSS-based layout |
| Font Handling | Manual embedding required | Automatic |
| Memory Management | Manual disposal of every PDF object | Standard IDisposable pattern |
| Async Support | Not available | Full async/await support |
Pre-Migration Preparation
Prerequisites
Ensure your environment meets these requirements before beginning migration:
- .NET Framework 4.6.2+ or .NET Core 3.1 / .NET 5-9
- Visual Studio 2019+ or JetBrains Rider
- NuGet Package Manager access
- IronPDF license key (free trial available at ironpdf.com)
Audit Adobe PDF Library SDK Usage
Run these commands in your solution directory to identify all Adobe PDF Library SDK references:
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" .
Breaking Changes to Anticipate
| Category | Adobe PDF Library SDK | IronPDF | Migration Action |
|---|---|---|---|
| Initialization | Library.Initialize() / Terminate() |
Automatic | Remove lifecycle code |
| Document Creation | new Document() with page construction |
ChromePdfRenderer |
Use HTML rendering |
| Coordinate System | PostScript points, bottom-left origin | CSS-based layout | Use HTML/CSS |
| Font Handling | Manual Font creation and embedding |
Automatic | Remove font code |
| Memory Management | Manual disposal of COM objects | Standard IDisposable | Use using statements |
| Page Construction | CreatePage(), AddContent() |
Automatic from HTML | Simplify significantly |
Step-by-Step Migration Process
Step 1: Update NuGet Packages
Remove the Adobe PDF Library SDK package and install 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
Step 2: Configure the License Key
Replace Adobe's licensing with IronPDF's code-based license key:
// 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
Step 3: Update Namespace References
Perform a global find-and-replace across your solution:
| Find | Replace With |
|---|---|
using Datalogics.PDFL; |
using IronPdf; |
APDFL exposes a single root namespace, Datalogics.PDFL. Document, Page, Content, Font, and Color are all classes inside that namespace, so there is just one using directive to swap.
Step 4: Remove Library Lifecycle Code
One of the most significant simplifications involves removing initialization and termination patterns:
// Adobe PDF Library 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);
// Adobe PDF Library 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 AdobePDFLibrary
Imports IronPdf
' Adobe PDF Library 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)
Complete API Migration Reference
Library Lifecycle Methods
| Adobe Method | IronPDF Equivalent |
|---|---|
Library.Initialize() |
Not needed |
Library.Terminate() |
Not needed |
Library.LicenseKey = "KEY" |
IronPdf.License.LicenseKey = "KEY" |
using (Library lib = new Library()) |
Not needed |
Document Creation Methods
| Adobe Method | IronPDF Method |
|---|---|
new Document() |
new ChromePdfRenderer() |
new Document(path) |
PdfDocument.FromFile(path) |
doc.CreatePage(index, rect) |
Automatic from 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) |
Content Creation (Major Paradigm Shift)
Adobe PDF Library SDK requires low-level content construction. IronPDF uses HTML/CSS:
| Adobe Method | IronPDF Method |
|---|---|
new Text() |
Use HTML <p>, <h1>, etc. |
text.AddRun(textRun) |
Use HTML |
new TextRun(text, font, size, point) |
CSS styling |
new Font(name, flags) |
CSS font-family |
new Image(path) |
HTML <img> tag |
content.AddElement(...) |
HTML content |
page.UpdateContent() |
Not needed |
Watermark and Security Methods
| Adobe Method | IronPDF Method |
|---|---|
doc.Watermark(textParams, wmParams) |
pdf.ApplyWatermark(html) |
WatermarkParams.Opacity (0.0-1.0) |
opacity parameter (0-100) or CSS opacity |
new EncryptionHandler(user, owner, perms) |
pdf.SecuritySettings |
PermissionFlags.PrintDoc |
AllowUserPrinting |
Text Extraction
| Adobe Method | IronPDF Method |
|---|---|
new WordFinder(doc, config) |
pdf.ExtractAllText() |
wordFinder.GetWordList() |
pdf.Pages[i].Text |
| Complex word/character iteration | Single method call |
Code Migration Examples
HTML to PDF Conversion
APDFL does not have a built-in HTML renderer. The closest like-for-like is constructing pages and content runs by hand to mimic the layout an HTML document would produce — or pairing APDFL with a separate HTML-to-PDF engine.
Adobe PDF Library SDK Implementation:
// Adobe PDF Library 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");
}
}
}
// Adobe PDF Library 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
IronPDF Implementation:
// 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 eliminates the library lifecycle wrapper, conversion parameter objects, and explicit disposal. The ChromePdfRenderer uses a Chromium-based engine for pixel-perfect CSS and JavaScript support. For advanced scenarios, see the HTML to PDF documentation.
Merging Multiple PDFs
PDF merging demonstrates the API complexity difference clearly.
Adobe PDF Library SDK Implementation:
// Adobe PDF Library 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");
}
}
}
// Adobe PDF Library 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
IronPDF Implementation:
// 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
Adobe's approach requires page-by-page iteration with insertion parameters. IronPDF provides a single Merge method that accepts multiple documents.
Adding Watermarks
Watermarking illustrates how IronPDF leverages HTML/CSS for styling flexibility.
Adobe PDF Library SDK Implementation:
// Adobe PDF Library 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");
}
}
}
// Adobe PDF Library 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
IronPDF Implementation:
// 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
IronPDF's HTML-based watermarking provides complete design control through CSS styling, eliminating the need for separate parameter objects.
Password Protection and Encryption
Adobe PDF Library SDK Implementation:
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
IronPDF Implementation:
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 uses strongly-typed properties instead of bitwise permission flags and encryption handler objects.
Text Extraction
Adobe PDF Library SDK Implementation:
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
IronPDF Implementation:
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
Adobe's word-by-word iteration becomes a single method call with IronPDF.
Headers and Footers
Adobe PDF Library SDK Implementation:
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
IronPDF Implementation:
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 handles page iteration automatically and supports placeholder tokens like {page} and {total-pages}. For more advanced layouts, see the headers and footers documentation.
URL to PDF Conversion
Adobe PDF Library SDK lacks built-in URL rendering capability. IronPDF provides native support:
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
For complete URL conversion options, see the URL to PDF documentation.
ASP.NET Core Integration
Adobe PDF Library SDK's static initialization pattern creates friction with dependency injection. IronPDF integrates naturally with modern .NET architectures.
Adobe Pattern (Problematic for DI):
public class AdobePdfService
{
public byte[] Generate(string content)
{
Library.Initialize();
try
{
// Complex document construction...
return bytes;
}
finally
{
Library.Terminate();
}
}
}
public class AdobePdfService
{
public byte[] Generate(string content)
{
Library.Initialize();
try
{
// Complex document construction...
return bytes;
}
finally
{
Library.Terminate();
}
}
}
Public Class AdobePdfService
Public Function Generate(content As String) As Byte()
Library.Initialize()
Try
' Complex document construction...
Return bytes
Finally
Library.Terminate()
End Try
End Function
End Class
IronPDF Pattern (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)()
Async Support
Adobe PDF Library SDK doesn't support async operations. IronPDF provides full async/await capabilities essential for scalable web applications:
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
Performance Optimization
Memory Usage Comparison
| Scenario | Adobe PDF Library SDK | IronPDF |
|---|---|---|
| Simple PDF | ~100 MB | ~50 MB |
| Complex document | ~200 MB | ~80 MB |
| Batch (100 PDFs) | High (native memory) | ~100 MB |
Optimization Tips
Reuse Renderer Instances:
// 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
Use Async in Web Applications:
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
Troubleshooting Common Migration Issues
Issue: Coordinate-Based Positioning Not Working
Adobe uses PostScript point coordinates. IronPDF uses CSS positioning:
// 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>"
Issue: Page Size Differences
Adobe uses PostScript points. IronPDF uses enums or custom dimensions:
// 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)
Issue: Font Not Found
Adobe requires manual font embedding. IronPDF handles fonts automatically:
// 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>"
Issue: SaveFlags Not Available
Adobe uses save flag combinations. IronPDF uses direct save:
// 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);
' Adobe
doc.Save(SaveFlags.Full Or SaveFlags.Incremental, path)
' IronPDF - full save is default
pdf.SaveAs(path)
Post-Migration Checklist
After completing the code migration, verify the following:
- Run all existing unit and integration tests
- Compare PDF outputs visually against previous versions
- Test all PDF workflows in a staging environment
- Verify licensing works correctly (
IronPdf.License.IsLicensed) - Performance benchmark against previous implementation
- Remove Adobe licensing configuration
- Update CI/CD pipeline dependencies
- Remove all Adobe PDF Library DLLs from the project
- Document new patterns for your development team
Additional Resources
Migrating from APDFL to IronPDF can simplify the typical .NET PDF generation codebase, particularly for teams whose primary need is HTML-to-PDF or document manipulation rather than the full Acrobat-derived feature surface. The shift from low-level page construction to HTML/CSS rendering removes most of the coordinate calculation, font management, and Library lifecycle handling code, and IronPDF's transparent per-developer licensing is typically easier to budget than APDFL's sales-led, OEM/SaaS-royalty model.

