푸터 콘텐츠로 바로가기
MIGRATION GUIDES

How to Migrate from ZetPDF to IronPDF in C#

ZetPDF is a commercially licensed PDF library for C# applications built on the foundation of the widely-used open-source PDFSharp library. While ZetPDF provides commercial support and basic PDF manipulation capabilities, it inherits significant limitations from its PDFSharp foundation. Most notably, the library relies on coordinate-based graphics programming and offers limited HTML-to-PDF conversion capabilities compared to modern alternatives.

This guide provides a complete migration path from ZetPDF to IronPDF, with step-by-step instructions, code comparisons, and practical examples for professional .NET developers evaluating this transition.

Why Migrate from ZetPDF

ZetPDF, as a fork of PDFSharp, inherits the same architectural constraints that limit its effectiveness for modern document generation workflows. Key reasons development teams consider migration include:

Coordinate-Based API: ZetPDF forces developers to position every element with exact coordinates. Complex manual positioning of every element creates maintenance challenges as requirements change.

Limited CSS Support: No styling system means manual font and color management for every element.

No JavaScript Rendering: Cannot render dynamic web content or execute JavaScript during PDF generation.

Limited Unique Offerings: Compared to using PDFSharp directly for no cost, ZetPDF offers few compelling reasons that necessitate its commercial licensing.

Manual Page Breaks: Must calculate and manage page overflow manually rather than relying on automatic pagination.

Text Measurement Required: Manual calculation for text wrapping creates additional development overhead.

The Fundamental Problem

ZetPDF and PDFSharp force you to position every element with exact coordinates:

// ZetPDF: Manual positioning nightmare
graphics.DrawString("Name:", font, brush, new XPoint(50, 100));
graphics.DrawString("John Doe", font, brush, new XPoint(100, 100));
graphics.DrawString("Address:", font, brush, new XPoint(50, 120));
graphics.DrawString("123 Main St", font, brush, new XPoint(100, 120));
// ... hundreds of lines for a simple form
// ZetPDF: Manual positioning nightmare
graphics.DrawString("Name:", font, brush, new XPoint(50, 100));
graphics.DrawString("John Doe", font, brush, new XPoint(100, 100));
graphics.DrawString("Address:", font, brush, new XPoint(50, 120));
graphics.DrawString("123 Main St", font, brush, new XPoint(100, 120));
// ... hundreds of lines for a simple form
$vbLabelText   $csharpLabel

IronPDF uses HTML/CSS—the layout engine handles everything:

// IronPDF: Simple HTML
var html = @"
<p><strong>Name:</strong> John Doe</p>
<p><strong>Address:</strong> 123 Main St</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
// IronPDF: Simple HTML
var html = @"
<p><strong>Name:</strong> John Doe</p>
<p><strong>Address:</strong> 123 Main St</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

IronPDF vs ZetPDF: Feature Comparison

Understanding the architectural differences helps technical decision-makers evaluate the migration investment:

Feature ZetPDF IronPDF
Based on PDFSharp Yes No
HTML-to-PDF Conversion Limited Yes (Full Chromium)
Commercial License Yes, Perpetual Yes
Open Source Foundation PDFSharp (MIT License) Chromium-based
CSS Support No Full CSS3
JavaScript No Full ES2024
Automatic Layout No Yes
Auto Page Breaks No Yes
Tables Manual drawing HTML <table>
Headers/Footers Manual HTML/CSS
Watermarks Manual code Built-in
Merge PDFs Limited Yes
Split PDFs Limited Yes
Digital Signatures No Yes
PDF/A No Yes
Simplicity and Ease of Use Moderate High

Quick Start: ZetPDF to IronPDF Migration

The migration can begin immediately with these foundational steps.

Step 1: Replace NuGet Package

Remove ZetPDF:

# Remove ZetPDF
dotnet remove package ZetPDF
# Remove ZetPDF
dotnet remove package ZetPDF
SHELL

Install IronPDF:

# Install IronPDF
dotnet add package IronPdf
# Install IronPDF
dotnet add package IronPdf
SHELL

Step 2: Update Namespaces

Replace ZetPDF namespaces with the IronPdf namespace:

// Before (ZetPDF)
using ZetPdf;
using ZetPdf.Drawing;
using ZetPdf.Fonts;

