Skip to footer content
PRODUCT COMPARISONS

IronPDF vs ABCpdf: Which C# PDF Library Delivers Better HTML to PDF Conversion in 2025?

PDF files are used in various industries for tasks such as invoicing and generating different document types. They help meet client requirements effectively. When building .NET applications that require PDF generation, choosing the right library can significantly impact your development speed, output quality, and long-term maintenance costs. Two libraries frequently considered by developers are IronPDF and ABCpdf—but which one truly delivers better results for your specific needs?

This comprehensive comparison examines both libraries' capabilities, from HTML-to-PDF conversion accuracy to licensing models, helping you make an informed decision. We'll explore real-world performance metrics, API design philosophy, and practical code examples that demonstrate each library's strengths and limitations. Whether you're building a SaaS platform that generates thousands of invoices daily or an enterprise application requiring pixel-perfect document rendering, understanding these differences is crucial for project success.

What is IronPDF?

IronPDF is a commercial-grade PDF generation library that helps C# software engineers to edit, extract and generate PDF documents in .NET projects. Built with a Chrome-based rendering engine at its core, IronPDF transforms HTML, CSS, and JavaScript into PDFs with the same fidelity you'd expect from printing a web page in Google Chrome.

Key Features of IronPDF

IronPDF uses a .NET Chromium engine to render HTML pages to PDF files. With HTML-to-PDF there is no need to use complex APIs to position or design PDFs. IronPDF supports standard web documents: HTML, ASPX, JS, CSS, and images. The library's architecture prioritizes developer experience while maintaining professional-grade output quality.

HTML-to-PDF Conversion Excellence

  • Full Support for HTML including HTML5 semantic elements
  • Complete CSS3 support including Flexbox, Grid, and modern layout techniques
  • JavaScript execution for dynamic content rendering
  • Web font support including Google Fonts and custom @font-face declarations
  • Responsive design rendering with viewport control
  • AJAX content loading with configurable wait times

Document Manipulation Capabilities

  • Merge and Split: Combine multiple PDFs or extract specific pages with single method calls
  • Headers and Footers: Add dynamic content including page numbers, dates, and custom HTML
  • Watermarking: Apply text or image watermarks with opacity and positioning control
  • Form Management: Create fillable PDF forms from HTML form elements automatically
  • Digital Signatures: Apply cryptographic signatures with certificate management
  • Encryption: Implement 128-bit and 256-bit AES encryption with granular permissions

Advanced Rendering Features

  • Multi-threaded Processing: Native async/await support for high-performance scenarios
  • Batch Operations: Optimized methods for processing multiple documents simultaneously
  • Memory Efficiency: Streaming support for large document generation without loading entire PDFs into memory
  • Cloud Optimization: Designed for containerized deployments in Docker, Azure, and AWS

Cross-Platform Architecture

IronPDF maintains consistent behavior across different environments:

  • Windows (x86/x64)
  • Linux (including Alpine for minimal Docker images)
  • macOS (Intel and Apple Silicon)
  • Azure App Service, Functions, and Container Instances
  • AWS Lambda and EC2
  • Google Cloud Platform

What is ABCpdf?

The ABCpdf .NET C# PDF library is a .NET component for the dynamic reading, writing, conversion and manipulation of Adobe PDF documents. Developed by WebSupergoo, ABCpdf has been serving the .NET community for over two decades, offering multiple HTML rendering engines and comprehensive PDF manipulation features.

Key Features of ABCpdf

ABCpdf fully supports HTML/CSS and related technologies like JavaScript, SVG, AJAX and Font Awesome. The library provides developers with both high-level convenience methods and low-level PDF object access.

Multiple Rendering Engines

ABCpdf's unique approach offers several rendering engines:

  • ABCChrome Engine: Based on Chromium for modern web standards (x64 only)
  • Gecko Engine: Multiple versions for compatibility testing
  • MSHTML Engine: Internet Explorer-based rendering
  • ABCWebKit Engine: WebKit-based rendering (x64 only)

This multi-engine approach allows developers to choose the best renderer for their specific content, though it adds complexity to deployment and testing.

Document Import Capabilities

ABCpdf can read a variety of document formats when helper applications like OpenOffice.org are installed. Supported formats include:

  • Microsoft Office documents (Word, Excel, PowerPoint)
  • PostScript and EPS files
  • XPS (XML Paper Specification)
  • SVG (Scalable Vector Graphics)
  • Various image formats including TIFF, JPEG 2000, and RAW formats

Low-Level PDF Manipulation

  • Direct access to PDF object model
  • Stream compression/decompression with multiple algorithms
  • Font subsetting and embedding control
  • Color space management and conversion
  • Content stream manipulation

Performance Features

ABCpdf is fully multithreaded, allowing it to be used flexibly in various .NET environments, including C#, ASPX, and VB, and it's tested in high-performance multithreaded settings. The library includes:

  • GigaPDF™ support for extremely large documents
  • Optimized memory usage for server environments
  • Efficient font caching mechanisms
  • Background thread processing capabilities

Comprehensive Feature Comparison

Table 4
Feature Comparison of IronPDF and ABCpdf for .NET Applications
Category Feature/Aspect IronPDF ABCpdf Key Advantage
Core Architecture Design Philosophy Simplicity-first, intuitive APIs Flexibility-first, multiple engines IronPDF: Faster development
API Complexity Simple methods like RenderHtmlAsPdf() Object-oriented with Doc class IronPDF: 70% less code
Learning Curve 1-2 hours typical 1-2 days typical IronPDF: Quicker adoption
Platform Support Cross-Platform Native support, single package Windows primary, Linux limited IronPDF: True cross-platform
.NET Versions .NET 9, 8, 7, 6, 5, Core 3.1+, Framework 4.6.2+ .NET 9, 8, 7, 6, 5, 4.0, Framework 2.0+ Both: Modern framework support
Operating Systems Windows, Linux, macOS, Docker native Windows, limited Linux support IronPDF: Broader OS support
HTML to PDF Rendering Engine Chrome V127+ engine Multiple engines (Chrome 123, Gecko, MSHTML) ABCpdf: Engine flexibility
CSS3/HTML5 Support 100% Chrome-compatible Varies by engine (70-100%) IronPDF: Consistent rendering
JavaScript Execution Full V8 JavaScript support Engine-dependent IronPDF: Modern JS features
Web Fonts Google Fonts, @font-face, system fonts Supported with ABCChrome Both: Web font support
Performance Single Page Rendering 200-400ms typical 150-300ms (ABCChrome) ABCpdf: Slightly faster
Batch Processing Optimized parallel processing Multi-threaded capable IronPDF: Better async support
Memory Usage 150-200MB (Chrome engine) 100-150MB (varies by engine) ABCpdf: Lower memory footprint
Developer Experience Documentation Extensive tutorials, videos, examples Comprehensive API docs IronPDF: More learning resources
Code Examples 100+ ready-to-run samples Extensive examples Both: Rich examples
IntelliSense Support Full XML documentation Comprehensive IntelliSense Both: IDE integration
Licensing & Pricing Entry Level Lite: $749 (1 dev, 1 project) Standard: $329 (1 dev, 32-bit only) ABCpdf: Lower entry cost
Professional Professional: $2,999 (10 devs, 10 projects) Professional: $479 (1 dev, 64-bit) IronPDF: Better team licensing
Redistribution +$1,999 royalty-free $4,790 Enterprise license IronPDF: More affordable
Support Support Included Yes, 24/5 engineering support Yes, email support IronPDF: Live chat support
Response Time < 1 minute (live chat) 24-48 hours typical IronPDF: Faster response
Best For Use Cases Modern web apps, SaaS, cloud-native Windows desktop, legacy systems Context-dependent
Note. ABCpdf offers multiple rendering engines for flexibility but requires Windows for full functionality. IronPDF provides consistent cross-platform performance with the latest Chrome engine. Pricing structures differ significantly between single-developer and team licenses.

Creating a New Project in Visual Studio

Before diving into code examples, let's set up a proper development environment. Open Visual Studio and create a new project:

  1. Navigate to File > New > Project
  2. Select "Console Application" (.NET Core or .NET Framework)
  3. Choose your target framework (.NET 6.0 or higher recommended)
  4. Name your project (e.g., "PdfLibraryComparison")
  5. Click Create

Create a new project in Visual Studio Visual Studio's project creation dialog for setting up a new .NET application

IronPDF C# Library Installation

Installation Methods

IronPDF offers multiple installation approaches to accommodate different development workflows:

The simplest approach is through Visual Studio's integrated NuGet Package Manager:

  1. Right-click your project in Solution Explorer
  2. Select "Manage NuGet Packages"
  3. Click "Browse" and search for "IronPDF"
  4. Click Install on the official IronPDF package

NuGet Package Manager showing IronPDF installation Installing IronPDF through Visual Studio's NuGet Package Manager interface

Method 2: Package Manager Console

For developers who prefer command-line tools:

Install-Package IronPdf

Package Manager Console installing IronPDF Using the Package Manager Console to install IronPDF with a single command

Method 3: Direct Download

For environments with restricted internet access:

  1. Download from NuGet.org
  2. Add the .nupkg file to a local NuGet feed
  3. Install from your local feed

Method 4: .NET CLI

For .NET Core/5+ projects:

dotnet add package IronPdf

Installing ABCpdf

Installation Methods

ABCpdf provides similar installation options with some additional considerations:

Method 1: NuGet Installation

Install-Package ABCpdf -Version 13.0.0.0

Note that ABCpdf has separate packages for different editions:

  • ABCpdf - Standard edition (32-bit only)
  • ABCpdf.ABCChrome64 - Required for Chrome rendering on 64-bit
  • ABCpdf.ABCGecko - For Gecko rendering engine

Method 2: Manual Installation

  1. Download from WebSupergoo website
  2. Extract the ZIP file
  3. Add references to the appropriate DLLs
  4. Copy native dependencies to your output directory

Platform-Specific Considerations

ABCpdf requires additional setup for non-Windows platforms:

<!-- For Linux deployment -->
<PackageReference Include="ABCpdf.Linux" Version="13.0.0.0" />
<!-- For Linux deployment -->
<PackageReference Include="ABCpdf.Linux" Version="13.0.0.0" />
XML

How Do These Libraries Handle HTML to PDF Conversion?

Understanding the fundamental differences in how each library approaches HTML to PDF conversion helps explain their varying capabilities and performance characteristics.

IronPDF's Approach: Chrome-First Architecture

IronPDF uses a full Chrome browser engine, providing several advantages:

using IronPdf;

// IronPDF's approach - Chrome rendering with full browser capabilities
var renderer = new ChromePdfRenderer();

// Configure rendering to match Chrome's print preview exactly
renderer.RenderingOptions = ChromePdfRenderOptions.DefaultChrome;

// Or customize for specific needs
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(500); // Wait for JS execution

// Convert complex HTML with modern CSS and JavaScript
string complexHtml = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;700&display=swap');

        .container {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            font-family: 'Roboto', sans-serif;
        }

        .card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 10px;
            padding: 20px;
            color: white;
            box-shadow: 0 10px 20px rgba(0,0,0,0.19);
            transform: translateY(0);
            transition: transform 0.3s;
        }

        @media print {
            .card { break-inside: avoid; }
        }
    </style>
</head>
<body>
    <div class='container'>
        <div class='card'>
            <h2>Modern CSS Support</h2>
            <p>Grid, Flexbox, Gradients, Shadows - all rendered perfectly</p>
        </div>
        <div class='card'>
            <h2>Web Fonts</h2>
            <p>Google Fonts and custom fonts work seamlessly</p>
        </div>
    </div>
    <script>
        // Dynamic content generation
        document.addEventListener('DOMContentLoaded', function() {
            const container = document.querySelector('.container');
            const dynamicCard = document.createElement('div');
            dynamicCard.className = 'card';
            dynamicCard.innerHTML = '<h2>JavaScript Generated</h2><p>This card was added by JavaScript</p>';
            container.appendChild(dynamicCard);
        });
    </script>
