Once you've mastered basic HTML-to-PDF conversion, the next challenge is adding professional features: headers with page numbers, watermarks, digital signatures, responsive page layouts, and archival-quality PDFs.
I've implemented these features in production systems handling millions of PDFs. Here's how to go beyond the basics.
How Do I Add Headers and Footers with Page Numbers?
Headers and footers with dynamic content (page numbers, dates, titles) are essential for professional PDFs.
IronPDF makes this straightforward with merge fields:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='text-align: center; font-size: 10px; color: #666;'>
Confidential Document - {date}
</div>"
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='text-align: center; font-size: 10px; color: #666;'>
Page {page} of {total-pages}
</div>"
};
// Adjust margins to make room for headers/footers
renderer.RenderingOptions.MarginTop = 50;
renderer.RenderingOptions.MarginBottom = 50;
var pdf = renderer.RenderHtmlAsPdf("<h1>Document Content</h1>");
pdf.SaveAs("with-headers-footers.pdf");
Supported merge fields:
-
{page}: Current page number -
{total-pages}: Total page count -
{date}: Current date -
{time}: Current time -
{url}: Source URL (if rendering from URL) -
{html-title}: HTML<title>tag content -
{pdf-title}: PDF metadata title
These placeholders are automatically replaced during rendering.
Can I Style Headers and Footers with CSS?
Yes. Headers and footers support full HTML and CSS:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = @"
<style>
.header {
display: flex;
justify-content: space-between;
padding: 10px 20px;
border-bottom: 2px solid #2c3e50;
font-family: Arial, sans-serif;
}
.logo { font-weight: bold; color: #2c3e50; }
.date { color: #7f8c8d; font-size: 9px; }
</style>
<div class='header'>
<span class='logo'>Company Name</span>
<span class='date'>{date}</span>
</div>"
};
renderer.RenderingOptions.MarginTop = 60;
var pdf = renderer.RenderHtmlAsPdf("<h1>Professional Document</h1>");
pdf.SaveAs("styled-header.pdf");
IronPDF's dynamic margin sizing automatically adjusts content based on header/footer height.
How Do I Add Different Headers for First Page vs. Other Pages?
For cover pages or reports where the first page needs a different header, use conditional logic:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = @"
<style>
.first-page { display: none; }
.other-pages { display: block; }
</style>
<div class='first-page' style='text-align: center; font-size: 18px; font-weight: bold;'>
Cover Page Header
</div>
<div class='other-pages' style='text-align: right; font-size: 9px;'>
Page {page} of {total-pages}
</div>"
};
renderer.RenderingOptions.FirstPageNumber = 1;
renderer.RenderingOptions.MarginTop = 40;
var pdf = renderer.RenderHtmlAsPdf("<h1>Cover Page</h1><div style='page-break-after: always;'></div><h2>Page 2</h2>");
pdf.SaveAs("different-first-page.pdf");
You can also use IronPDF's ApplyStamp() method to overlay content on specific pages post-rendering.
How Do I Add Watermarks to PDFs?
Watermarks are useful for "DRAFT", "CONFIDENTIAL", or branding overlays.
Approach 1: Watermark during HTML rendering
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var html = @"
<style>
body { position: relative; }
.watermark {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
font-size: 120px;
color: rgba(0, 0, 0, 0.1);
font-weight: bold;
z-index: -1;
user-select: none;
}
</style>
<div class='watermark'>DRAFT</div>
<h1>Document Content</h1>
<p>This document has a watermark.</p>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("watermarked.pdf");
Approach 2: Watermark after PDF generation
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Original Document</h1>");
// Apply watermark stamp to all pages
pdf.ApplyWatermark("<h1 style='color: rgba(255,0,0,0.3);'>CONFIDENTIAL</h1>",
rotation: 45,
opacity: 30);
pdf.SaveAs("watermark-stamp.pdf");
The post-processing approach is better when you need to watermark existing PDFs or apply different watermarks conditionally.
How Do I Control Page Breaks Precisely?
CSS page break properties control where pages split:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var html = @"
<style>
.section {
page-break-after: always; /* Force page break after this element */
}
.keep-together {
page-break-inside: avoid; /* Prevent breaking inside this element */
}
h1 {
page-break-before: always; /* New page before every h1 */
}
</style>
<div class='section'>
<h2>Section 1</h2>
<p>This section ends with a page break.</p>
</div>
<div class='keep-together'>
<h3>Important Block</h3>
<p>This entire block stays on one page—no splits.</p>
</div>
<h1>Chapter 2</h1>
<p>This starts on a new page because of the h1 rule.</p>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("controlled-breaks.pdf");
Page break properties:
-
page-break-before: always— Start a new page before this element -
page-break-after: always— Start a new page after this element -
page-break-inside: avoid— Prevent splitting this element across pages
These work reliably with IronPDF's Chromium rendering.
Can I Use Responsive CSS for Different Page Sizes?
Yes. Use @media queries for print-specific styling:
using IronPdf;
using IronPdf.Rendering;
// Install via NuGet: Install-Package IronPdf
var html = @"
<style>
@media print {
.no-print { display: none; }
.print-only { display: block; }
body { font-size: 12pt; }
}
@media screen {
.print-only { display: none; }
}
@page {
margin: 2cm;
}
</style>
<div class='no-print'>
<p>This appears in browsers but NOT in PDFs.</p>
</div>
<div class='print-only'>
<p>This appears ONLY in PDFs.</p>
</div>
<h1>Document Title</h1>";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("responsive.pdf");
IronPDF respects CSS @media print rules, so you can design one HTML template that works for both web and PDF.
How Do I Generate Archival-Quality PDFs (PDF/A)?
PDF/A is an ISO-standardized format for long-term archival. It embeds all fonts and images and disallows features that may not render consistently decades from now.
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // Required for PDF/A
renderer.RenderingOptions.CreatePdfFormsFromHtml = false;
var pdf = renderer.RenderHtmlAsPdf("<h1>Archival Document</h1>");
// Convert to PDF/A-2B
pdf.ToPdfA();
pdf.SaveAs("archive.pdf");
PDF/A compliance ensures your PDFs remain readable for decades, even as software evolves.
Can I Add Digital Signatures to PDFs?
Yes. Digital signatures provide authenticity and tamper-evidence.
using IronPdf;
using IronPdf.Signing;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Contract Document</h1>");
// Load certificate (.pfx file)
var signature = new PdfSignature("certificate.pfx", "password");
signature.SigningContact = "legal@company.com";
signature.SigningReason = "Contract Approval";
signature.SigningLocation = "San Francisco, CA";
pdf.Sign(signature);
pdf.SaveAs("signed-contract.pdf");
The PDF will display a signature badge in PDF readers. Recipients can verify the signature's authenticity using the certificate.
How Do I Add Form Fields to PDFs?
IronPDF can convert HTML form elements into interactive PDF forms:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var html = @"
<form>
<label>Name:</label>
<input type='text' name='name' />
<label>Email:</label>
<input type='email' name='email' />
<label>Comments:</label>
<textarea name='comments'></textarea>
<label>Subscribe:</label>
<input type='checkbox' name='subscribe' />
</form>";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("form.pdf");
The generated PDF contains fillable form fields that users can complete in Adobe Reader or other PDF viewers.
How Do I Programmatically Fill PDF Forms?
If you have an existing PDF form, you can populate it programmatically:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var pdf = PdfDocument.FromFile("template-form.pdf");
var form = pdf.Form;
form.SetFieldValue("name", "John Doe");
form.SetFieldValue("email", "john@example.com");
form.SetFieldValue("subscribe", "true");
pdf.SaveAs("filled-form.pdf");
This is useful for automated report generation where you fill templates with database data.
Can I Merge Multiple PDFs into One?
Yes, IronPDF can merge multiple PDFs:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("combined.pdf");
Or merge HTML-rendered PDFs:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
var coverPage = renderer.RenderHtmlAsPdf("<h1>Cover Page</h1>");
var contentPage = renderer.RenderHtmlAsPdf("<h1>Content</h1>");
var appendix = renderer.RenderHtmlAsPdf("<h1>Appendix</h1>");
var finalPdf = PdfDocument.Merge(coverPage, contentPage, appendix);
finalPdf.SaveAs("final-report.pdf");
How Do I Split PDFs into Separate Files?
Extract specific pages from a PDF:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var pdf = PdfDocument.FromFile("large-document.pdf");
// Extract pages 1-5
var subset = pdf.CopyPages(0, 4); // Zero-indexed
subset.SaveAs("pages-1-to-5.pdf");
// Extract a single page
var singlePage = pdf.CopyPage(9); // Page 10 (zero-indexed)
singlePage.SaveAs("page-10.pdf");
Can I Compress PDFs to Reduce File Size?
Yes. IronPDF supports compression:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Document with Images</h1><img src='large-image.jpg'>");
// Compress images and optimize file size
pdf.CompressImages(90); // 90% quality
pdf.CompressionStrategy = PdfCompressionStrategy.HighQuality;
pdf.SaveAs("compressed.pdf");
Compression is especially useful for PDFs with many images.
How Do I Add Metadata (Title, Author, Subject)?
Set PDF metadata for better organization and searchability:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Annual Report 2025</h1>");
pdf.MetaData.Title = "Annual Report 2025";
pdf.MetaData.Author = "Jacob Mellor";
pdf.MetaData.Subject = "Financial Performance";
pdf.MetaData.Keywords = "finance, report, 2025";
pdf.MetaData.CreationDate = DateTime.Now;
pdf.SaveAs("annual-report-2025.pdf");
Metadata appears in PDF reader properties and helps with document management systems.
Can I Password-Protect PDFs?
Yes, encrypt PDFs with user and owner passwords:
using IronPdf;
using IronPdf.Engines.Chrome;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential Document</h1>");
// Set passwords
pdf.Password = "user-password"; // Required to open the PDF
pdf.OwnerPassword = "owner-password"; // Required to change permissions
// Set permissions (what users can do with the PDF)
pdf.SecuritySettings.AllowUserCopying = false;
pdf.SecuritySettings.AllowUserPrinting = false;
pdf.SecuritySettings.AllowUserAnnotations = false;
pdf.SecuritySettings.AllowUserFormData = false;
pdf.SecuritySettings.AllowUserModifyDocument = false;
pdf.SaveAs("encrypted.pdf");
Users must enter the password to open or modify the PDF.
How Do I Extract Text from Existing PDFs?
IronPDF can parse and extract text from PDFs:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var pdf = PdfDocument.FromFile("document.pdf");
// Extract all text
string allText = pdf.ExtractAllText();
Console.WriteLine(allText);
// Extract text from specific page
string pageText = pdf.ExtractTextFromPage(0); // First page (zero-indexed)
Console.WriteLine(pageText);
Useful for indexing PDFs or extracting data for processing.
Can I Add Bookmarks (Table of Contents)?
Yes, create PDF bookmarks for navigation:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(@"
<h1 id='chapter1'>Chapter 1</h1>
<p>Content for chapter 1...</p>
<div style='page-break-after: always;'></div>
<h1 id='chapter2'>Chapter 2</h1>
<p>Content for chapter 2...</p>");
// Add bookmarks
pdf.Bookmarks.Add("Chapter 1", 0); // Page 1 (zero-indexed)
pdf.Bookmarks.Add("Chapter 2", 1); // Page 2
pdf.SaveAs("with-bookmarks.pdf");
Bookmarks appear in the PDF reader's sidebar for easy navigation.
How Do I Render Charts and Graphs from JavaScript Libraries?
IronPDF executes JavaScript before rendering, so libraries like Chart.js work:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var html = @"
<!DOCTYPE html>
<html>
<head>
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
</head>
<body>
<canvas id='myChart' width='400' height='200'></canvas>
<script>
const ctx = document.getElementById('myChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Revenue',
data: [12, 19, 3, 5]
}]
}
});
</script>
</body>
</html>";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.RenderDelay = 1000; // Wait for Chart.js to render
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("chart.pdf");
The rendered PDF includes the chart as a rasterized image.
Advanced Rendering Options Reference
Here's a quick reference for advanced rendering options:
using IronPdf;
using IronPdf.Rendering;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
// Page settings
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
// Rendering quality
renderer.RenderingOptions.Dpi = 300;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
// JavaScript and timing
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.RenderDelay = 500; // Wait 500ms before rendering
renderer.RenderingOptions.Timeout = 60; // Timeout after 60 seconds
// Forms and interactivity
renderer.RenderingOptions.CreatePdfFormsFromHtml = true;
// Advanced
renderer.RenderingOptions.ViewPortWidth = 1024;
renderer.RenderingOptions.ViewPortHeight = 768;
renderer.RenderingOptions.Zoom = 100; // 100% zoom
var pdf = renderer.RenderHtmlAsPdf("<h1>Advanced PDF</h1>");
pdf.SaveAs("advanced.pdf");
These options give you fine-grained control over PDF output.
Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.
Top comments (0)