// After (IronPDF)
using IronPdf;
// Before (ZetPDF)
using ZetPdf;
using ZetPdf.Drawing;
using ZetPdf.Fonts;

// After (IronPDF)
using IronPdf;
$vbLabelText   $csharpLabel

Step 3: Initialize License

Add license initialization at application startup:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Code Migration Examples

Converting HTML to PDF

The HTML-to-PDF operation demonstrates the API differences between these .NET PDF libraries.

ZetPDF Approach:

// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
        converter.ConvertHtmlToPdf(htmlContent, "output.pdf");
        Console.WriteLine("PDF created successfully");
    }
}
// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
        converter.ConvertHtmlToPdf(htmlContent, "output.pdf");
        Console.WriteLine("PDF created successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF Approach:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("output.pdf");
        Console.WriteLine("PDF created successfully");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var htmlContent = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("output.pdf");
        Console.WriteLine("PDF created successfully");
    }
}
$vbLabelText   $csharpLabel

ZetPDF uses HtmlToPdfConverter with ConvertHtmlToPdf() that writes directly to a file path. IronPDF provides ChromePdfRenderer with RenderHtmlAsPdf() that returns a PdfDocument object, giving you more flexibility with the output—you can save to file, get binary data, or perform additional operations before saving.

For advanced HTML-to-PDF scenarios, see the HTML to PDF conversion guide.

Converting URLs to PDF

URL-to-PDF conversion shows the pattern differences clearly.

ZetPDF Approach:

// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        var url = "https://www.example.com";
        converter.ConvertUrlToPdf(url, "webpage.pdf");
        Console.WriteLine("PDF from URL created successfully");
    }
}
// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;

class Program
{
    static void Main()
    {
        var converter = new HtmlToPdfConverter();
        var url = "https://www.example.com";
        converter.ConvertUrlToPdf(url, "webpage.pdf");
        Console.WriteLine("PDF from URL created successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF Approach:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var url = "https://www.example.com";
        var pdf = renderer.RenderUrlAsPdf(url);
        pdf.SaveAs("webpage.pdf");
        Console.WriteLine("PDF from URL created successfully");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var url = "https://www.example.com";
        var pdf = renderer.RenderUrlAsPdf(url);
        pdf.SaveAs("webpage.pdf");
        Console.WriteLine("PDF from URL created successfully");
    }
}
$vbLabelText   $csharpLabel

ZetPDF uses the same HtmlToPdfConverter class with ConvertUrlToPdf(). IronPDF provides RenderUrlAsPdf() on ChromePdfRenderer, which leverages a full Chromium rendering engine for accurate web page capture including JavaScript execution and modern CSS.

Explore the URL to PDF documentation for authentication and custom header options.

Merging Multiple PDFs

PDF merging reveals significant API differences in how documents are handled.

ZetPDF Approach:

// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var merger = new PdfMerger();
        var files = new List<string> { "document1.pdf", "document2.pdf" };
        merger.MergeFiles(files, "merged.pdf");
        Console.WriteLine("PDFs merged successfully");
    }
}
// NuGet: Install-Package ZetPDF
using ZetPDF;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var merger = new PdfMerger();
        var files = new List<string> { "document1.pdf", "document2.pdf" };
        merger.MergeFiles(files, "merged.pdf");
        Console.WriteLine("PDFs merged successfully");
    }
}
$vbLabelText   $csharpLabel

IronPDF Approach:

// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var pdfs = new List<PdfDocument>
        {
            PdfDocument.FromFile("document1.pdf"),
            PdfDocument.FromFile("document2.pdf")
        };
        var merged = PdfDocument.Merge(pdfs);
        merged.SaveAs("merged.pdf");
        Console.WriteLine("PDFs merged successfully");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var pdfs = new List<PdfDocument>
        {
            PdfDocument.FromFile("document1.pdf"),
            PdfDocument.FromFile("document2.pdf")
        };
        var merged = PdfDocument.Merge(pdfs);
        merged.SaveAs("merged.pdf");
        Console.WriteLine("PDFs merged successfully");
    }
}
$vbLabelText   $csharpLabel

ZetPDF uses a dedicated PdfMerger class that operates on file paths with MergeFiles(). IronPDF loads documents as PdfDocument objects using PdfDocument.FromFile(), then merges them with the static PdfDocument.Merge() method. This object-oriented approach enables additional operations on the merged document before saving.