</body>
</html>";

var pdf = renderer.RenderHtmlAsPdf(complexHtml);
pdf.SaveAs("modern-web-features.pdf");
using IronPdf;

// IronPDF's approach - Chrome rendering with full browser capabilities
var renderer = new ChromePdfRenderer();

// Configure rendering to match Chrome's print preview exactly
renderer.RenderingOptions = ChromePdfRenderOptions.DefaultChrome;

// Or customize for specific needs
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(500); // Wait for JS execution

// Convert complex HTML with modern CSS and JavaScript
string complexHtml = @"
<!DOCTYPE html>
<html>
<head>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;700&display=swap');

        .container {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            font-family: 'Roboto', sans-serif;
        }

        .card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 10px;
            padding: 20px;
            color: white;
            box-shadow: 0 10px 20px rgba(0,0,0,0.19);
            transform: translateY(0);
            transition: transform 0.3s;
        }

        @media print {
            .card { break-inside: avoid; }
        }
    </style>
</head>
<body>
    <div class='container'>
        <div class='card'>
            <h2>Modern CSS Support</h2>
            <p>Grid, Flexbox, Gradients, Shadows - all rendered perfectly</p>
        </div>
        <div class='card'>
            <h2>Web Fonts</h2>
            <p>Google Fonts and custom fonts work seamlessly</p>
        </div>
    </div>
    <script>
        // Dynamic content generation
        document.addEventListener('DOMContentLoaded', function() {
            const container = document.querySelector('.container');
            const dynamicCard = document.createElement('div');
            dynamicCard.className = 'card';
            dynamicCard.innerHTML = '<h2>JavaScript Generated</h2><p>This card was added by JavaScript</p>';
            container.appendChild(dynamicCard);
        });
    </script>
</body>
</html>";

var pdf = renderer.RenderHtmlAsPdf(complexHtml);
pdf.SaveAs("modern-web-features.pdf");
Imports IronPdf

' IronPDF's approach - Chrome rendering with full browser capabilities
Private renderer = New ChromePdfRenderer()

' Configure rendering to match Chrome's print preview exactly
renderer.RenderingOptions = ChromePdfRenderOptions.DefaultChrome

' Or customize for specific needs
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Screen
renderer.RenderingOptions.EnableJavaScript = True
renderer.RenderingOptions.WaitFor.RenderDelay(500) ' Wait for JS execution

' Convert complex HTML with modern CSS and JavaScript
Dim complexHtml As String = "
<!DOCTYPE html>
<html>
<head>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;700&display=swap');

        .container {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            font-family: 'Roboto', sans-serif;
        }

        .card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border-radius: 10px;
            padding: 20px;
            color: white;
            box-shadow: 0 10px 20px rgba(0,0,0,0.19);
            transform: translateY(0);
            transition: transform 0.3s;
        }

        @media print {
            .card { break-inside: avoid; }
        }
    </style>
</head>
<body>
    <div class='container'>
        <div class='card'>
            <h2>Modern CSS Support</h2>
            <p>Grid, Flexbox, Gradients, Shadows - all rendered perfectly</p>
        </div>
        <div class='card'>
            <h2>Web Fonts</h2>
            <p>Google Fonts and custom fonts work seamlessly</p>
        </div>
    </div>
    <script>
        // Dynamic content generation
        document.addEventListener('DOMContentLoaded', function() {
            const container = document.querySelector('.container');
            const dynamicCard = document.createElement('div');
            dynamicCard.className = 'card';
            dynamicCard.innerHTML = '<h2>JavaScript Generated</h2><p>This card was added by JavaScript</p>';
            container.appendChild(dynamicCard);
        });
    </script>
</body>
</html>"

Dim pdf = renderer.RenderHtmlAsPdf(complexHtml)
pdf.SaveAs("modern-web-features.pdf")
$vbLabelText   $csharpLabel

This code demonstrates several key advantages of IronPDF's Chrome-based approach:

  1. Modern CSS Support: Grid layouts, flexbox, gradients, and transforms work exactly as they do in Chrome
  2. Web Font Integration: Google Fonts load automatically without additional configuration
  3. JavaScript Execution: Dynamic content generation happens before PDF rendering
  4. Media Queries: Print-specific styles are properly applied

ABCpdf's Approach: Multi-Engine Flexibility

ABCpdf offers multiple rendering engines, each with different capabilities:

using WebSupergoo.ABCpdf13;

// Method 1: Using ABCChrome engine (most modern)
Doc chromeDoc = new Doc();
chromeDoc.HtmlOptions.Engine = EngineType.Chrome;
chromeDoc.HtmlOptions.Chrome.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

// Chrome engine supports modern web standards
int chromeId = chromeDoc.AddImageUrl("https://example.com");

// Chain pages if content overflows
while (chromeDoc.Chainable(chromeId))
{
    chromeDoc.Page = chromeDoc.AddPage();
    chromeId = chromeDoc.AddImageToChain(chromeId);
}

chromeDoc.Save("chrome-engine-output.pdf");

// Method 2: Using Gecko engine (Firefox-based)
Doc geckoDoc = new Doc();
geckoDoc.HtmlOptions.Engine = EngineType.Gecko;
geckoDoc.HtmlOptions.UseScript = true; // Enable JavaScript

// Gecko provides good standards support with lower resource usage
string html = "<html><body><h1>Gecko Rendered Content</h1></body></html>";
geckoDoc.AddImageHtml(html);
geckoDoc.Save("gecko-engine-output.pdf");

// Method 3: Using MSHTML engine (IE-based, legacy support)
Doc ieDoc = new Doc();
ieDoc.HtmlOptions.Engine = EngineType.MSHtml;

// MSHTML is faster but with limited modern CSS support
ieDoc.AddImageUrl("https://legacy-app.example.com");
ieDoc.Save("ie-engine-output.pdf");
using WebSupergoo.ABCpdf13;

// Method 1: Using ABCChrome engine (most modern)
Doc chromeDoc = new Doc();
chromeDoc.HtmlOptions.Engine = EngineType.Chrome;
chromeDoc.HtmlOptions.Chrome.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");

// Chrome engine supports modern web standards
int chromeId = chromeDoc.AddImageUrl("https://example.com");

// Chain pages if content overflows
while (chromeDoc.Chainable(chromeId))
{
    chromeDoc.Page = chromeDoc.AddPage();
    chromeId = chromeDoc.AddImageToChain(chromeId);
}

chromeDoc.Save("chrome-engine-output.pdf");

// Method 2: Using Gecko engine (Firefox-based)
Doc geckoDoc = new Doc();
geckoDoc.HtmlOptions.Engine = EngineType.Gecko;
geckoDoc.HtmlOptions.UseScript = true; // Enable JavaScript

// Gecko provides good standards support with lower resource usage
string html = "<html><body><h1>Gecko Rendered Content</h1></body></html>";
geckoDoc.AddImageHtml(html);
geckoDoc.Save("gecko-engine-output.pdf");

// Method 3: Using MSHTML engine (IE-based, legacy support)
Doc ieDoc = new Doc();
ieDoc.HtmlOptions.Engine = EngineType.MSHtml;

// MSHTML is faster but with limited modern CSS support
ieDoc.AddImageUrl("https://legacy-app.example.com");
ieDoc.Save("ie-engine-output.pdf");
Imports WebSupergoo.ABCpdf13

' Method 1: Using ABCChrome engine (most modern)
Private chromeDoc As New Doc()
chromeDoc.HtmlOptions.Engine = EngineType.Chrome
chromeDoc.HtmlOptions.Chrome.SetUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")

' Chrome engine supports modern web standards
Dim chromeId As Integer = chromeDoc.AddImageUrl("https://example.com")

' Chain pages if content overflows
Do While chromeDoc.Chainable(chromeId)
	chromeDoc.Page = chromeDoc.AddPage()
	chromeId = chromeDoc.AddImageToChain(chromeId)
Loop

chromeDoc.Save("chrome-engine-output.pdf")

' Method 2: Using Gecko engine (Firefox-based)
Dim geckoDoc As New Doc()
geckoDoc.HtmlOptions.Engine = EngineType.Gecko
geckoDoc.HtmlOptions.UseScript = True ' Enable JavaScript

' Gecko provides good standards support with lower resource usage
Dim html As String = "<html><body><h1>Gecko Rendered Content</h1></body></html>"
geckoDoc.AddImageHtml(html)
geckoDoc.Save("gecko-engine-output.pdf")

' Method 3: Using MSHTML engine (IE-based, legacy support)
Dim ieDoc As New Doc()
ieDoc.HtmlOptions.Engine = EngineType.MSHtml

' MSHTML is faster but with limited modern CSS support
ieDoc.AddImageUrl("https://legacy-app.example.com")
ieDoc.Save("ie-engine-output.pdf")
$vbLabelText   $csharpLabel

The multi-engine approach provides flexibility but requires careful consideration:

  1. Engine Selection: Developers must choose the appropriate engine for their content
  2. Feature Parity: Different engines support different HTML/CSS features
  3. Deployment Complexity: Each engine may have different runtime requirements
  4. Testing Overhead: Output may vary between engines, requiring more testing

Creating PDF Documents from URLs

One of the most common use cases for PDF libraries is converting live web pages to PDF documents. Let's examine how each library handles this task.

Using IronPDF

IronPDF's URL to PDF conversion leverages the full Chrome browser engine:

using IronPdf;
using System;
using System.Threading.Tasks;

public class UrlToPdfConverter
{
    public static async Task ConvertUrlToPdfAsync()
    {
        var renderer = new ChromePdfRenderer();

        // Configure for optimal web page capture
        renderer.RenderingOptions = new ChromePdfRenderOptions
        {
            // Viewport and scaling
            ViewPortWidth = 1920,
            ViewPortHeight = 1080,
            ZoomLevel = 100,

            // Paper and margins
            PaperSize = PdfPaperSize.A4,
            MarginTop = 10,
            MarginBottom = 10,
            MarginLeft = 10,
            MarginRight = 10,

            // Rendering behavior
            CssMediaType = PdfCssMediaType.Screen,
            PrintHtmlBackgrounds = true,
            CreatePdfFormsFromHtml = true,

            // JavaScript and timing
            EnableJavaScript = true,
            WaitFor = new WaitFor
            {
                // Wait strategies for dynamic content
                RenderDelay = 500, // milliseconds
                JavaScriptFinishDelay = 100,
                AllowedExecutionTime = 30000 // 30 seconds max
            }
        };

        // Handle authentication if needed
        renderer.RenderingOptions.HttpOptions.HttpHeaders.Add("Authorization", "Bearer your-token");

        // Convert with error handling
        try
        {
            // Async conversion for better performance
            var pdf = await renderer.RenderUrlAsPdfAsync("https://github.com/trending");

            // Add metadata
            pdf.MetaData.Author = "IronPDF Example";
            pdf.MetaData.Title = "GitHub Trending Projects";
            pdf.MetaData.CreationDate = DateTime.Now;

            // Add watermark
            pdf.ApplyWatermark("<h2 style='color:red;opacity:0.5'>CONFIDENTIAL</h2>", 
                30, VerticalAlignment.Middle, HorizontalAlignment.Center);

            pdf.SaveAs("github-trending.pdf");
            Console.WriteLine("PDF created successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error creating PDF: {ex.Message}");
        }
    }
}
using IronPdf;
using System;
using System.Threading.Tasks;

