Convert HTML to PDF in C# and VB.NET

If you have already invested significant time and money into creating content in HTML form, you may want to create PDFs from that HTML. This approach is a natural choice for anyone who wants to avoid duplicate work.

This article is a detailed guide to converting HTML to PDF in .NET using Docotic.Pdf together with its free HtmlToPdf add‑on.

For information on why Docotic.Pdf is the right choice, how to install the add-on, and how the conversion works internally, refer to the HTML to PDF API overview page.

HTML to PDF conversion

Simple HTML to PDF C# conversion

First, install the add-on.

Install-Package BitMiracle.Docotic.Pdf.HtmlToPdf

Using the HTML to PDF API, the C# conversion code can look like this:

static async Task ConvertUrlToPdfAsync(string urlString, string pdfFileName)
{
    using var converter = await HtmlConverter.CreateAsync();
    using var pdf = await converter.CreatePdfAsync(new Uri(urlString));
    pdf.Save(pdfFileName);
}

It is rather simple. Only two calls are required to produce a PDF document.

The code creates an instance of the converter and uses it to generate a PDF from HTML. You can edit the PDF document or sign it with a digital signature. For simplicity, the example code saves the document as is.

As you can see, the API is asynchronous and does not provide synchronous methods at all.

Using the async API in synchronous code

There are cases when you need to call the API from some synchronous code. For example, when your console application uses an older version of C# and you don't have async Main. Don't worry, you still can use the add-on in your app.

The following code shows how to convert URL to PDF in a regular synchronous method:

Task.Run(async () =>
{
    using var converter = await HtmlConverter.CreateAsync();
    var uri = new Uri("https://bitmiracle.com/pdf-library/html-pdf/");
    using var pdf = await converter.CreatePdfAsync(uri);
    pdf.Save("output.pdf");
}).GetAwaiter().GetResult();

VB.NET applications use a similar code. Here is a snippet that shows how to convert HTML to PDF in a synchronous VB.NET code.

Task.Run(
    Async Function()
        Using converter = Await HtmlConverter.CreateAsync()
            Dim uri = New Uri("https://bitmiracle.com/pdf-library/html-pdf/")
            Using pdf = Await converter.CreatePdfAsync(uri)
                pdf.Save("output.pdf")
            End Using
        End Using
    End Function
).GetAwaiter().GetResult()

Please note that in general it is not recommended to call async methods synchronously, so use the wrapper only when you have no other choice.

Sample code

We provide sample codes for console, Windows Forms and WPF applications. Download complete test projects from our GitHub repository:

There is also the HTML to PDF group of samples. Each sample comes in C# and VB.NET version.

Create a PDF with an HTML string or file in C# and VB.NET

It's easy to convert an HTML string to PDF with the API. The string can contain a complete HTML document or just a fragment. The converter will create a PDF from the HTML code for you.

using var converter = await HtmlConverter.CreateAsync();

var html = "<body><br><br><br><h1>Hello, World</h1></body>";
using var pdf = await converter.CreatePdfFromStringAsync(html);
pdf.Save("output.pdf");

HTML can contain relative references to images, scripts and CSS files. To properly convert such code, you would need to specify a base URL for all the relative links in the HTML. Here is how to specify a base URL using the conversion options:

using var converter = await HtmlConverter.CreateAsync();

var incompleteHtml = "<img src=\"/images/team.svg\"></img>";

var options = new HtmlConversionOptions();
options.Load.BaseUri = new Uri("https://bitmiracle.com/");

using var pdf = await converter.CreatePdfFromStringAsync(incompleteHtml, options);
pdf.Save("output.pdf");

Our GitHub repository contains the full test project.

Converting an HTML file is almost the same as converting an URL. Just use the CreatePdfAsync overload that accepts a path instead of an URL. The base URL and other options are also supported when converting an HTML file to PDF in C# or VB.NET code.

var sampleHtmlPath = @"C:\path\to\sample.html";
using var pdf = await converter.CreatePdfAsync(sampleHtmlPath);
pdf.Save("output.pdf");

You can also convert SVG images to PDF using the API.

Use custom page size, margins, and scale

When dealing with web pages that have wide layouts, you can either increase the output PDF size or scale the content down to fit the PDF page. To better position the scaled content, you can also set up margins.

A well-scaled PDF provides a better reading experience, because its readers won't need to zoom in or out to view the content properly. If the HTML document is hard to read because of a small font size, you may scale the content up.

By default, the API produces PDFs with page size equal to A4. There are no margins and no magnification. Using the conversion options, you can change these settings.

See how to set up scaling factor and margins when generating PDF from HTML

using var converter = await HtmlConverter.CreateAsync();

var html = "<html><head><style>body { background-color: coral; margin-top: 100px;}</style></head>" +
"<body><h1>Did you notice the margins and the scale?</h1></body></html>";

var options = new HtmlConversionOptions();
options.Page.MarginLeft = 10;
options.Page.MarginTop = 20;
options.Page.MarginRight = 30;
options.Page.MarginBottom = 40;
options.Page.Scale = 1.5;

using var pdf = await converter.CreatePdfFromStringAsync(html, options);
pdf.Save("output.pdf");

Docotic.Pdf samples repository contains the complete project.

The HTML to PDF API can add repeatable footer / header blocks on generated pages. Converter creates the blocks from the HTML templates specified in page options. We recommend using inline styles and Data URIs for images inside the templates.

The converter places headers and footers inside page margins. Given that the default page margins are small, the content of the header and footer may not be visible. We recommend specifying top and bottom margins explicitly. The size should match the size of the header and the footer, respectively.