Explore the PDF merging documentation for additional merge options.

Coordinate-Based Drawing vs HTML

For developers with existing ZetPDF code using coordinate-based graphics, the migration path involves converting drawing commands to HTML/CSS.

ZetPDF Coordinate-Based Approach:

using ZetPdf;
using ZetPdf.Drawing;

var document = new PdfDocument();
var page = document.AddPage();
page.Width = XUnit.FromMillimeter(210);
page.Height = XUnit.FromMillimeter(297);

var graphics = XGraphics.FromPdfPage(page);
var titleFont = new XFont("Arial", 24, XFontStyle.Bold);
var bodyFont = new XFont("Arial", 12);

graphics.DrawString("Company Report", titleFont, XBrushes.Navy,
    new XPoint(50, 50));
graphics.DrawString("This is the introduction paragraph.", bodyFont, XBrushes.Black,
    new XPoint(50, 80));
graphics.DrawString("Generated: " + DateTime.Now.ToString(), bodyFont, XBrushes.Gray,
    new XPoint(50, 100));

document.Save("report.pdf");
using ZetPdf;
using ZetPdf.Drawing;

var document = new PdfDocument();
var page = document.AddPage();
page.Width = XUnit.FromMillimeter(210);
page.Height = XUnit.FromMillimeter(297);

var graphics = XGraphics.FromPdfPage(page);
var titleFont = new XFont("Arial", 24, XFontStyle.Bold);
var bodyFont = new XFont("Arial", 12);

graphics.DrawString("Company Report", titleFont, XBrushes.Navy,
    new XPoint(50, 50));
graphics.DrawString("This is the introduction paragraph.", bodyFont, XBrushes.Black,
    new XPoint(50, 80));
graphics.DrawString("Generated: " + DateTime.Now.ToString(), bodyFont, XBrushes.Gray,
    new XPoint(50, 100));

document.Save("report.pdf");
$vbLabelText   $csharpLabel

IronPDF HTML Approach:

using IronPdf;

var html = $@"
<html>
<head>
    <style>
        body {{ font-family: Arial, sans-serif; padding: 50px; }}
        h1 {{ color: navy; }}
        .date {{ color: gray; }}
    </style>
</head>
<body>
    <h1>Company Report</h1>
    <p>This is the introduction paragraph.</p>
    <p class='date'>Generated: {DateTime.Now}</p>
</body>
</html>";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("report.pdf");
using IronPdf;

var html = $@"
<html>
<head>
    <style>
        body {{ font-family: Arial, sans-serif; padding: 50px; }}
        h1 {{ color: navy; }}
        .date {{ color: gray; }}
    </style>
</head>
<body>
    <h1>Company Report</h1>
    <p>This is the introduction paragraph.</p>
    <p class='date'>Generated: {DateTime.Now}</p>
</body>
</html>";

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("report.pdf");
$vbLabelText   $csharpLabel

The ZetPDF approach requires creating font objects, calculating exact pixel positions, and manually managing the graphics context. The IronPDF approach uses standard HTML and CSS that web developers already know—fonts, colors, and layout are handled through familiar CSS properties.

ZetPDF API to IronPDF Mapping Reference

This mapping accelerates migration by showing direct API equivalents:

ZetPDF IronPDF
new PdfDocument() new ChromePdfRenderer()
document.AddPage() Automatic
XGraphics.FromPdfPage(page) N/A
graphics.DrawString() HTML text elements
graphics.DrawImage() <img> tag
graphics.DrawLine() CSS borders
graphics.DrawRectangle() CSS border + div
new XFont() CSS font-family
XBrushes.Black CSS color
document.Save() pdf.SaveAs()
PdfReader.Open() PdfDocument.FromFile()
HtmlToPdfConverter ChromePdfRenderer
ConvertHtmlToPdf() RenderHtmlAsPdf()
ConvertUrlToPdf() RenderUrlAsPdf()
PdfMerger PdfDocument.Merge()

Common Migration Issues and Solutions

Issue 1: Coordinate-Based Layout

ZetPDF: Everything requires exact X,Y coordinates with manual positioning.

Solution: Use HTML/CSS flow layout. For absolute positioning when needed, use CSS:

.positioned-element {
    position: absolute;
    top: 100px;
    left: 50px;
}

Issue 2: Font Object Management