public class UrlToPdfConverter
{
    public static async Task ConvertUrlToPdfAsync()
    {
        var renderer = new ChromePdfRenderer();

        // Configure for optimal web page capture
        renderer.RenderingOptions = new ChromePdfRenderOptions
        {
            // Viewport and scaling
            ViewPortWidth = 1920,
            ViewPortHeight = 1080,
            ZoomLevel = 100,

            // Paper and margins
            PaperSize = PdfPaperSize.A4,
            MarginTop = 10,
            MarginBottom = 10,
            MarginLeft = 10,
            MarginRight = 10,

            // Rendering behavior
            CssMediaType = PdfCssMediaType.Screen,
            PrintHtmlBackgrounds = true,
            CreatePdfFormsFromHtml = true,

            // JavaScript and timing
            EnableJavaScript = true,
            WaitFor = new WaitFor
            {
                // Wait strategies for dynamic content
                RenderDelay = 500, // milliseconds
                JavaScriptFinishDelay = 100,
                AllowedExecutionTime = 30000 // 30 seconds max
            }
        };

        // Handle authentication if needed
        renderer.RenderingOptions.HttpOptions.HttpHeaders.Add("Authorization", "Bearer your-token");

        // Convert with error handling
        try
        {
            // Async conversion for better performance
            var pdf = await renderer.RenderUrlAsPdfAsync("https://github.com/trending");

            // Add metadata
            pdf.MetaData.Author = "IronPDF Example";
            pdf.MetaData.Title = "GitHub Trending Projects";
            pdf.MetaData.CreationDate = DateTime.Now;

            // Add watermark
            pdf.ApplyWatermark("<h2 style='color:red;opacity:0.5'>CONFIDENTIAL</h2>", 
                30, VerticalAlignment.Middle, HorizontalAlignment.Center);

            pdf.SaveAs("github-trending.pdf");
            Console.WriteLine("PDF created successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error creating PDF: {ex.Message}");
        }
    }
}
Imports IronPdf
Imports System
Imports System.Threading.Tasks

Public Class UrlToPdfConverter
	Public Shared Async Function ConvertUrlToPdfAsync() As Task
		Dim renderer = New ChromePdfRenderer()

		' Configure for optimal web page capture
		renderer.RenderingOptions = New ChromePdfRenderOptions With {
			.ViewPortWidth = 1920,
			.ViewPortHeight = 1080,
			.ZoomLevel = 100,
			.PaperSize = PdfPaperSize.A4,
			.MarginTop = 10,
			.MarginBottom = 10,
			.MarginLeft = 10,
			.MarginRight = 10,
			.CssMediaType = PdfCssMediaType.Screen,
			.PrintHtmlBackgrounds = True,
			.CreatePdfFormsFromHtml = True,
			.EnableJavaScript = True,
			.WaitFor = New WaitFor With {
				.RenderDelay = 500,
				.JavaScriptFinishDelay = 100,
				.AllowedExecutionTime = 30000
			}
		}

		' Handle authentication if needed
		renderer.RenderingOptions.HttpOptions.HttpHeaders.Add("Authorization", "Bearer your-token")

		' Convert with error handling
		Try
			' Async conversion for better performance
			Dim pdf = Await renderer.RenderUrlAsPdfAsync("https://github.com/trending")

			' Add metadata
			pdf.MetaData.Author = "IronPDF Example"
			pdf.MetaData.Title = "GitHub Trending Projects"
			pdf.MetaData.CreationDate = DateTime.Now

			' Add watermark
			pdf.ApplyWatermark("<h2 style='color:red;opacity:0.5'>CONFIDENTIAL</h2>", 30, VerticalAlignment.Middle, HorizontalAlignment.Center)

			pdf.SaveAs("github-trending.pdf")
			Console.WriteLine("PDF created successfully!")
		Catch ex As Exception
			Console.WriteLine($"Error creating PDF: {ex.Message}")
		End Try
	End Function
End Class
$vbLabelText   $csharpLabel

Key features demonstrated:

  • Viewport Control: Simulate different screen sizes for responsive testing
  • Authentication Support: Add headers for protected resources
  • Dynamic Content Handling: Wait strategies for JavaScript-heavy pages
  • Post-Processing: Add metadata and watermarks after conversion

Using ABCpdf

ABCpdf's URL conversion with page chaining:

using WebSupergoo.ABCpdf13;
using System;

public class ABCpdfUrlConverter
{
    public static void ConvertUrlWithABCpdf()
    {
        using (Doc theDoc = new Doc())
        {
            // Configure the HTML engine
            theDoc.HtmlOptions.Engine = EngineType.Chrome;
            theDoc.HtmlOptions.Chrome.LoadDelay = 1000; // Wait 1 second

            // Set viewport size
            theDoc.HtmlOptions.BrowserWidth = 1200;

            // Authentication
            theDoc.HtmlOptions.HttpAdditionalHeaders = "Authorization: Bearer your-token";

            // Page setup
            theDoc.Rect.Inset(20, 20);
            theDoc.Page = theDoc.AddPage();

            // Add the URL
            int theID = theDoc.AddImageUrl("https://github.com/trending");

            // Chain pages for overflow content
            while (true)
            {
                if (!theDoc.Chainable(theID))
                    break;
                theDoc.Page = theDoc.AddPage();
                theID = theDoc.AddImageToChain(theID);
            }

            // Reduce file size
            for (int i = 1; i <= theDoc.PageCount; i++)
            {
                theDoc.PageNumber = i;
                theDoc.Flatten();
            }

            // Save
            theDoc.Save("abcpdf-github.pdf");
        }
    }
}
using WebSupergoo.ABCpdf13;
using System;

public class ABCpdfUrlConverter
{
    public static void ConvertUrlWithABCpdf()
    {
        using (Doc theDoc = new Doc())
        {
            // Configure the HTML engine
            theDoc.HtmlOptions.Engine = EngineType.Chrome;
            theDoc.HtmlOptions.Chrome.LoadDelay = 1000; // Wait 1 second

            // Set viewport size
            theDoc.HtmlOptions.BrowserWidth = 1200;

            // Authentication
            theDoc.HtmlOptions.HttpAdditionalHeaders = "Authorization: Bearer your-token";

            // Page setup
            theDoc.Rect.Inset(20, 20);
            theDoc.Page = theDoc.AddPage();

            // Add the URL
            int theID = theDoc.AddImageUrl("https://github.com/trending");

            // Chain pages for overflow content
            while (true)
            {
                if (!theDoc.Chainable(theID))
                    break;
                theDoc.Page = theDoc.AddPage();
                theID = theDoc.AddImageToChain(theID);
            }

            // Reduce file size
            for (int i = 1; i <= theDoc.PageCount; i++)
            {
                theDoc.PageNumber = i;
                theDoc.Flatten();
            }

            // Save
            theDoc.Save("abcpdf-github.pdf");
        }
    }
}
Imports WebSupergoo.ABCpdf13
Imports System

Public Class ABCpdfUrlConverter
	Public Shared Sub ConvertUrlWithABCpdf()
		Using theDoc As New Doc()
			' Configure the HTML engine
			theDoc.HtmlOptions.Engine = EngineType.Chrome
			theDoc.HtmlOptions.Chrome.LoadDelay = 1000 ' Wait 1 second

			' Set viewport size
			theDoc.HtmlOptions.BrowserWidth = 1200

			' Authentication
			theDoc.HtmlOptions.HttpAdditionalHeaders = "Authorization: Bearer your-token"

			' Page setup
			theDoc.Rect.Inset(20, 20)
			theDoc.Page = theDoc.AddPage()

			' Add the URL
			Dim theID As Integer = theDoc.AddImageUrl("https://github.com/trending")

			' Chain pages for overflow content
			Do
				If Not theDoc.Chainable(theID) Then
					Exit Do
				End If
				theDoc.Page = theDoc.AddPage()
				theID = theDoc.AddImageToChain(theID)
			Loop

			' Reduce file size
			For i As Integer = 1 To theDoc.PageCount
				theDoc.PageNumber = i
				theDoc.Flatten()
			Next i

			' Save
			theDoc.Save("abcpdf-github.pdf")
		End Using
	End Sub
End Class
$vbLabelText   $csharpLabel

Notable differences:

  • Page Chaining: Manual handling of multi-page content
  • Engine Configuration: Must explicitly choose rendering engine
  • Resource Management: Requires proper disposal with using statement

Creating PDFs from HTML Strings

Both libraries excel at converting HTML strings to PDF, but their approaches differ significantly.

Using IronPDF

IronPDF's HTML string conversion with advanced features:

using IronPdf;
using System.IO;

public class HtmlStringToPdf
{
    public static void GenerateInvoicePdf()
    {
        var renderer = new ChromePdfRenderer();

        // Configure for print-quality output
        renderer.RenderingOptions = new ChromePdfRenderOptions
        {
            PaperSize = PdfPaperSize.A4,
            DPI = 300, // High quality print
            CssMediaType = PdfCssMediaType.Print,
            PaperFit = new PaperFit
            {
                UseFitToPageRendering = true,
                RenderScale = 100
            }
        };

        // Professional invoice HTML
        string invoiceHtml = @"
<!DOCTYPE html>
<html>
<head>
    <meta charset='UTF-8'>
    <style>
        @page {
            size: A4;
            margin: 0;
        }

        body {
            font-family: 'Segoe UI', Arial, sans-serif;
            margin: 0;
            padding: 20mm;
            color: #333;
        }

        .invoice-header {
            display: flex;
            justify-content: space-between;
            align-items: start;
            margin-bottom: 30px;
            border-bottom: 2px solid #0066cc;
            padding-bottom: 20px;
        }

        .company-info h1 {
            color: #0066cc;
            margin: 0;
            font-size: 28px;
        }

        .invoice-details {
            text-align: right;
        }

        .invoice-details h2 {
            color: #666;
            margin: 0 0 10px 0;
            font-size: 24px;
        }

        .invoice-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 30px;
        }

        .invoice-table th {
            background-color: #0066cc;
            color: white;
            padding: 12px;
            text-align: left;
        }

        .invoice-table td {
            padding: 12px;
            border-bottom: 1px solid #ddd;
        }

        .invoice-table tr:hover {
            background-color: #f5f5f5;
        }

        .total-section {
            margin-top: 30px;
            text-align: right;
        }

        .total-section .total-row {
            display: flex;
            justify-content: flex-end;
            margin: 5px 0;
        }

        .total-section .label {
            font-weight: bold;
            margin-right: 20px;
            min-width: 100px;
        }

        .total-section .grand-total {
            font-size: 20px;
            color: #0066cc;
            border-top: 2px solid #0066cc;
            padding-top: 10px;
            margin-top: 10px;
        }

        @media print {
            .no-print { display: none; }
        }
    </style>
</head>
<body>
    <div class='invoice-header'>
        <div class='company-info'>
            <h1>ACME Corporation</h1>
            <p>123 Business Street<br>
            New York, NY 10001<br>
            Phone: (555) 123-4567<br>
            Email: billing@acme.com</p>
        </div>
        <div class='invoice-details'>
            <h2>INVOICE</h2>
            <p><strong>Invoice #:</strong> INV-2025-001<br>
            <strong>Date:</strong> " + DateTime.Now.ToString("MMMM dd, yyyy") + @"<br>
            <strong>Due Date:</strong> " + DateTime.Now.AddDays(30).ToString("MMMM dd, yyyy") + @"</p>
        </div>
    </div>

    <div class='billing-info'>
        <h3>Bill To:</h3>
        <p>John Doe<br>
        456 Client Avenue<br>
        Los Angeles, CA 90001</p>
    </div>

    <table class='invoice-table'>
        <thead>
            <tr>
                <th>Description</th>
                <th>Quantity</th>
                <th>Unit Price</th>
                <th>Total</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Professional Services - Web Development</td>
                <td>40 hours</td>
                <td>$150.00</td>
                <td>$6,000.00</td>
            </tr>
            <tr>
                <td>Hosting Services (Annual)</td>
                <td>1</td>
                <td>$1,200.00</td>
                <td>$1,200.00</td>
            </tr>
            <tr>
                <td>Domain Registration</td>
                <td>2</td>
                <td>$15.00</td>
                <td>$30.00</td>
            </tr>
        </tbody>
    </table>

