How to Migrate from GemBox PDF to IronPDF in C#
Migrating from GemBox PDF to IronPDF transforms your .NET PDF workflow from coordinate-based, programmatic document construction to modern HTML/CSS-based rendering. This guide provides a comprehensive, step-by-step migration path that eliminates paragraph limits and simplifies document creation for professional .NET developers.
Why Migrate from GemBox PDF to IronPDF
The GemBox PDF Challenges
GemBox PDF is a capable .NET PDF component, but it has significant limitations that affect real-world development:
20 Paragraph Limit in Free Version: The free version restricts you to 20 paragraphs, and table cells count toward this limit. A simple 10-row, 5-column table uses 50 "paragraphs," making the free version unusable for even basic business documents.
No HTML-to-PDF Conversion: GemBox PDF requires programmatic document construction. You must calculate coordinates and manually position every element—there's no simple "render this HTML" capability.
Coordinate-Based Layout: Unlike HTML/CSS where layout flows naturally, GemBox PDF requires you to calculate exact X/Y positions for every text element, image, and shape.
Limited Feature Set: Compared to comprehensive PDF libraries, GemBox PDF focuses on basic operations—reading, writing, merging, splitting—without advanced features like HTML rendering or modern CSS support.
Programmatic Only: Every design change requires code changes. Want to tweak spacing? Recalculate coordinates. Want a different font size? Adjust all Y positions below it.
Table Cell Counting: The paragraph limit counts table cells, not just visible paragraphs. This makes the free version practically worthless for documents with tables.
- Learning Curve for Design: Developers must think in coordinates rather than document flow, making simple tasks like "add a paragraph" surprisingly complex.
GemBox PDF vs IronPDF Comparison
| Aspect | GemBox PDF | IronPDF |
|---|---|---|
| Free Version Limits | 20 paragraphs (includes table cells) | Watermark only, no content limits |
| HTML-to-PDF | Not supported | Full Chromium engine |
| Layout Approach | Coordinate-based, manual | HTML/CSS flow layout |
| Tables | Count toward paragraph limit | Unlimited, use HTML tables |
| Modern CSS | Not applicable | Flexbox, Grid, CSS3 animations |
| JavaScript Support | Not applicable | Full JavaScript execution |
| Design Changes | Recalculate coordinates | Edit HTML/CSS |
| Learning Curve | PDF coordinate system | HTML/CSS (web familiar) |
For teams planning .NET 10 and C# 14 adoption through 2025 and 2026, IronPDF provides a future-proof foundation that leverages familiar web technologies for PDF generation.
Migration Complexity Assessment
Estimated Effort by Feature
| Feature | Migration Complexity | Notes |
|---|---|---|
| Load/Save PDFs | Very Low | Direct method mapping |
| Merge PDFs | Very Low | Direct method mapping |
| Split PDFs | Low | Page index handling |
| Text Extraction | Very Low | Direct method mapping |
| Add Text | Medium | Coordinate → HTML |
| Tables | Low | Manual → HTML tables |
| Images | Low | Coordinate → HTML |
| Watermarks | Low | Different API |
| Password Protection | Medium | Different structure |
| Form Fields | Medium | API differences |
Paradigm Shift
The biggest change in this GemBox PDF migration is moving from coordinate-based layout to HTML/CSS layout:
GemBox PDF: "Draw text at position (100, 700)"
IronPDF: "Render this HTML with CSS styling"This paradigm shift is generally easier for developers familiar with web technologies, but requires thinking about PDFs differently.
Before You Start
Prerequisites
- .NET Version: IronPDF supports .NET Framework 4.6.2+ and .NET Core 2.0+ / .NET 5/6/7/8/9+
- License Key: Obtain your IronPDF license key from ironpdf.com
- Backup: Create a branch for migration work
- HTML/CSS Knowledge: Basic familiarity helpful but not required
Identify All GemBox PDF Usage
# Find all GemBox PDF references
grep -r "GemBox\.Pdf\|PdfDocument\|PdfPage\|PdfFormattedText\|ComponentInfo\.SetLicense" --include="*.cs" .
# Find package references
grep -r "GemBox\.Pdf" --include="*.csproj" .# Find all GemBox PDF references
grep -r "GemBox\.Pdf\|PdfDocument\|PdfPage\|PdfFormattedText\|ComponentInfo\.SetLicense" --include="*.cs" .
# Find package references
grep -r "GemBox\.Pdf" --include="*.csproj" .NuGet Package Changes
# Remove GemBox PDF
dotnet remove package GemBox.Pdf
# Install IronPDF
dotnet add package IronPdf# Remove GemBox PDF
dotnet remove package GemBox.Pdf
# Install IronPDF
dotnet add package IronPdfQuick Start Migration
Step 1: Update License Configuration
Before (GemBox PDF):
// Must call before any GemBox PDF operations
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Or for professional:
ComponentInfo.SetLicense("YOUR-PROFESSIONAL-LICENSE");// Must call before any GemBox PDF operations
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Or for professional:
ComponentInfo.SetLicense("YOUR-PROFESSIONAL-LICENSE");After (IronPDF):
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or in appsettings.json:
// { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or in appsettings.json:
// { "IronPdf.License.LicenseKey": "YOUR-LICENSE-KEY" }Step 2: Update Namespace Imports
// Before (GemBox PDF)
using GemBox.Pdf;
using GemBox.Pdf.Content;
// After (IronPDF)
using IronPdf;
using IronPdf.Editing;// Before (GemBox PDF)
using GemBox.Pdf;
using GemBox.Pdf.Content;
// After (IronPDF)
using IronPdf;
using IronPdf.Editing;Step 3: Basic Conversion Pattern
Before (GemBox PDF):
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
var formattedText = new PdfFormattedText()
{
Text = "Hello World",
FontSize = 24
};
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
var formattedText = new PdfFormattedText()
{
Text = "Hello World",
FontSize = 24
};
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}After (IronPDF):
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1 style='font-size:24px;'>Hello World</h1>");
pdf.SaveAs("output.pdf");using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1 style='font-size:24px;'>Hello World</h1>");
pdf.SaveAs("output.pdf");Key Differences:
- No coordinate calculations needed
- HTML/CSS instead of programmatic layout
- No paragraph limits
- Simpler, more readable code
Complete API Reference
Namespace Mapping
| GemBox PDF | IronPDF |
|---|---|
GemBox.Pdf | IronPdf |
GemBox.Pdf.Content | IronPdf (content is HTML) |
GemBox.Pdf.Security | IronPdf (SecuritySettings) |
GemBox.Pdf.Forms | IronPdf.Forms |
Core Class Mapping
| GemBox PDF | IronPDF | Description |
|---|---|---|
PdfDocument | PdfDocument | Main PDF document class |
PdfPage | PdfDocument.Pages[i] | Page representation |
PdfContent | N/A (use HTML) | Page content |
PdfFormattedText | N/A (use HTML) | Formatted text |
PdfPoint | N/A (use CSS positioning) | Coordinate positioning |
ComponentInfo.SetLicense() | IronPdf.License.LicenseKey | License management |
Document Operations
| GemBox PDF | IronPDF | Notes |
|---|---|---|
new PdfDocument() | new PdfDocument() | Create new document |
PdfDocument.Load(path) | PdfDocument.FromFile(path) | Load from file |
PdfDocument.Load(stream) | PdfDocument.FromStream(stream) | Load from stream |
document.Save(path) | pdf.SaveAs(path) | Save to file |
document.Save(stream) | pdf.Stream or pdf.BinaryData | Get as stream/bytes |
Page Operations
| GemBox PDF | IronPDF | Notes |
|---|---|---|
document.Pages.Add() | Create via HTML rendering | Add new page |
document.Pages.Count | pdf.PageCount | Page count |
document.Pages[index] | pdf.Pages[index] | Access page (both 0-indexed) |
document.Pages.AddClone(pages) | PdfDocument.Merge() | Clone/merge pages |
Text and Content Operations
| GemBox PDF | IronPDF | Notes |
|---|---|---|
new PdfFormattedText() | HTML string | Text content |
formattedText.FontSize = 12 | CSS font-size: 12pt | Font size |
formattedText.Font = ... | CSS font-family: ... | Font family |
page.Content.DrawText(text, point) | renderer.RenderHtmlAsPdf(html) | Render text |
page.Content.GetText() | pdf.ExtractTextFromPage(i) | Extract text |
Code Migration Examples
Example 1: HTML to PDF Conversion
Before (GemBox PDF):
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
var document = PdfDocument.Load("input.html");
document.Save("output.pdf");
}
}// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
var document = PdfDocument.Load("input.html");
document.Save("output.pdf");
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
}
}IronPDF's ChromePdfRenderer uses a modern Chromium engine for accurate HTML/CSS/JavaScript rendering. Unlike GemBox PDF's limited HTML support, IronPDF can render any HTML content with full CSS3 and JavaScript support. See the HTML to PDF documentation for more rendering options.
Example 2: Merge PDF Files
Before (GemBox PDF):
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using System.Linq;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var source1 = PdfDocument.Load("document1.pdf");
var source2 = PdfDocument.Load("document2.pdf");
document.Pages.AddClone(source1.Pages);
document.Pages.AddClone(source2.Pages);
document.Save("merged.pdf");
}
}
}// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using System.Linq;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var source1 = PdfDocument.Load("document1.pdf");
var source2 = PdfDocument.Load("document2.pdf");
document.Pages.AddClone(source1.Pages);
document.Pages.AddClone(source2.Pages);
document.Save("merged.pdf");
}
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");
}
}IronPDF's static Merge method simplifies the operation—no need to create an empty document and clone pages individually. Learn more about merging and splitting PDFs.
Example 3: Add Text to PDF
Before (GemBox PDF):
// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
var formattedText = new PdfFormattedText()
{
Text = "Hello World",
FontSize = 24
};
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
}
}// NuGet: Install-Package GemBox.Pdf
using GemBox.Pdf;
using GemBox.Pdf.Content;
class Program
{
static void Main()
{
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
var formattedText = new PdfFormattedText()
{
Text = "Hello World",
FontSize = 24
};
page.Content.DrawText(formattedText, new PdfPoint(100, 700));
document.Save("output.pdf");
}
}
}After (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<p>Original Content</p>");
var stamper = new TextStamper()
{
Text = "Hello World",
FontSize = 24,
HorizontalOffset = 100,
VerticalOffset = 700
};
pdf.ApplyStamp(stamper);
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<p>Original Content</p>");
var stamper = new TextStamper()
{
Text = "Hello World",
FontSize = 24,
HorizontalOffset = 100,
VerticalOffset = 700
};
pdf.ApplyStamp(stamper);
pdf.SaveAs("output.pdf");
}
}For adding text to existing PDFs, IronPDF provides the TextStamper class which offers precise positioning control. For new documents, simply include the text in your HTML template. See the stamping documentation for additional options.
Example 4: Creating Tables (The Biggest Improvement!)
Before (GemBox PDF) - Each cell counts toward 20-paragraph limit:
using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
double y = 700;
double[] xPositions = { 50, 200, 300, 400 };
// Headers (4 paragraphs)
var headers = new[] { "Product", "Price", "Qty", "Total" };
for (int i = 0; i < headers.Length; i++)
{
var text = new PdfFormattedText { Text = headers[i], FontSize = 12 };
page.Content.DrawText(text, new PdfPoint(xPositions[i], y));
}
y -= 20;
// Data rows (4 paragraphs per row!)
// Can only add a few rows before hitting 20-paragraph limit!
document.Save("products.pdf");
}using GemBox.Pdf;
using GemBox.Pdf.Content;
ComponentInfo.SetLicense("FREE-LIMITED-KEY");
using (var document = new PdfDocument())
{
var page = document.Pages.Add();
double y = 700;
double[] xPositions = { 50, 200, 300, 400 };
// Headers (4 paragraphs)
var headers = new[] { "Product", "Price", "Qty", "Total" };
for (int i = 0; i < headers.Length; i++)
{
var text = new PdfFormattedText { Text = headers[i], FontSize = 12 };
page.Content.DrawText(text, new PdfPoint(xPositions[i], y));
}
y -= 20;
// Data rows (4 paragraphs per row!)
// Can only add a few rows before hitting 20-paragraph limit!
document.Save("products.pdf");
}After (IronPDF) - No limits, proper HTML tables:
using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var html = @"
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr><td>Widget A</td><td>$19.99</td><td>5</td><td>$99.95</td></tr>
<tr><td>Widget B</td><td>$29.99</td><td>3</td><td>$89.97</td></tr>
<!-- Add hundreds or thousands of rows - no limit! -->
</tbody>
</table>
</body>
</html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("products.pdf");using IronPdf;
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
var html = @"
<html>
<head>
<style>
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #4CAF50; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr><td>Widget A</td><td>$19.99</td><td>5</td><td>$99.95</td></tr>
<tr><td>Widget B</td><td>$29.99</td><td>3</td><td>$89.97</td></tr>
<!-- Add hundreds or thousands of rows - no limit! -->
</tbody>
</table>
</body>
</html>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("products.pdf");This is the most significant improvement in the GemBox PDF migration. Tables that were impossible in GemBox PDF's free version work perfectly in IronPDF with full CSS styling support.
Critical Migration Notes
Coordinate to CSS Positioning
If you need pixel-perfect positioning (similar to GemBox PDF's coordinate system), use CSS absolute positioning:
<div style="position:absolute; left:50px; top:750px; font-size:24px;">
Text positioned at specific coordinates
</div><div style="position:absolute; left:50px; top:750px; font-size:24px;">
Text positioned at specific coordinates
</div>Page Indexing
Both GemBox PDF and IronPDF use 0-indexed pages, making this aspect of the migration straightforward:
// GemBox PDF
var page = document.Pages[0];
// IronPDF
var page = pdf.Pages[0];// GemBox PDF
var page = document.Pages[0];
// IronPDF
var page = pdf.Pages[0];Security Settings
// GemBox PDF
document.SaveOptions.SetPasswordEncryption(userPassword, ownerPassword);
// IronPDF
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";// GemBox PDF
document.SaveOptions.SetPasswordEncryption(userPassword, ownerPassword);
// IronPDF
pdf.SecuritySettings.UserPassword = "userPassword";
pdf.SecuritySettings.OwnerPassword = "ownerPassword";Troubleshooting
Issue 1: PdfFormattedText Not Found
Problem: PdfFormattedText doesn't exist in IronPDF.
Solution: Use HTML with CSS styling:
// GemBox PDF
var text = new PdfFormattedText { Text = "Hello", FontSize = 24 };
// IronPDF
var html = "<p style='font-size:24px;'>Hello</p>";
var pdf = renderer.RenderHtmlAsPdf(html);// GemBox PDF
var text = new PdfFormattedText { Text = "Hello", FontSize = 24 };
// IronPDF
var html = "<p style='font-size:24px;'>Hello</p>";
var pdf = renderer.RenderHtmlAsPdf(html);Issue 2: DrawText Method Not Found
Problem: page.Content.DrawText() not available.
Solution: Create content via HTML rendering or use stampers:
// For new documents - render HTML
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Content</h1>");
// For existing documents - use stampers
var stamper = new TextStamper() { Text = "Added Text" };
pdf.ApplyStamp(stamper);// For new documents - render HTML
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Content</h1>");
// For existing documents - use stampers
var stamper = new TextStamper() { Text = "Added Text" };
pdf.ApplyStamp(stamper);Issue 3: Document Loading Differences
Problem: PdfDocument.Load() not found.
Solution: Use PdfDocument.FromFile() or FromStream():
// GemBox PDF
var doc = PdfDocument.Load("input.pdf");
// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");// GemBox PDF
var doc = PdfDocument.Load("input.pdf");
// IronPDF
var pdf = PdfDocument.FromFile("input.pdf");Issue 4: Save Method Differences
Problem: document.Save() method signature differs.
Solution: Use SaveAs():
// GemBox PDF
document.Save("output.pdf");
// IronPDF
pdf.SaveAs("output.pdf");// GemBox PDF
document.Save("output.pdf");
// IronPDF
pdf.SaveAs("output.pdf");Migration Checklist
Pre-Migration
- Inventory all GemBox PDF usage in codebase
- Identify coordinate-based layouts that need HTML conversion
- Evaluate current paragraph limits affecting your code
- Obtain IronPDF license key
- Create migration branch in version control
Code Migration
- Remove GemBox PDF NuGet package:
dotnet remove package GemBox.Pdf - Install IronPdf NuGet package:
dotnet add package IronPdf - Update namespace imports
- Replace
ComponentInfo.SetLicense()withIronPdf.License.LicenseKey - Convert
PdfDocument.Load()toPdfDocument.FromFile() - Convert
document.Save()topdf.SaveAs() - Replace coordinate-based text with HTML content
- Convert
PdfFormattedTextto HTML with CSS styling - Update merge operations to use
PdfDocument.Merge()
Testing
- Verify all documents generate correctly
- Validate document appearance matches expectations
- Test table generation (previously limited by 20-paragraph rule)
- Verify text extraction works correctly
- Test merge and split operations
- Validate security/encryption functionality
Post-Migration
- Remove GemBox PDF license keys
- Update documentation
- Train team on HTML/CSS approach for PDFs
- Enjoy unlimited content without paragraph limits!






