PDF Generation Template Editor
Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.
Open-source visual PDF generation engine with customizable templates and developer-friendly APIs.
When converting HTML to PDF, you can set page margins through CConverterProperties and draw independent HTML headers and footers inside the top and bottom margins of every page. Page numbers and the total page count are calculated automatically after pagination, so there is no need to set them page by page.
Page margins are in CSS pixels (px), in the order top, right, bottom, left. Margins declared with @page in the HTML take precedence over this setting. The margins are 0 when not set.
CConverterProperties properties = new CConverterProperties();
properties.SetPageSize(new CSize { Width = 595, Height = 842 });
// Set the page margins. Returns false and keeps the previous margins if any value is negative
properties.SetPageMargins(new CPageMargins { Top = 35, Right = 0, Bottom = 42, Left = 0 });
// Get the current page margins
CPageMargins margins = properties.GetPageMargins();Headers and footers are configured with CHeaderFooterOptions, and their templates are HTML fragments. Elements with the following classes in a template are filled automatically:
| class | Content |
|---|---|
date | The date. When Date is not set, the local date and time of the conversion is used, in the format YYYY-MM-DD HH:MM |
title | The title. When Title is not set, the <title> of the document is used |
url | The address. An HTML string has no address of its own, so provide it through Url |
pageNumber | The current page number, starting from 1 |
totalPages | The total page count, excluding the leading pages that are excluded from numbering |
CConverterProperties properties = new CConverterProperties();
properties.SetBaseUri("/baseUri/");
properties.SetPageSize(new CSize { Width = 595, Height = 842 });
// Headers and footers are drawn inside the top and bottom margins, so reserve enough space for them
properties.SetPageMargins(new CPageMargins { Top = 35, Right = 0, Bottom = 42, Left = 0 });
CHeaderFooterOptions options = new CHeaderFooterOptions();
// Master switch, false by default. Templates are ignored when it is off
options.DisplayHeaderFooter = true;
// An empty string uses the built-in default template; "<div></div>" leaves the band blank
options.HeaderTemplate = """
<div style="height:25px;background:linear-gradient(#6097c7 41%,#fff 40%)"></div>
""";
options.FooterTemplate = """
<div style="position:relative;height:42px;font-family:DroidSansFallback;font-size:8pt;line-height:14px">
<div style="position:absolute;left:24.3%;top:2px;white-space:nowrap">
This report is for reference only. Please refer to the policy terms of the insurer for details!
</div>
<div style="position:absolute;right:0.6cm;top:2px;white-space:nowrap">
Date: <span class="date"></span>
</div>
<div style="position:absolute;left:32px;bottom:1px;font-size:7.5pt;color:#707070">
Page <span class="pageNumber"></span> of <span class="totalPages"></span>
</div>
</div>
""";
// Base directory for relative resources such as images and styles in the templates.
// When empty, the resource directory of the document is used
options.BaseUri = "/templateDir/";
// Overrides the <title> of the document
options.Title = "Family Insurance Policy Review";
// A fixed date. When empty, the local date and time of the conversion is used
options.Date = "2026/9/23";
// The first page is a cover: it shows no header or footer and is not counted in the page numbers
options.SkipLeadingTemplatePages = 1;
options.SkipLeadingNumberedPages = 1;
// Returns false if a skip count is negative
properties.SetHeaderFooterOptions(options);
CHtmlConverter.ConvertToPdf("/htmlFile.html", "/headerFooterOut.pdf", properties);When a template is an empty string, the built-in default template is used: the header shows the date and the title, and the footer shows the address and "page number/total pages".
CHeaderFooterOptions options = new CHeaderFooterOptions
{
DisplayHeaderFooter = true,
Url = "https://www.compdf.com"
};
properties.SetHeaderFooterOptions(options);Set the header to "<div></div>" to show only the footer. An empty string would use the default template instead.
CHeaderFooterOptions options = new CHeaderFooterOptions
{
DisplayHeaderFooter = true,
HeaderTemplate = "<div></div>",
FooterTemplate = "<div style='font-size:9pt;text-align:center'>- <span class='pageNumber'></span> -</div>"
};
properties.SetHeaderFooterOptions(options);SkipLeadingTemplatePages and SkipLeadingNumberedPages are independent:
SkipLeadingTemplatePages: No header or footer is drawn on the first N pages.SkipLeadingNumberedPages: The first N pages are excluded from numbering. Their pageNumber is empty, and totalPages does not count them.For example, in a 35-page document with both set to 1, the cover has no header or footer, the second page shows 1/34, and the last page shows 34/34. With only SkipLeadingTemplatePages = 1, the second page shows 2/35.
DroidSansFallback font without loading extra fonts.<header> and <footer> elements that are repeated as headers and footers in the document; the conversion fails in that case.CHeaderFooterOptions object afterwards does not affect the settings.