See how to change HTML to PDF and add header and footer

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.HeaderTemplate = File.ReadAllText("header-template.html");
options.Page.MarginTop = 50;

options.Page.FooterTemplate = File.ReadAllText("footer-template.html");
options.Page.MarginBottom = 50;

var url = new Uri("https://www.iana.org/numbers");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

The templates use regular HTML code with support for a few variables. These variables are date, title, url, pageNumber and totalPages. Both the header templates and footer templates support the same set of variables.

The full test project and template code is in Docotic.Pdf samples repository. The sample code shows how to use the variables and Data URIs in the templates.

Password-protected HTML to PDF C# conversion

Some web pages require authentication to access them. When you access a secure URL that requires HTTP authentication, the browser asks you to provide username and password.

Using the conversion options, you can instruct the API to provide credentials for webpages that require login.

This C# code shows how to convert password protected HTML to PDF

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://httpbin.org/basic-auth/foo/bar");

var options = new HtmlConversionOptions();
options.Authentication.SetCredentials("foo", "bar");

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Find the complete working sample in samples repo.

It is also easy if the page needs some cookies set to function properly. Just add those cookies to the options. Here is how:

var options = new HtmlConversionOptions();
options.Cookies.Add(new Cookie("sessionID", "my-session-ID"));

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Delay conversion start

By default, the conversion starts immediately after loading. Delaying HTML to PDF conversion can be useful if the page keeps updating for a while after being loaded. It is often the case when dealing with dynamic content generated by JavaScript or AJAX calls.

The Acid 3 test is a perfect example of a page that would benefit from a delay before conversion. The test executes the number of checks to evaluate a browser's ability to render complex web pages correctly. These checks take time. Try changing the wait time in the following code to see how it affects the conversion results.

var options = new HtmlConversionOptions();
options.Start.SetStartAfterDelay(10 * 1000);

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://acid3.acidtests.org/");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

The above code shows how to convert HTML to PDF with delay. While the additional time helps with getting better results, please note that adding delays can affect performance. Insufficient delays can negatively affect the quality of the conversion. An alternative approach to using a delay is to use a script that would execute until the page is ready.

You can get the full test project in Docotic.Pdf samples repository.

Execute JavaScript before conversion

The add-on API provides a way to run a JS code before the conversion. The code can dynamically generate or modify the HTML content. For example, it can toggle elements, or to make dynamic content loading happen.

The following code shows how to delay HTML to PDF conversion until JavaScript has finished.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
var js = @"document.body.style.backgroundColor = 'green';";
options.Start.SetStartAfterScriptRun(js);

var url = new Uri("https://google.com");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

The above snippet uses a very simple code just to illustrate the approach. For a more real-world example, check out the corresponding sample app in our GitHub repo. The app shows how to deal with a page that dynamically loads its contents. The JavaScript code in the app scrolls the page until there is no more new content. After that, the conversion to PDF happens.

Convert HTML to PDF in .NET ignoring SSL errors

When sending secure requests to load HTML, the add-on checks if the SSL certificate that authenticates a website's identity and enables an encrypted connection is valid and trusted.

By default, the add-on will throw an exception if the HTML to PDF converter does not trust the certificate for any reason. It usually happen because of a self-signed, revoked, or expired certificate.

If you understand the risk of accepting an untrusted certificate, you can tell the add-on to bypass the checks using the engine options.

var engineOptions = new HtmlEngineOptions
{
    IgnoreSslErrors = true
};
using var converter = await HtmlConverter.CreateAsync(engineOptions);

var url = new Uri("https://self-signed.badssl.com/");
using var pdf = await converter.CreatePdfAsync(url);
pdf.Save("output.pdf");

For the complete code, head over to Docotic.Pdf samples repo.

Overlay HTML onto an existing PDF

There are cases when you would like to use an existing PDF as a backdrop for the conversion result. For example, when you have a picture of a form and want to put something over empty areas in that picture. The result will look like a filled form. This is possible with Docotic.Pdf and the add-on.

This process involves creating a new PDF from the HTML (the overlay content) and then merging it with the existing PDF. The final document will include both the original content and the new overlay. Here is the code that illustrates the process.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.SetSizeInches(4.13, 5.83);

string htmlCode =
    "<div style=\"position: absolute; top: 270px; right: 100px;\">" +
    "I would like to put this here</div>";
using var htmlPdf = await converter.CreatePdfFromStringAsync(htmlCode, options);

using var pdf = new PdfDocument("pdf-to-merge-with.pdf");
var xObj = pdf.CreateXObject(htmlPdf.Pages[0]);

pdf.Pages[0].Canvas.DrawXObject(xObj, 0, 0);
pdf.Save("output.pdf");

It is important to specify a page size for the overlay. Usually, the size should be equal to the size of the page you want to overlay. Then you would need to produce the new PDF with the overlay content. Please note that the background is transparent by default. You may change the background by running a script before the conversion if needed.

The code above:

  • creates a PDF document with a transparent page from the HTML
  • opens an existing PDF
  • creates an XObject from the first page of the converted document in the existing document
  • draws the XObject on top of the first PDF page of the existing document

The full test project with an example source PDF is in Docotic.Pdf samples repository.

Photo of Sergey Bobrovsky
Written by

Sergey is a PDF expert and the co‑founder of Bit Miracle. He has been developing PDF libraries since 2005. Docotic.Pdf is his best library to date. Customers praise it as a high‑quality, robust component that is well‑designed and memory‑efficient.