    <div class='total-section'>
        <div class='total-row'>
            <span class='label'>Subtotal:</span>
            <span>$7,230.00</span>
        </div>
        <div class='total-row'>
            <span class='label'>Tax (8%):</span>
            <span>$578.40</span>
        </div>
        <div class='total-row grand-total'>
            <span class='label'>Total Due:</span>
            <span>$7,808.40</span>
        </div>
    </div>

    <div class='footer' style='margin-top: 50px; padding-top: 20px; border-top: 1px solid #ddd; text-align: center; color: #666;'>
        <p>Thank you for your business!<br>
        Payment is due within 30 days. Please include invoice number with payment.</p>
    </div>
</body>
</html>";

        // Generate PDF with base path for local assets
        var pdf = renderer.RenderHtmlAsPdf(invoiceHtml, @"C:\Assets\");

        // Add security
        pdf.SecuritySettings.AllowUserEditing = false;
        pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
        pdf.SecuritySettings.OwnerPassword = "admin123";

        // Save with optimization
        pdf.CompressImages(60); // 60% quality for smaller file size
        pdf.SaveAs("professional-invoice.pdf");
    }
}
using IronPdf;
using System.IO;

public class HtmlStringToPdf
{
    public static void GenerateInvoicePdf()
    {
        var renderer = new ChromePdfRenderer();

        // Configure for print-quality output
        renderer.RenderingOptions = new ChromePdfRenderOptions
        {
            PaperSize = PdfPaperSize.A4,
            DPI = 300, // High quality print
            CssMediaType = PdfCssMediaType.Print,
            PaperFit = new PaperFit
            {
                UseFitToPageRendering = true,
                RenderScale = 100
            }
        };

        // Professional invoice HTML
        string invoiceHtml = @"
<!DOCTYPE html>
<html>
<head>
    <meta charset='UTF-8'>
    <style>
        @page {
            size: A4;
            margin: 0;
        }

        body {
            font-family: 'Segoe UI', Arial, sans-serif;
            margin: 0;
            padding: 20mm;
            color: #333;
        }

        .invoice-header {
            display: flex;
            justify-content: space-between;
            align-items: start;
            margin-bottom: 30px;
            border-bottom: 2px solid #0066cc;
            padding-bottom: 20px;
        }

        .company-info h1 {
            color: #0066cc;
            margin: 0;
            font-size: 28px;
        }

        .invoice-details {
            text-align: right;
        }

        .invoice-details h2 {
            color: #666;
            margin: 0 0 10px 0;
            font-size: 24px;
        }

        .invoice-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 30px;
        }

        .invoice-table th {
            background-color: #0066cc;
            color: white;
            padding: 12px;
            text-align: left;
        }

        .invoice-table td {
            padding: 12px;
            border-bottom: 1px solid #ddd;
        }

        .invoice-table tr:hover {
            background-color: #f5f5f5;
        }

        .total-section {
            margin-top: 30px;
            text-align: right;
        }

        .total-section .total-row {
            display: flex;
            justify-content: flex-end;
            margin: 5px 0;
        }

        .total-section .label {
            font-weight: bold;
            margin-right: 20px;
            min-width: 100px;
        }

        .total-section .grand-total {
            font-size: 20px;
            color: #0066cc;
            border-top: 2px solid #0066cc;
            padding-top: 10px;
            margin-top: 10px;
        }

        @media print {
            .no-print { display: none; }
        }
    </style>
</head>
<body>
    <div class='invoice-header'>
        <div class='company-info'>
            <h1>ACME Corporation</h1>
            <p>123 Business Street<br>
            New York, NY 10001<br>
            Phone: (555) 123-4567<br>
            Email: billing@acme.com</p>
        </div>
        <div class='invoice-details'>
            <h2>INVOICE</h2>
            <p><strong>Invoice #:</strong> INV-2025-001<br>
            <strong>Date:</strong> " + DateTime.Now.ToString("MMMM dd, yyyy") + @"<br>
            <strong>Due Date:</strong> " + DateTime.Now.AddDays(30).ToString("MMMM dd, yyyy") + @"</p>
        </div>
    </div>

    <div class='billing-info'>
        <h3>Bill To:</h3>
        <p>John Doe<br>
        456 Client Avenue<br>
        Los Angeles, CA 90001</p>
    </div>

    <table class='invoice-table'>
        <thead>
            <tr>
                <th>Description</th>
                <th>Quantity</th>
                <th>Unit Price</th>
                <th>Total</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Professional Services - Web Development</td>
                <td>40 hours</td>
                <td>$150.00</td>
                <td>$6,000.00</td>
            </tr>
            <tr>
                <td>Hosting Services (Annual)</td>
                <td>1</td>
                <td>$1,200.00</td>
                <td>$1,200.00</td>
            </tr>
            <tr>
                <td>Domain Registration</td>
                <td>2</td>
                <td>$15.00</td>
                <td>$30.00</td>
            </tr>
        </tbody>
    </table>

    <div class='total-section'>
        <div class='total-row'>
            <span class='label'>Subtotal:</span>
            <span>$7,230.00</span>
        </div>
        <div class='total-row'>
            <span class='label'>Tax (8%):</span>
            <span>$578.40</span>
        </div>
        <div class='total-row grand-total'>
            <span class='label'>Total Due:</span>
            <span>$7,808.40</span>
        </div>
    </div>

    <div class='footer' style='margin-top: 50px; padding-top: 20px; border-top: 1px solid #ddd; text-align: center; color: #666;'>
        <p>Thank you for your business!<br>
        Payment is due within 30 days. Please include invoice number with payment.</p>
    </div>
</body>
</html>";

        // Generate PDF with base path for local assets
        var pdf = renderer.RenderHtmlAsPdf(invoiceHtml, @"C:\Assets\");

        // Add security
        pdf.SecuritySettings.AllowUserEditing = false;
        pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
        pdf.SecuritySettings.OwnerPassword = "admin123";

        // Save with optimization
        pdf.CompressImages(60); // 60% quality for smaller file size
        pdf.SaveAs("professional-invoice.pdf");
    }
}
Imports IronPdf
Imports System.IO

Public Class HtmlStringToPdf
	Public Shared Sub GenerateInvoicePdf()
		Dim renderer = New ChromePdfRenderer()

		' Configure for print-quality output
		renderer.RenderingOptions = New ChromePdfRenderOptions With {
			.PaperSize = PdfPaperSize.A4,
			.DPI = 300,
			.CssMediaType = PdfCssMediaType.Print,
			.PaperFit = New PaperFit With {
				.UseFitToPageRendering = True,
				.RenderScale = 100
			}
		}

		' Professional invoice HTML
		Dim invoiceHtml As String = "
<!DOCTYPE html>
<html>
<head>
    <meta charset='UTF-8'>
    <style>
        @page {
            size: A4;
            margin: 0;
        }

        body {
            font-family: 'Segoe UI', Arial, sans-serif;
            margin: 0;
            padding: 20mm;
            color: #333;
        }

        .invoice-header {
            display: flex;
            justify-content: space-between;
            align-items: start;
            margin-bottom: 30px;
            border-bottom: 2px solid #0066cc;
            padding-bottom: 20px;
        }

        .company-info h1 {
            color: #0066cc;
            margin: 0;
            font-size: 28px;
        }

        .invoice-details {
            text-align: right;
        }

        .invoice-details h2 {
            color: #666;
            margin: 0 0 10px 0;
            font-size: 24px;
        }

        .invoice-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 30px;
        }

        .invoice-table th {
            background-color: #0066cc;
            color: white;
            padding: 12px;
            text-align: left;
        }

        .invoice-table td {
            padding: 12px;
            border-bottom: 1px solid #ddd;
        }

        .invoice-table tr:hover {
            background-color: #f5f5f5;
        }

        .total-section {
            margin-top: 30px;
            text-align: right;
        }

        .total-section .total-row {
            display: flex;
            justify-content: flex-end;
            margin: 5px 0;
        }

        .total-section .label {
            font-weight: bold;
            margin-right: 20px;
            min-width: 100px;
        }

        .total-section .grand-total {
            font-size: 20px;
            color: #0066cc;
            border-top: 2px solid #0066cc;
            padding-top: 10px;
            margin-top: 10px;
        }

        @media print {
            .no-print { display: none; }
        }
    </style>
</head>
<body>
    <div class='invoice-header'>
        <div class='company-info'>
            <h1>ACME Corporation</h1>
            <p>123 Business Street<br>
            New York, NY 10001<br>
            Phone: (555) 123-4567<br>
            Email: billing@acme.com</p>
        </div>
        <div class='invoice-details'>
            <h2>INVOICE</h2>
            <p><strong>Invoice #:</strong> INV-2025-001<br>
            <strong>Date:</strong> " & DateTime.Now.ToString("MMMM dd, yyyy") & "<br>
            <strong>Due Date:</strong> " & DateTime.Now.AddDays(30).ToString("MMMM dd, yyyy") & "</p>
        </div>
    </div>

    <div class='billing-info'>
        <h3>Bill To:</h3>
        <p>John Doe<br>
        456 Client Avenue<br>
        Los Angeles, CA 90001</p>
    </div>

    <table class='invoice-table'>
        <thead>
            <tr>
                <th>Description</th>
                <th>Quantity</th>
                <th>Unit Price</th>
                <th>Total</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Professional Services - Web Development</td>
                <td>40 hours</td>
                <td>$150.00</td>
                <td>$6,000.00</td>
            </tr>
            <tr>
                <td>Hosting Services (Annual)</td>
                <td>1</td>
                <td>$1,200.00</td>
                <td>$1,200.00</td>
            </tr>
            <tr>
                <td>Domain Registration</td>
                <td>2</td>
                <td>$15.00</td>
                <td>$30.00</td>
            </tr>
        </tbody>
    </table>

    <div class='total-section'>
        <div class='total-row'>
            <span class='label'>Subtotal:</span>
            <span>$7,230.00</span>
        </div>
        <div class='total-row'>
            <span class='label'>Tax (8%):</span>
            <span>$578.40</span>
        </div>
        <div class='total-row grand-total'>
            <span class='label'>Total Due:</span>
            <span>$7,808.40</span>
        </div>
    </div>

    <div class='footer' style='margin-top: 50px; padding-top: 20px; border-top: 1px solid #ddd; text-align: center; color: #666;'>
        <p>Thank you for your business!<br>
        Payment is due within 30 days. Please include invoice number with payment.</p>
    </div>