ZetPDF: Create XFont objects for each font variation.

Solution: Use CSS font-family—fonts are handled automatically:

<style>
    body { font-family: Arial, sans-serif; }
    h1 { font-family: 'Times New Roman', serif; font-size: 24px; font-weight: bold; }
</style>
<style>
    body { font-family: Arial, sans-serif; }
    h1 { font-family: 'Times New Roman', serif; font-size: 24px; font-weight: bold; }
</style>
HTML

Issue 3: Color Handling

ZetPDF: Use XBrushes and color objects.

Solution: Use standard CSS colors:

.header { color: navy; background-color: #f5f5f5; }
.warning { color: rgb(255, 0, 0); }

Issue 4: Manual Page Breaks

ZetPDF: Track Y position and create new pages manually when content overflows.

Solution: IronPDF handles automatic page breaks. For explicit control, use CSS:

.section { page-break-after: always; }
.keep-together { page-break-inside: avoid; }

Issue 5: Table Creation

ZetPDF: Requires manual drawing of rectangles, lines, and text positioning.

Solution: Use standard HTML tables with CSS styling:

<table style="border-collapse: collapse; width: 100%;">
    <tr>
        <th style="border: 1px solid black; padding: 8px;">Header</th>
    </tr>
    <tr>
        <td style="border: 1px solid black; padding: 8px;">Data</td>
    </tr>
</table>
<table style="border-collapse: collapse; width: 100%;">
    <tr>
        <th style="border: 1px solid black; padding: 8px;">Header</th>
    </tr>
    <tr>
        <td style="border: 1px solid black; padding: 8px;">Data</td>
    </tr>
</table>
HTML

ZetPDF Migration Checklist

Pre-Migration Tasks

Audit your codebase to identify all ZetPDF usage:

grep -r "using ZetPDF" --include="*.cs" .
grep -r "HtmlToPdfConverter\|PdfMerger\|XGraphics" --include="*.cs" .
grep -r "using ZetPDF" --include="*.cs" .
grep -r "HtmlToPdfConverter\|PdfMerger\|XGraphics" --include="*.cs" .
SHELL

Document coordinate-based drawing code that needs conversion to HTML. Note font and color usage patterns. Map layout structures to HTML equivalents.

Code Update Tasks

  1. Remove ZetPDF NuGet package
  2. Install IronPdf NuGet package
  3. Update namespace imports from ZetPDF to IronPdf
  4. Replace HtmlToPdfConverter with ChromePdfRenderer
  5. Convert ConvertHtmlToPdf() calls to RenderHtmlAsPdf() + SaveAs()
  6. Convert ConvertUrlToPdf() calls to RenderUrlAsPdf() + SaveAs()
  7. Replace PdfMerger.MergeFiles() with PdfDocument.Merge()
  8. Convert DrawString() calls to HTML text elements
  9. Convert XFont to CSS font-family
  10. Replace XBrushes with CSS colors
  11. Add IronPDF license initialization at startup

Post-Migration Testing

After migration, verify these aspects:

  • Compare visual output to ensure appearance matches or improves
  • Verify fonts render as expected with CSS styling
  • Test page breaks occur correctly with automatic pagination
  • Verify images are positioned and displayed correctly
  • Test PDF merging operations produce correct output
  • Confirm all existing functionality works with the new implementation

Key Benefits of Migrating to IronPDF

Moving from ZetPDF to IronPDF provides several critical advantages:

Modern Chromium Rendering Engine: IronPDF uses Chromium for HTML-to-PDF conversion, ensuring full CSS3 and ES2024 JavaScript support. Modern frameworks and responsive designs render correctly.

HTML-Based Content Creation: Web developers can leverage existing HTML and CSS skills. No need to learn coordinate-based drawing APIs or manage font objects.

Automatic Layout and Pagination: Text wrapping, page breaks, and flow layout happen automatically. No manual calculation of element positions.

Simplified API: Single-method calls for common operations. PdfDocument.Merge() replaces complex file path handling patterns.

Active Development: As .NET 10 and C# 14 adoption increases through 2026, IronPDF's regular updates ensure compatibility with current and future .NET versions.

Comprehensive Feature Set: Built-in watermarking, digital signatures, PDF/A compliance, and advanced PDF manipulation features that ZetPDF lacks.

커티스 차우
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.