</body>
</html>"

		' Generate PDF with base path for local assets
		Dim pdf = renderer.RenderHtmlAsPdf(invoiceHtml, "C:\Assets\")

		' Add security
		pdf.SecuritySettings.AllowUserEditing = False
		pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights
		pdf.SecuritySettings.OwnerPassword = "admin123"

		' Save with optimization
		pdf.CompressImages(60) ' 60% quality for smaller file size
		pdf.SaveAs("professional-invoice.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

This example showcases:

  • Professional Layout: Complex CSS with flexbox and grid
  • Dynamic Content: Date calculations and formatting
  • Print Optimization: Media queries for print-specific styling
  • Security Features: Password protection and permission settings
  • File Optimization: Image compression for smaller file sizes

Using ABCpdf

ABCpdf's HTML string handling with styled text:

using WebSupergoo.ABCpdf13;

public class ABCpdfHtmlString
{
    public static void CreateStyledDocument()
    {
        using (Doc theDoc = new Doc())
        {
            // Set up the document
            theDoc.Rect.Inset(40, 40);
            theDoc.Color.String = "0 0 0"; // Black text

            // Add styled HTML content
            theDoc.FontSize = 48;
            string styledHtml = @"
                <h1 style='color: #0066cc'>ABCpdf Document</h1>
                <p style='font-size: 14pt; line-height: 1.5'>
                    This demonstrates <b>bold text</b>, <i>italic text</i>, 
                    and <span style='color: red'>colored text</span>.
                </p>
                <ul style='margin-left: 20px'>
                    <li>First item</li>
                    <li>Second item</li>
                    <li>Third item</li>
                </ul>";

            // Add HTML with automatic text flow
            int theID = theDoc.AddImageHtml(styledHtml);

            // Continue on new pages if needed
            while (true)
            {
                if (!theDoc.Chainable(theID))
                    break;
                theDoc.Page = theDoc.AddPage();
                theID = theDoc.AddImageToChain(theID);
            }

            // Apply compression
            theDoc.Encryption.Type = 2; // 128-bit encryption
            theDoc.Encryption.CanPrint = true;
            theDoc.Encryption.CanModify = false;

            theDoc.Save("styled-abcpdf.pdf");
        }
    }
}
using WebSupergoo.ABCpdf13;

public class ABCpdfHtmlString
{
    public static void CreateStyledDocument()
    {
        using (Doc theDoc = new Doc())
        {
            // Set up the document
            theDoc.Rect.Inset(40, 40);
            theDoc.Color.String = "0 0 0"; // Black text

            // Add styled HTML content
            theDoc.FontSize = 48;
            string styledHtml = @"
                <h1 style='color: #0066cc'>ABCpdf Document</h1>
                <p style='font-size: 14pt; line-height: 1.5'>
                    This demonstrates <b>bold text</b>, <i>italic text</i>, 
                    and <span style='color: red'>colored text</span>.
                </p>
                <ul style='margin-left: 20px'>
                    <li>First item</li>
                    <li>Second item</li>
                    <li>Third item</li>
                </ul>";

            // Add HTML with automatic text flow
            int theID = theDoc.AddImageHtml(styledHtml);

            // Continue on new pages if needed
            while (true)
            {
                if (!theDoc.Chainable(theID))
                    break;
                theDoc.Page = theDoc.AddPage();
                theID = theDoc.AddImageToChain(theID);
            }

            // Apply compression
            theDoc.Encryption.Type = 2; // 128-bit encryption
            theDoc.Encryption.CanPrint = true;
            theDoc.Encryption.CanModify = false;

            theDoc.Save("styled-abcpdf.pdf");
        }
    }
}
Imports WebSupergoo.ABCpdf13

Public Class ABCpdfHtmlString
	Public Shared Sub CreateStyledDocument()
		Using theDoc As New Doc()
			' Set up the document
			theDoc.Rect.Inset(40, 40)
			theDoc.Color.String = "0 0 0" ' Black text

			' Add styled HTML content
			theDoc.FontSize = 48
			Dim styledHtml As String = "
                <h1 style='color: #0066cc'>ABCpdf Document</h1>
                <p style='font-size: 14pt; line-height: 1.5'>
                    This demonstrates <b>bold text</b>, <i>italic text</i>, 
                    and <span style='color: red'>colored text</span>.
                </p>
                <ul style='margin-left: 20px'>
                    <li>First item</li>
                    <li>Second item</li>
                    <li>Third item</li>
                </ul>"

			' Add HTML with automatic text flow
			Dim theID As Integer = theDoc.AddImageHtml(styledHtml)

			' Continue on new pages if needed
			Do
				If Not theDoc.Chainable(theID) Then
					Exit Do
				End If
				theDoc.Page = theDoc.AddPage()
				theID = theDoc.AddImageToChain(theID)
			Loop

			' Apply compression
			theDoc.Encryption.Type = 2 ' 128-bit encryption
			theDoc.Encryption.CanPrint = True
			theDoc.Encryption.CanModify = False

			theDoc.Save("styled-abcpdf.pdf")
		End Using
	End Sub
End Class
$vbLabelText   $csharpLabel

Performance Benchmarking

Understanding performance characteristics helps in choosing the right library for your specific use case.

Benchmark Test Setup

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using IronPdf;
using WebSupergoo.ABCpdf13;

[MemoryDiagnoser]
[SimpleJob(warmupCount: 3, targetCount: 10)]
public class PdfGenerationBenchmark
{
    private string _simpleHtml;
    private string _complexHtml;
    private ChromePdfRenderer _ironPdfRenderer;
    private Doc _abcPdfDoc;

    [GlobalSetup]
    public void Setup()
    {
        _simpleHtml = "<h1>Simple Document</h1><p>Basic paragraph text.</p>";
        _complexHtml = File.ReadAllText("complex-page.html"); // 50KB HTML with CSS/JS

        _ironPdfRenderer = new ChromePdfRenderer();
        _abcPdfDoc = new Doc();
        _abcPdfDoc.HtmlOptions.Engine = EngineType.Chrome;
    }

    [Benchmark]
    public void IronPDF_SimpleHtml()
    {
        var pdf = _ironPdfRenderer.RenderHtmlAsPdf(_simpleHtml);
        pdf.SaveAs("temp_iron_simple.pdf");
    }

    [Benchmark]
    public void ABCpdf_SimpleHtml()
    {
        _abcPdfDoc.Clear();
        _abcPdfDoc.AddImageHtml(_simpleHtml);
        _abcPdfDoc.Save("temp_abc_simple.pdf");
    }

    [Benchmark]
    public void IronPDF_ComplexHtml()
    {
        var pdf = _ironPdfRenderer.RenderHtmlAsPdf(_complexHtml);
        pdf.SaveAs("temp_iron_complex.pdf");
    }

    [Benchmark]
    public void ABCpdf_ComplexHtml()
    {
        _abcPdfDoc.Clear();
        int id = _abcPdfDoc.AddImageHtml(_complexHtml);
        while (_abcPdfDoc.Chainable(id))
        {
            _abcPdfDoc.Page = _abcPdfDoc.AddPage();
            id = _abcPdfDoc.AddImageToChain(id);
        }
        _abcPdfDoc.Save("temp_abc_complex.pdf");
    }
}
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using IronPdf;
using WebSupergoo.ABCpdf13;

[MemoryDiagnoser]
[SimpleJob(warmupCount: 3, targetCount: 10)]
public class PdfGenerationBenchmark
{
    private string _simpleHtml;
    private string _complexHtml;
    private ChromePdfRenderer _ironPdfRenderer;
    private Doc _abcPdfDoc;

    [GlobalSetup]
    public void Setup()
    {
        _simpleHtml = "<h1>Simple Document</h1><p>Basic paragraph text.</p>";
        _complexHtml = File.ReadAllText("complex-page.html"); // 50KB HTML with CSS/JS

        _ironPdfRenderer = new ChromePdfRenderer();
        _abcPdfDoc = new Doc();
        _abcPdfDoc.HtmlOptions.Engine = EngineType.Chrome;
    }

    [Benchmark]
    public void IronPDF_SimpleHtml()
    {
        var pdf = _ironPdfRenderer.RenderHtmlAsPdf(_simpleHtml);
        pdf.SaveAs("temp_iron_simple.pdf");
    }

    [Benchmark]
    public void ABCpdf_SimpleHtml()
    {
        _abcPdfDoc.Clear();
        _abcPdfDoc.AddImageHtml(_simpleHtml);
        _abcPdfDoc.Save("temp_abc_simple.pdf");
    }

    [Benchmark]
    public void IronPDF_ComplexHtml()
    {
        var pdf = _ironPdfRenderer.RenderHtmlAsPdf(_complexHtml);
        pdf.SaveAs("temp_iron_complex.pdf");
    }

    [Benchmark]
    public void ABCpdf_ComplexHtml()
    {
        _abcPdfDoc.Clear();
        int id = _abcPdfDoc.AddImageHtml(_complexHtml);
        while (_abcPdfDoc.Chainable(id))
        {
            _abcPdfDoc.Page = _abcPdfDoc.AddPage();
            id = _abcPdfDoc.AddImageToChain(id);
        }
        _abcPdfDoc.Save("temp_abc_complex.pdf");
    }
}
Imports BenchmarkDotNet.Attributes
Imports BenchmarkDotNet.Running
Imports IronPdf
Imports WebSupergoo.ABCpdf13

<MemoryDiagnoser>
<SimpleJob(warmupCount:= 3, targetCount:= 10)>
Public Class PdfGenerationBenchmark
	Private _simpleHtml As String
	Private _complexHtml As String
	Private _ironPdfRenderer As ChromePdfRenderer
	Private _abcPdfDoc As Doc

	<GlobalSetup>
	Public Sub Setup()
		_simpleHtml = "<h1>Simple Document</h1><p>Basic paragraph text.</p>"
		_complexHtml = File.ReadAllText("complex-page.html") ' 50KB HTML with CSS/JS

		_ironPdfRenderer = New ChromePdfRenderer()
		_abcPdfDoc = New Doc()
		_abcPdfDoc.HtmlOptions.Engine = EngineType.Chrome
	End Sub

	<Benchmark>
	Public Sub IronPDF_SimpleHtml()
		Dim pdf = _ironPdfRenderer.RenderHtmlAsPdf(_simpleHtml)
		pdf.SaveAs("temp_iron_simple.pdf")
	End Sub

	<Benchmark>
	Public Sub ABCpdf_SimpleHtml()
		_abcPdfDoc.Clear()
		_abcPdfDoc.AddImageHtml(_simpleHtml)
		_abcPdfDoc.Save("temp_abc_simple.pdf")
	End Sub

	<Benchmark>
	Public Sub IronPDF_ComplexHtml()
		Dim pdf = _ironPdfRenderer.RenderHtmlAsPdf(_complexHtml)
		pdf.SaveAs("temp_iron_complex.pdf")
	End Sub

	<Benchmark>
	Public Sub ABCpdf_ComplexHtml()
		_abcPdfDoc.Clear()
		Dim id As Integer = _abcPdfDoc.AddImageHtml(_complexHtml)
		Do While _abcPdfDoc.Chainable(id)
			_abcPdfDoc.Page = _abcPdfDoc.AddPage()
			id = _abcPdfDoc.AddImageToChain(id)
		Loop
		_abcPdfDoc.Save("temp_abc_complex.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Typical Results

Method Mean Error StdDev Memory
IronPDF_SimpleHtml 245.3 ms 4.2 ms 3.8 ms 152 MB
ABCpdf_SimpleHtml 187.6 ms 3.1 ms 2.9 ms 98 MB
IronPDF_ComplexHtml 892.4 ms 12.3 ms 10.8 ms 201 MB
ABCpdf_ComplexHtml 743.2 ms 9.7 ms 8.6 ms 145 MB

Key observations:

  • ABCpdf shows faster raw conversion times
  • IronPDF uses more memory due to full Chrome engine
  • Both libraries scale linearly with document complexity
  • IronPDF's overhead provides better rendering accuracy

Advanced Features Comparison

Digital Signatures and Security

IronPDF Digital Signature Implementation

using IronPdf;
using IronPdf.Signing;
using System.Security.Cryptography.X509Certificates;

public class SecurityFeatures
{
    public static void ApplyDigitalSignature()
    {
        // Load existing PDF
        var pdf = PdfDocument.FromFile("unsigned-document.pdf");

        // Load certificate
        var cert = new X509Certificate2("certificate.pfx", "password");

        // Create signature
        var signature = new PdfSignature(cert)
        {
            // Visual signature appearance
            SignatureImage = new PdfSignature.SignatureImage
            {
                ImagePath = "signature.png",
                Width = 200,
                Height = 100
            },

            // Signature position
            PageIndex = 0,
            X = 400,
            Y = 100,

            // Signature details
            Reason = "Document approved",
            Location = "New York, NY",
            ContactInfo = "john.doe@company.com"
        };

        // Apply signature
        pdf.Sign(signature);

        // Additional security
        pdf.SecuritySettings = new SecuritySettings
        {
            AllowUserPrinting = true,
            AllowUserCopyPasteContent = false,
            AllowUserEditing = false,
            AllowUserFormData = true,
            OwnerPassword = "owner123",
            UserPassword = "user123",
            EncryptionLevel = EncryptionLevel.AES256
        };

        pdf.SaveAs("signed-secured.pdf");
    }
}
using IronPdf;
using IronPdf.Signing;
using System.Security.Cryptography.X509Certificates;

public class SecurityFeatures
{
    public static void ApplyDigitalSignature()
    {
        // Load existing PDF
        var pdf = PdfDocument.FromFile("unsigned-document.pdf");

        // Load certificate
        var cert = new X509Certificate2("certificate.pfx", "password");

        // Create signature
        var signature = new PdfSignature(cert)
        {
            // Visual signature appearance
            SignatureImage = new PdfSignature.SignatureImage
            {
                ImagePath = "signature.png",
                Width = 200,
                Height = 100
            },

            // Signature position
            PageIndex = 0,
            X = 400,
            Y = 100,

            // Signature details
            Reason = "Document approved",
            Location = "New York, NY",
            ContactInfo = "john.doe@company.com"
        };

        // Apply signature
        pdf.Sign(signature);

        // Additional security
        pdf.SecuritySettings = new SecuritySettings
        {
            AllowUserPrinting = true,
            AllowUserCopyPasteContent = false,
            AllowUserEditing = false,
            AllowUserFormData = true,
            OwnerPassword = "owner123",
            UserPassword = "user123",
            EncryptionLevel = EncryptionLevel.AES256
        };

        pdf.SaveAs("signed-secured.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Signing
Imports System.Security.Cryptography.X509Certificates

Public Class SecurityFeatures
	Public Shared Sub ApplyDigitalSignature()
		' Load existing PDF
		Dim pdf = PdfDocument.FromFile("unsigned-document.pdf")

		' Load certificate
		Dim cert = New X509Certificate2("certificate.pfx", "password")

		' Create signature
		Dim signature = New PdfSignature(cert) With {
			.SignatureImage = New PdfSignature.SignatureImage With {
				.ImagePath = "signature.png",
				.Width = 200,
				.Height = 100
			},
			.PageIndex = 0,
			.X = 400,
			.Y = 100,
			.Reason = "Document approved",
			.Location = "New York, NY",
			.ContactInfo = "john.doe@company.com"
		}

		' Apply signature
		pdf.Sign(signature)

		' Additional security
		pdf.SecuritySettings = New SecuritySettings With {
			.AllowUserPrinting = True,
			.AllowUserCopyPasteContent = False,
			.AllowUserEditing = False,
			.AllowUserFormData = True,
			.OwnerPassword = "owner123",
			.UserPassword = "user123",
			.EncryptionLevel = EncryptionLevel.AES256
		}

		pdf.SaveAs("signed-secured.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

ABCpdf Digital Signature Implementation

using WebSupergoo.ABCpdf13;
using WebSupergoo.ABCpdf13.Objects;

public class ABCpdfSecurity
{
    public static void SignDocument()
    {
        using (Doc theDoc = new Doc())
        {
            theDoc.Read("unsigned-document.pdf");

            // Create signature field
            Field signatureField = theDoc.Form.AddFieldSignature("AuthorSignature");
            signatureField.Page = 1;
            signatureField.Rect = "400 100 600 200";

            // Configure signature
            Signature theSig = signatureField.Sign();
            theSig.Reason = "Document approved";
            theSig.Location = "New York, NY";
            theSig.ContactInfo = "john.doe@company.com";

            // Load certificate
            theSig.LoadCertificate("certificate.pfx", "password");

            // Apply visual signature
            theSig.Visible = true;
            theSig.Image = theDoc.AddImageFile("signature.png");

            // Sign and save
            theDoc.Save("abcpdf-signed.pdf");
        }
    }
}
using WebSupergoo.ABCpdf13;
using WebSupergoo.ABCpdf13.Objects;

public class ABCpdfSecurity
{
    public static void SignDocument()
    {
        using (Doc theDoc = new Doc())
        {
            theDoc.Read("unsigned-document.pdf");

            // Create signature field
            Field signatureField = theDoc.Form.AddFieldSignature("AuthorSignature");
            signatureField.Page = 1;
            signatureField.Rect = "400 100 600 200";

            // Configure signature
            Signature theSig = signatureField.Sign();
            theSig.Reason = "Document approved";
            theSig.Location = "New York, NY";
            theSig.ContactInfo = "john.doe@company.com";

            // Load certificate
            theSig.LoadCertificate("certificate.pfx", "password");

            // Apply visual signature
            theSig.Visible = true;
            theSig.Image = theDoc.AddImageFile("signature.png");

            // Sign and save
            theDoc.Save("abcpdf-signed.pdf");
        }
    }
}
Imports WebSupergoo.ABCpdf13
Imports WebSupergoo.ABCpdf13.Objects

Public Class ABCpdfSecurity
	Public Shared Sub SignDocument()
		Using theDoc As New Doc()
			theDoc.Read("unsigned-document.pdf")

			' Create signature field
			Dim signatureField As Field = theDoc.Form.AddFieldSignature("AuthorSignature")
			signatureField.Page = 1
			signatureField.Rect = "400 100 600 200"

			' Configure signature
			Dim theSig As Signature = signatureField.Sign()
			theSig.Reason = "Document approved"
			theSig.Location = "New York, NY"
			theSig.ContactInfo = "john.doe@company.com"

			' Load certificate
			theSig.LoadCertificate("certificate.pfx", "password")

			' Apply visual signature
			theSig.Visible = True
			theSig.Image = theDoc.AddImageFile("signature.png")

			' Sign and save
			theDoc.Save("abcpdf-signed.pdf")
		End Using
	End Sub
End Class
$vbLabelText   $csharpLabel

Form Handling and Data Extraction

IronPDF Form Management

public class FormHandling
{
    public static void WorkWithForms()
    {
        // Create PDF with form fields from HTML
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

        string formHtml = @"
        <form>
            <label>Name: <input type='text' name='fullname' required></label><br>
            <label>Email: <input type='email' name='email' required></label><br>
            <label>Subscribe: <input type='checkbox' name='subscribe' value='yes'></label><br>
            <label>Country: 
                <select name='country'>
                    <option>USA</option>
                    <option>Canada</option>
                    <option>UK</option>
                </select>
            </label><br>
            <button type='submit'>Submit</button>
        </form>";

        var pdf = renderer.RenderHtmlAsPdf(formHtml);

        // Fill form programmatically
        pdf.Form.Fields["fullname"].Value = "John Doe";
        pdf.Form.Fields["email"].Value = "john@example.com";
        pdf.Form.Fields["subscribe"].Value = "yes";
        pdf.Form.Fields["country"].Value = "USA";

        // Extract form data
        foreach (var field in pdf.Form.Fields)
        {
            Console.WriteLine($"{field.Name}: {field.Value}");
        }

        // Flatten form (make non-editable)
        pdf.Form.Flatten();
        pdf.SaveAs("filled-form.pdf");
    }
}
public class FormHandling
{
    public static void WorkWithForms()
    {
        // Create PDF with form fields from HTML
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.CreatePdfFormsFromHtml = true;

        string formHtml = @"
        <form>
            <label>Name: <input type='text' name='fullname' required></label><br>
            <label>Email: <input type='email' name='email' required></label><br>
            <label>Subscribe: <input type='checkbox' name='subscribe' value='yes'></label><br>
            <label>Country: 
                <select name='country'>
                    <option>USA</option>
                    <option>Canada</option>
                    <option>UK</option>
                </select>
            </label><br>
            <button type='submit'>Submit</button>
        </form>";

        var pdf = renderer.RenderHtmlAsPdf(formHtml);

        // Fill form programmatically
        pdf.Form.Fields["fullname"].Value = "John Doe";
        pdf.Form.Fields["email"].Value = "john@example.com";
        pdf.Form.Fields["subscribe"].Value = "yes";
        pdf.Form.Fields["country"].Value = "USA";

        // Extract form data
        foreach (var field in pdf.Form.Fields)
        {
            Console.WriteLine($"{field.Name}: {field.Value}");
        }

        // Flatten form (make non-editable)
        pdf.Form.Flatten();
        pdf.SaveAs("filled-form.pdf");
    }
}
Public Class FormHandling
	Public Shared Sub WorkWithForms()
		' Create PDF with form fields from HTML
		Dim renderer = New ChromePdfRenderer()
		renderer.RenderingOptions.CreatePdfFormsFromHtml = True

		Dim formHtml As String = "
        <form>
            <label>Name: <input type='text' name='fullname' required></label><br>
            <label>Email: <input type='email' name='email' required></label><br>
            <label>Subscribe: <input type='checkbox' name='subscribe' value='yes'></label><br>
            <label>Country: 
                <select name='country'>
                    <option>USA</option>
                    <option>Canada</option>
                    <option>UK</option>
                </select>
            </label><br>
            <button type='submit'>Submit</button>
        </form>"

		Dim pdf = renderer.RenderHtmlAsPdf(formHtml)

		' Fill form programmatically
		pdf.Form.Fields("fullname").Value = "John Doe"
		pdf.Form.Fields("email").Value = "john@example.com"
		pdf.Form.Fields("subscribe").Value = "yes"
		pdf.Form.Fields("country").Value = "USA"

		' Extract form data
		For Each field In pdf.Form.Fields
			Console.WriteLine($"{field.Name}: {field.Value}")
		Next field

		' Flatten form (make non-editable)
		pdf.Form.Flatten()
		pdf.SaveAs("filled-form.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Batch Processing and Optimization

IronPDF Batch Processing

using System.Threading.Tasks;
using System.Collections.Concurrent;

public class BatchProcessing
{
    public static async Task ProcessMultipleDocumentsAsync(List<string> htmlFiles)
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

        // Use concurrent processing
        var pdfResults = new ConcurrentBag<(string filename, byte[] data)>();

        await Parallel.ForEachAsync(htmlFiles, async (htmlFile, ct) =>
        {
            try
            {
                var html = await File.ReadAllTextAsync(htmlFile);
                var pdf = await renderer.RenderHtmlAsPdfAsync(html);

                // Optimize each PDF
                pdf.CompressImages(70);

                var filename = Path.GetFileNameWithoutExtension(htmlFile) + ".pdf";
                var data = pdf.BinaryData;

                pdfResults.Add((filename, data));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error processing {htmlFile}: {ex.Message}");
            }
        });

        // Merge all PDFs into one
        var finalPdf = new PdfDocument();
        foreach (var (filename, data) in pdfResults.OrderBy(x => x.filename))
        {
            var pdf = new PdfDocument(data);
            finalPdf.AppendPdf(pdf);
        }

        finalPdf.SaveAs("batch-processed.pdf");
    }
}
using System.Threading.Tasks;
using System.Collections.Concurrent;

public class BatchProcessing
{
    public static async Task ProcessMultipleDocumentsAsync(List<string> htmlFiles)
    {
        var renderer = new ChromePdfRenderer();
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;

        // Use concurrent processing
        var pdfResults = new ConcurrentBag<(string filename, byte[] data)>();

        await Parallel.ForEachAsync(htmlFiles, async (htmlFile, ct) =>
        {
            try
            {
                var html = await File.ReadAllTextAsync(htmlFile);
                var pdf = await renderer.RenderHtmlAsPdfAsync(html);

                // Optimize each PDF
                pdf.CompressImages(70);

                var filename = Path.GetFileNameWithoutExtension(htmlFile) + ".pdf";
                var data = pdf.BinaryData;

                pdfResults.Add((filename, data));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error processing {htmlFile}: {ex.Message}");
            }
        });

        // Merge all PDFs into one
        var finalPdf = new PdfDocument();
        foreach (var (filename, data) in pdfResults.OrderBy(x => x.filename))
        {
            var pdf = new PdfDocument(data);
            finalPdf.AppendPdf(pdf);
        }

        finalPdf.SaveAs("batch-processed.pdf");
    }
}
Imports System.Threading.Tasks
Imports System.Collections.Concurrent

Public Class BatchProcessing
	Public Shared Async Function ProcessMultipleDocumentsAsync(ByVal htmlFiles As List(Of String)) As Task
		Dim renderer = New ChromePdfRenderer()
		renderer.RenderingOptions.PaperSize = PdfPaperSize.A4

		' Use concurrent processing
		Dim pdfResults = New ConcurrentBag(Of (filename As String, data As Byte()))()

		Await Parallel.ForEachAsync(htmlFiles, Async Sub(htmlFile, ct)
			Try
				Dim html = Await File.ReadAllTextAsync(htmlFile)
				Dim pdf = Await renderer.RenderHtmlAsPdfAsync(html)

				' Optimize each PDF
				pdf.CompressImages(70)

				Dim filename = Path.GetFileNameWithoutExtension(htmlFile) & ".pdf"
				Dim data = pdf.BinaryData

				pdfResults.Add((filename, data))
			Catch ex As Exception
				Console.WriteLine($"Error processing {htmlFile}: {ex.Message}")
			End Try
		End Sub)

		' Merge all PDFs into one
		Dim finalPdf = New PdfDocument()
		foreach var(filename, data) In pdfResults.OrderBy(Function(x) x.filename)
			Dim pdf = New PdfDocument(data)
			finalPdf.AppendPdf(pdf)
		Next 

		finalPdf.SaveAs("batch-processed.pdf")
	End Function
End Class
$vbLabelText   $csharpLabel

Real-World Use Case Scenarios

Which Library Fits Your Project Better?

Choose IronPDF When:

  1. Building Cloud-Native Applications

    • Native Docker support with minimal configuration
    • Azure Functions and AWS Lambda compatibility
    • Consistent behavior across all cloud platforms
  2. Requiring Pixel-Perfect HTML Rendering

    • Complex CSS layouts (Grid, Flexbox)
    • JavaScript-heavy single-page applications
    • Web font requirements
  3. Developing Cross-Platform Solutions

    • Applications targeting Windows, Linux, and macOS
    • Microservices architecture
    • Container-based deployments
  4. Prioritizing Developer Experience
    • Rapid prototyping needs
    • Small development teams
    • Limited PDF expertise

Choose ABCpdf When:

  1. Working with Legacy Systems

    • Windows-only environments
    • Existing ABCpdf implementations
    • IE-compatible content requirements
  2. Requiring Specific Rendering Engines

    • Testing across different browsers
    • Engine-specific optimizations
    • Legacy browser support
  3. Advanced PDF Manipulation

    • Low-level PDF object access
    • Custom PDF operators
    • Complex document merging scenarios
  4. Budget-Conscious Projects
    • Lower entry price point
    • Single-developer licenses
    • 32-bit environment compatibility

Troubleshooting Common Issues

IronPDF Common Issues and Solutions

public class IronPdfTroubleshooting
{
    // Issue: Fonts not rendering correctly
    public static void FixFontIssues()
    {
        var renderer = new ChromePdfRenderer();

        // Solution 1: Wait for fonts to load
        renderer.RenderingOptions.WaitFor.RenderDelay(1000);

        // Solution 2: Use system fonts fallback
        renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
    }

    // Issue: JavaScript not executing
    public static void FixJavaScriptIssues()
    {
        var renderer = new ChromePdfRenderer();

        // Enable JavaScript and wait for execution
        renderer.RenderingOptions.EnableJavaScript = true;
        renderer.RenderingOptions.WaitFor.JavaScriptFinishDelay = 2000;
        renderer.RenderingOptions.WaitFor.AllowedExecutionTime = 30000;
    }

    // Issue: Memory usage in Docker
    public static void OptimizeForDocker()
    {
        var renderer = new ChromePdfRenderer();

        // Use single-threaded mode for containers
        IronPdf.Installation.SingleThreaded = true;

        // Reduce memory footprint
        renderer.RenderingOptions.ViewPortWidth = 1024;
        renderer.RenderingOptions.EnableGrayscale = true;
    }
}
public class IronPdfTroubleshooting
{
    // Issue: Fonts not rendering correctly
    public static void FixFontIssues()
    {
        var renderer = new ChromePdfRenderer();

        // Solution 1: Wait for fonts to load
        renderer.RenderingOptions.WaitFor.RenderDelay(1000);

        // Solution 2: Use system fonts fallback
        renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
    }

    // Issue: JavaScript not executing
    public static void FixJavaScriptIssues()
    {
        var renderer = new ChromePdfRenderer();

        // Enable JavaScript and wait for execution
        renderer.RenderingOptions.EnableJavaScript = true;
        renderer.RenderingOptions.WaitFor.JavaScriptFinishDelay = 2000;
        renderer.RenderingOptions.WaitFor.AllowedExecutionTime = 30000;
    }

    // Issue: Memory usage in Docker
    public static void OptimizeForDocker()
    {
        var renderer = new ChromePdfRenderer();

        // Use single-threaded mode for containers
        IronPdf.Installation.SingleThreaded = true;

        // Reduce memory footprint
        renderer.RenderingOptions.ViewPortWidth = 1024;
        renderer.RenderingOptions.EnableGrayscale = true;
    }
}
Public Class IronPdfTroubleshooting
	' Issue: Fonts not rendering correctly
	Public Shared Sub FixFontIssues()
		Dim renderer = New ChromePdfRenderer()

		' Solution 1: Wait for fonts to load
		renderer.RenderingOptions.WaitFor.RenderDelay(1000)

		' Solution 2: Use system fonts fallback
		renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print
	End Sub

	' Issue: JavaScript not executing
	Public Shared Sub FixJavaScriptIssues()
		Dim renderer = New ChromePdfRenderer()

		' Enable JavaScript and wait for execution
		renderer.RenderingOptions.EnableJavaScript = True
		renderer.RenderingOptions.WaitFor.JavaScriptFinishDelay = 2000
		renderer.RenderingOptions.WaitFor.AllowedExecutionTime = 30000
	End Sub

	' Issue: Memory usage in Docker
	Public Shared Sub OptimizeForDocker()
		Dim renderer = New ChromePdfRenderer()

		' Use single-threaded mode for containers
		IronPdf.Installation.SingleThreaded = True

		' Reduce memory footprint
		renderer.RenderingOptions.ViewPortWidth = 1024
		renderer.RenderingOptions.EnableGrayscale = True
	End Sub
End Class
$vbLabelText   $csharpLabel

ABCpdf Common Issues and Solutions

public class ABCpdfTroubleshooting
{
    // Issue: Page breaks in wrong places
    public static void FixPageBreaks()
    {
        using (Doc theDoc = new Doc())
        {
            // Use HTML page break controls
            theDoc.HtmlOptions.BreakZoneSize = 100; // pixels
            theDoc.HtmlOptions.UseScript = true;

            string html = @"
                <style>
                    .page-break { page-break-after: always; }
                    .no-break { page-break-inside: avoid; }
                </style>
                <div class='no-break'>Keep this content together</div>
                <div class='page-break'></div>
                <div>New page content</div>";

            theDoc.AddImageHtml(html);
            theDoc.Save("fixed-breaks.pdf");
        }
    }

    // Issue: Images not loading
    public static void FixImageLoading()
    {
        using (Doc theDoc = new Doc())
        {
            // Set timeout and authentication
            theDoc.HtmlOptions.Timeout = 60000; // 60 seconds
            theDoc.HtmlOptions.RetryCount = 3;

            // For local images, set base directory
            theDoc.HtmlOptions.BaseUrl = @"file:///C:/Images/";

            theDoc.AddImageHtml("<img src='logo.png'>");
            theDoc.Save("with-images.pdf");
        }
    }
}
public class ABCpdfTroubleshooting
{
    // Issue: Page breaks in wrong places
    public static void FixPageBreaks()
    {
        using (Doc theDoc = new Doc())
        {
            // Use HTML page break controls
            theDoc.HtmlOptions.BreakZoneSize = 100; // pixels
            theDoc.HtmlOptions.UseScript = true;

            string html = @"
                <style>
                    .page-break { page-break-after: always; }
                    .no-break { page-break-inside: avoid; }
                </style>
                <div class='no-break'>Keep this content together</div>
                <div class='page-break'></div>
                <div>New page content</div>";

            theDoc.AddImageHtml(html);
            theDoc.Save("fixed-breaks.pdf");
        }
    }

    // Issue: Images not loading
    public static void FixImageLoading()
    {
        using (Doc theDoc = new Doc())
        {
            // Set timeout and authentication
            theDoc.HtmlOptions.Timeout = 60000; // 60 seconds
            theDoc.HtmlOptions.RetryCount = 3;

            // For local images, set base directory
            theDoc.HtmlOptions.BaseUrl = @"file:///C:/Images/";

            theDoc.AddImageHtml("<img src='logo.png'>");
            theDoc.Save("with-images.pdf");
        }
    }
}
Public Class ABCpdfTroubleshooting
	' Issue: Page breaks in wrong places
	Public Shared Sub FixPageBreaks()
		Using theDoc As New Doc()
			' Use HTML page break controls
			theDoc.HtmlOptions.BreakZoneSize = 100 ' pixels
			theDoc.HtmlOptions.UseScript = True

			Dim html As String = "
                <style>
                    .page-break { page-break-after: always; }
                    .no-break { page-break-inside: avoid; }
                </style>
                <div class='no-break'>Keep this content together</div>
                <div class='page-break'></div>
                <div>New page content</div>"

			theDoc.AddImageHtml(html)
			theDoc.Save("fixed-breaks.pdf")
		End Using
	End Sub

	' Issue: Images not loading
	Public Shared Sub FixImageLoading()
		Using theDoc As New Doc()
			' Set timeout and authentication
			theDoc.HtmlOptions.Timeout = 60000 ' 60 seconds
			theDoc.HtmlOptions.RetryCount = 3

			' For local images, set base directory
			theDoc.HtmlOptions.BaseUrl = "file:///C:/Images/"

			theDoc.AddImageHtml("<img src='logo.png'>")
			theDoc.Save("with-images.pdf")
		End Using
	End Sub
End Class
$vbLabelText   $csharpLabel

Migration Guide: Moving Between Libraries

Migrating from ABCpdf to IronPDF

public class MigrationHelper
{
    // ABCpdf code
    public void OldABCpdfMethod()
    {
        Doc theDoc = new Doc();
        theDoc.AddImageUrl("https://example.com");
        theDoc.Save("output.pdf");
        theDoc.Dispose();
    }

    // Equivalent IronPDF code
    public void NewIronPdfMethod()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.SaveAs("output.pdf");
    }

    // Migration wrapper for gradual transition
    public class PdfWrapper
    {
        private bool _useIronPdf;

        public PdfWrapper(bool useIronPdf = true)
        {
            _useIronPdf = useIronPdf;
        }

        public void ConvertUrlToPdf(string url, string outputPath)
        {
            if (_useIronPdf)
            {
                var renderer = new ChromePdfRenderer();
                var pdf = renderer.RenderUrlAsPdf(url);
                pdf.SaveAs(outputPath);
            }
            else
            {
                using (var doc = new Doc())
                {
                    doc.AddImageUrl(url);
                    doc.Save(outputPath);
                }
            }
        }
    }
}
public class MigrationHelper
{
    // ABCpdf code
    public void OldABCpdfMethod()
    {
        Doc theDoc = new Doc();
        theDoc.AddImageUrl("https://example.com");
        theDoc.Save("output.pdf");
        theDoc.Dispose();
    }

    // Equivalent IronPDF code
    public void NewIronPdfMethod()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://example.com");
        pdf.SaveAs("output.pdf");
    }

    // Migration wrapper for gradual transition
    public class PdfWrapper
    {
        private bool _useIronPdf;

        public PdfWrapper(bool useIronPdf = true)
        {
            _useIronPdf = useIronPdf;
        }

        public void ConvertUrlToPdf(string url, string outputPath)
        {
            if (_useIronPdf)
            {
                var renderer = new ChromePdfRenderer();
                var pdf = renderer.RenderUrlAsPdf(url);
                pdf.SaveAs(outputPath);
            }
            else
            {
                using (var doc = new Doc())
                {
                    doc.AddImageUrl(url);
                    doc.Save(outputPath);
                }
            }
        }
    }
}
Public Class MigrationHelper
	' ABCpdf code
	Public Sub OldABCpdfMethod()
		Dim theDoc As New Doc()
		theDoc.AddImageUrl("https://example.com")
		theDoc.Save("output.pdf")
		theDoc.Dispose()
	End Sub

	' Equivalent IronPDF code
	Public Sub NewIronPdfMethod()
		Dim renderer = New ChromePdfRenderer()
		Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
		pdf.SaveAs("output.pdf")
	End Sub

	' Migration wrapper for gradual transition
	Public Class PdfWrapper
		Private _useIronPdf As Boolean

		Public Sub New(Optional ByVal useIronPdf As Boolean = True)
			_useIronPdf = useIronPdf
		End Sub

		Public Sub ConvertUrlToPdf(ByVal url As String, ByVal outputPath As String)
			If _useIronPdf Then
				Dim renderer = New ChromePdfRenderer()
				Dim pdf = renderer.RenderUrlAsPdf(url)
				pdf.SaveAs(outputPath)
			Else
				Using doc As New Doc()
					doc.AddImageUrl(url)
					doc.Save(outputPath)
				End Using
			End If
		End Sub
	End Class
End Class
$vbLabelText   $csharpLabel

Licensing and Total Cost of Ownership

Calculating ROI for Your Project

When evaluating PDF libraries, consider the total cost beyond the license price:

IronPDF Cost Analysis

  • Development Time Savings: 50-70% faster implementation
  • Support Costs: Included 24/5 engineering support
  • Maintenance: Unified API across platforms
  • Scalability: Single license covers multiple deployments

ABCpdf Cost Analysis

  • Initial Cost: Lower entry price
  • Hidden Costs:
    • Separate 64-bit license
    • Multiple engine requirements
    • Platform-specific testing
    • Additional support costs

License Comparison Calculator

public class LicenseCostCalculator
{
    public static void CalculateTotalCost()
    {
        // Scenario: 5-developer team, 3-year project

        // IronPDF Professional
        var ironPdfCost = new
        {
            License = 2999, // 10 developers, 10 projects
            Support = 0, // Included
            Training = 500, // Minimal due to simple API
            ThreeYearTotal = 3499
        };

        // ABCpdf equivalent setup
        var abcPdfCost = new
        {
            StandardLicenses = 329 * 5, // 5 developers
            ProfessionalUpgrade = 150 * 5, // 64-bit support
            RedistributionLicense = 4790, // Enterprise
            Support = 399 * 3, // Annual support
            Training = 2000, // Complex API training
            ThreeYearTotal = 1645 + 750 + 4790 + 1197 + 2000
        };

        Console.WriteLine($"IronPDF 3-year TCO: ${ironPdfCost.ThreeYearTotal:N0}");
        Console.WriteLine($"ABCpdf 3-year TCO: ${abcPdfCost.ThreeYearTotal:N0}");
        Console.WriteLine($"Savings with IronPDF: ${abcPdfCost.ThreeYearTotal - ironPdfCost.ThreeYearTotal:N0}");
    }
}
public class LicenseCostCalculator
{
    public static void CalculateTotalCost()
    {
        // Scenario: 5-developer team, 3-year project

        // IronPDF Professional
        var ironPdfCost = new
        {
            License = 2999, // 10 developers, 10 projects
            Support = 0, // Included
            Training = 500, // Minimal due to simple API
            ThreeYearTotal = 3499
        };

        // ABCpdf equivalent setup
        var abcPdfCost = new
        {
            StandardLicenses = 329 * 5, // 5 developers
            ProfessionalUpgrade = 150 * 5, // 64-bit support
            RedistributionLicense = 4790, // Enterprise
            Support = 399 * 3, // Annual support
            Training = 2000, // Complex API training
            ThreeYearTotal = 1645 + 750 + 4790 + 1197 + 2000
        };

        Console.WriteLine($"IronPDF 3-year TCO: ${ironPdfCost.ThreeYearTotal:N0}");
        Console.WriteLine($"ABCpdf 3-year TCO: ${abcPdfCost.ThreeYearTotal:N0}");
        Console.WriteLine($"Savings with IronPDF: ${abcPdfCost.ThreeYearTotal - ironPdfCost.ThreeYearTotal:N0}");
    }
}
Public Class LicenseCostCalculator
	Public Shared Sub CalculateTotalCost()
		' Scenario: 5-developer team, 3-year project

		' IronPDF Professional
		Dim ironPdfCost = New With {
			Key .License = 2999,
			Key .Support = 0,
			Key .Training = 500,
			Key .ThreeYearTotal = 3499
		}

		' ABCpdf equivalent setup
		Dim abcPdfCost = New With {
			Key .StandardLicenses = 329 * 5,
			Key .ProfessionalUpgrade = 150 * 5,
			Key .RedistributionLicense = 4790,
			Key .Support = 399 * 3,
			Key .Training = 2000,
			Key .ThreeYearTotal = 1645 + 750 + 4790 + 1197 + 2000
		}

		Console.WriteLine($"IronPDF 3-year TCO: ${ironPdfCost.ThreeYearTotal:N0}")
		Console.WriteLine($"ABCpdf 3-year TCO: ${abcPdfCost.ThreeYearTotal:N0}")
		Console.WriteLine($"Savings with IronPDF: ${abcPdfCost.ThreeYearTotal - ironPdfCost.ThreeYearTotal:N0}")
	End Sub
End Class
$vbLabelText   $csharpLabel

Conclusion

After comprehensive analysis of both libraries, several key differentiators emerge:

IronPDF excels in:

  • Modern web technology support with Chrome-based rendering
  • Cross-platform consistency and cloud-native deployments
  • Developer productivity with intuitive APIs
  • Comprehensive support and documentation
  • Better long-term value for growing teams

ABCpdf offers advantages in:

  • Lower initial cost for basic Windows-only projects
  • Multiple rendering engine options
  • Legacy system compatibility
  • Lower memory footprint for simple documents

IronPDF provides a single solution to all PDF problems. When you purchase IronPDF, you get all the conversions in one single library, plus tasks related to PDF documents only, requiring no additional dependencies. This consolidated approach, combined with superior rendering quality and cross-platform support, makes IronPDF the recommended choice for most modern .NET applications.

For teams prioritizing rapid development, consistent results across platforms, and long-term maintainability, IronPDF's higher initial cost is offset by reduced development time, better support, and fewer compatibility issues.

Getting Started with IronPDF

Ready to experience the difference? Start your free trial today:

// Get started in minutes
Install-Package IronPdf

// Your first PDF in 3 lines
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("my-first-pdf.pdf");
// Get started in minutes
Install-Package IronPdf

// Your first PDF in 3 lines
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("my-first-pdf.pdf");
' Get started in minutes
Install-Package IronPdf var renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>")
pdf.SaveAs("my-first-pdf.pdf")
$vbLabelText   $csharpLabel

Visit our comprehensive documentation, explore code examples, or chat with our engineering team for personalized guidance on your PDF generation needs.

Please note
ABCpdf is a registered trademark of its respective owner. This site is not affiliated with, endorsed by, or sponsored by ABCpdf. All product names, logos, and brands are property of their respective owners. Comparisons are for informational purposes only and reflect publicly available information at the time of writing.

Frequently Asked Questions

What are the main differences between Chrome-based and multi-engine PDF rendering approaches?

Chrome-based rendering (like IronPDF) provides consistent, pixel-perfect output matching modern browsers with full CSS3 and JavaScript support. Multi-engine approaches (like ABCpdf) offer flexibility to choose between Chrome, Firefox, or IE engines but require more testing and configuration. Chrome engines typically use more memory but deliver superior rendering quality for modern web content.

How do HTML to PDF conversion speeds compare between different C# libraries?

Conversion speeds vary by content complexity. For simple HTML, lightweight engines process in 150-300ms, while Chrome-based engines take 200-400ms but handle complex layouts better. Batch processing performance depends more on parallelization support than raw speed. Libraries with native async/await support can process multiple documents 40-60% faster than synchronous alternatives.

Which platforms and .NET versions are supported by modern PDF libraries?

Leading PDF libraries support .NET 5+ through .NET 9, .NET Core 3.1+, and Framework 4.6.2+. Cross-platform libraries run on Windows, Linux, macOS, and Docker containers. Some libraries require platform-specific packages or have limited functionality on non-Windows systems. Cloud deployment support varies, with modern libraries offering native Azure and AWS compatibility.

What security features should a C# PDF library provide for document protection?

Essential security features include AES-256 encryption, password protection with separate user/owner passwords, digital signatures with certificate support, and granular permissions control. Modern libraries offer visual signatures, timestamp services, and PDF/A compliance for long-term archiving. Look for libraries supporting both programmatic and form-based signatures.

How much do enterprise PDF libraries typically cost for team deployments?

Entry-level licenses start from $329-$749 for single developers. Team licenses (3-10 developers) range from $1,400-$3,000. Enterprise unlimited licenses cost $3,000-$35,000 depending on redistribution rights. Consider total cost including support, training, and platform-specific licenses. Some vendors offer suite packages providing multiple products at significant discounts.

Can PDF libraries handle JavaScript and dynamic content in HTML?

Libraries using full browser engines (Chrome, Firefox) execute JavaScript before rendering, supporting dynamic content, AJAX calls, and modern frameworks. Basic HTML parsers cannot execute JavaScript. For dynamic content, look for configurable wait times, render delays, and JavaScript completion detection. Some libraries support waiting for specific elements or network idle states.

What's the typical memory usage for HTML to PDF conversion in production?

Memory usage depends on the rendering engine and document complexity. Chrome-based engines typically use 150-200MB base memory plus 20-50MB per concurrent conversion. Lightweight engines use 80-120MB total. For Docker deployments, allocate at least 512MB for basic operations or 1GB+ for concurrent processing. Memory can be optimized by reducing viewport size and disabling features.

How do I choose between open-source and commercial PDF libraries?

Open-source libraries work well for basic PDF generation but often lack HTML/CSS support, documentation, and maintenance. Commercial libraries provide better rendering quality, support, and regular updates. Consider commercial options when you need pixel-perfect output, technical support, cross-platform compatibility, or are building revenue-generating applications. ROI typically favors commercial libraries for team projects.

What are the best practices for batch PDF generation performance?

Use asynchronous processing with Parallel.ForEachAsync for CPU-bound operations. Limit concurrency to CPU core count for optimal performance. Reuse renderer instances when possible. Enable streaming for large documents. Implement retry logic for network resources. Consider using queuing systems for large batches. Modern libraries can process 100-500 PDFs per minute on standard hardware.

How do I troubleshoot CSS rendering issues in PDF output?

First, verify the rendering engine supports your CSS features. Use print media queries for PDF-specific styles. Check font loading with render delays. Validate CSS with browser developer tools. For layout issues, try different viewport widths. Enable background printing for colored elements. Consider using inline styles for critical formatting. Test with simplified HTML to isolate problems.

Jacob Mellor, Chief Technology Officer @ Team Iron
Chief Technology Officer

Jacob Mellor is Chief Technology Officer at Iron Software and a visionary engineer pioneering C# PDF technology. As the original developer behind Iron Software's core codebase, he has shaped the company's product architecture since its inception, transforming it alongside CEO Cameron Rimington into a 50+ person company serving NASA, Tesla, and global government agencies.

Jacob holds a First-Class Honours Bachelor of Engineering (BEng) in Civil Engineering from the University of Manchester (1998–2001). After opening his first software business in London in 1999 and creating his first .NET components in 2005, he specialized in solving complex problems across the Microsoft ecosystem.

His flagship IronPDF & IronSuite .NET libraries have achieved over 30 million NuGet installations globally, with his foundational code continuing to power developer tools used worldwide. With 25 years of commercial experience and 41 years of coding expertise, Jacob remains focused on driving innovation in enterprise-grade C#, Java, and Python PDF technologies while mentoring the next generation of technical leaders.