HTML to PDF Converter Overview

The HTML to PDF Converter turns web pages and HTML strings into PDF documents. It renders the HTML with a Chromium engine that ships inside the NuGet package, so HTML5, CSS3, JavaScript, web fonts and SVG come out as in the Chrome browser, and there is no browser to install on the server. The same component converts HTML to images with the HtmlToImageConverter class.

A conversion takes three steps: create an HtmlToPdfConverter object, optionally set its options, and call one of its methods with a URL or an HTML string. The result is a PDF document in memory or in a file. A new converter already produces an A4 document with the page laid out as in a desktop browser, so the options are needed only to change that result or to add features to the document.

This topic describes the packages, the conversion methods, the page layout and the features of the converter, with links to the topics that describe each of them in detail. It ends with the code of the Getting Started demo.

NuGet Packages

The component is distributed as a NuGet package for each platform. Each package contains the same .NET Standard 2.0 library, used from .NET 6 to .NET 10 and from .NET Framework 4.6.2 to 4.8.1, and the native rendering engine for its platform.

Platform

HTML to PDF package

Windows x64

Winnovative.Pdf.Next.HtmlToPdf.Windows

Linux x64

Winnovative.Pdf.Next.HtmlToPdf.Linux

The Winnovative.Pdf.Next.Windows and Winnovative.Pdf.Next.Linux metapackages reference the HTML to PDF package of their platform together with all the other components of the library, and Winnovative.Pdf.Next.Windows.Arm64, Winnovative.Pdf.Next.Linux.Arm64 and Winnovative.Pdf.Next.MacOS do the same for Windows and Linux on ARM64 and for macOS on Apple Silicon. The Winnovative.Pdf.Next.HtmlToPdf and Winnovative.Pdf.Next metapackages reference both the Windows x64 and the Linux x64 packages, for applications built once and deployed on either platform. Installing and running the packages is described in Getting Started on Windows and Getting Started on Linux.

Converting HTML to PDF

The HtmlToPdfConverter class converts a URL, which can also be a local file, or an HTML string. An HTML string is converted with a base URL, used to resolve the relative URLs of the images, style sheets and scripts it references. The PDF document is returned in a memory buffer or saved to a file:

Source

PDF in memory

PDF saved to a file

URL or local file

ConvertUrl(String)

ConvertUrlToFile(String, String)

HTML string

ConvertHtml(String, String)

ConvertHtmlToFile(String, String, String)

Each method has an asynchronous variant with the Async suffix, following the Task-based Asynchronous Pattern, with an optional System.ThreadingCancellationToken to cancel the conversion: ConvertUrlAsync(String, CancellationToken), ConvertHtmlAsync(String, String, CancellationToken), ConvertUrlToFileAsync(String, String, CancellationToken) and ConvertHtmlToFileAsync(String, String, String, CancellationToken). Converters can run in parallel, one per conversion, as shown in Convert Multiple HTML Pages to PDF in Parallel; how the rendering engine processes are started and reused is described in HTML to PDF Rendering Modes and the Persistent Rendering Engine.

Page Size and Layout

The size of the PDF pages, the width at which the HTML is laid out and the scale at which it is drawn are set together by a layout method of the converter. A new converter uses FitBrowserWindowToPage(PdfPageSize, PdfPageOrientation, Int32) with an A4 page: the page is laid out as in a 1024 pixel browser window and scaled to the page width. HTML templates designed for the paper size use LayoutAtPageWidth(PdfPageSize, PdfPageOrientation, Boolean, String), and other methods cover the output of Chrome, receipts and pages as wide as the browser window. The methods and the settings for the usual cases are described in HTML to PDF Page Setup and Scaling, and all the options of the converter in HTML to PDF Converter Options.

Features of the Converter

Beyond the conversion itself, the converter adds structure, interactivity and security to the generated document, and controls how the page is loaded before it is converted.

Page structure

Navigation and content

Interactivity, standards and security

Loading the page

Code Sample - Convert HTML to PDF with HtmlToPdfConverter Class

C#
using System;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc;
using Winnovative_Next_AspNetDemo.Models;
using Winnovative_Next_AspNetDemo.Models.HTML_to_PDF;

// Use Winnovative Namespace
using Winnovative.Pdf.Next;

namespace Winnovative_Next_AspNetDemo.Controllers.HTML_to_PDF
{
    public class HTML_to_PDF_Getting_StartedController : Controller
    {
        // GET: Getting_Started
        public ActionResult Index()
        {
            var model = new HTML_to_PDF_Getting_Started_ViewModel();
            return View(model);
        }

        [HttpPost]
        public ActionResult ConvertHtmlToPdf(HTML_to_PDF_Getting_Started_ViewModel model)
        {
            if (!ModelState.IsValid)
            {
                var errorMessage = ModelStateHelper.GetModelErrors(ModelState);
                throw new ValidationException(errorMessage);
            }

            // Set the license key received after purchase to use the library in licensed mode; leave it commented for demo mode
            // Licensing.LicenseKey = "your-license-key";

            // Create a HTML to PDF converter object with default settings
            HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter();

            // Set the initial HTML viewer height in pixels
            if (model.HtmlViewerHeight.HasValue)
                htmlToPdfConverter.HtmlViewerHeight = model.HtmlViewerHeight.Value;

            // Optionally load the lazy images
            htmlToPdfConverter.LoadLazyImages = model.LoadLazyImages;

            // Set the lazy images load mode
            htmlToPdfConverter.LazyImagesLoadMode = model.LazyImagesLoadMode == "Browser" ?
                LazyImagesLoadMode.Browser : LazyImagesLoadMode.Custom;

            // Set the PDF page margins in points. The default is 0
            htmlToPdfConverter.PdfDocumentOptions.LeftMargin = model.LeftMargin;
            htmlToPdfConverter.PdfDocumentOptions.RightMargin = model.RightMargin;
            htmlToPdfConverter.PdfDocumentOptions.TopMargin = model.TopMargin;
            htmlToPdfConverter.PdfDocumentOptions.BottomMargin = model.BottomMargin;

            // Set the media type used in @media rules when rendering HTML to PDF
            htmlToPdfConverter.MediaType = model.MediaType == "Print" ? "print" : "screen";

            // Set the page layout: how the width at which the HTML is laid out relates to the PDF page width
            PdfPageSize pageSize = SelectedPdfPageSize(model.PdfPageSize);
            PdfPageOrientation pageOrientation = SelectedPdfPageOrientation(model.PdfPageOrientation);

            switch (model.PageLayout)
            {
                case "FitBrowserWindowToPage":
                    // Fixed page size: the HTML is laid out as in a browser window of the given width and the result
                    // is scaled to the content width of the page, so a responsive site keeps its desktop layout.
                    // This is the default layout of the converter, with an A4 page and a 1024 pixel window
                    htmlToPdfConverter.FitBrowserWindowToPage(pageSize, pageOrientation, model.HtmlViewerWidth);
                    break;

                case "LayoutAtPageWidth":
                    // Fixed page size: the HTML is laid out at the content width of the page, one CSS pixel
                    // being 0.75 points. For HTML templates designed for the paper size, usually with the print media type
                    htmlToPdfConverter.LayoutAtPageWidth(pageSize, pageOrientation, mediaType: htmlToPdfConverter.MediaType);
                    break;

                default:
                    // The PDF page width follows the browser window width and the HTML is drawn 1:1;
                    // the page height comes from the page size and the orientation
                    htmlToPdfConverter.PageWidthFromBrowserWindow(model.HtmlViewerWidth, singlePage: model.SinglePage);
                    htmlToPdfConverter.HtmlViewerZoom = model.HtmlViewerZoom;
                    htmlToPdfConverter.PdfDocumentOptions.PdfPageSize = pageSize;
                    htmlToPdfConverter.PdfDocumentOptions.PdfPageOrientation = pageOrientation;
                    break;
            }

            // A single page as tall as the content, with the page width of the layout. The page is at least as tall
            // as the browser window, so the window height is set to 1 pixel for the page to end with the content
            if (model.SinglePage)
            {
                htmlToPdfConverter.PdfDocumentOptions.AutoResizePdfPageHeight = true;
                htmlToPdfConverter.HtmlViewerHeight = 1;
            }

            // Sets the PDF standard for the generated document
            // Leave as None to generate a plain PDF without an accessibility structure tree or archival metadata
            htmlToPdfConverter.PdfDocumentOptions.PdfStandard = model.PdfStandard;

            // Set the maximum time, in seconds, to wait for the HTML page to load
            // The default value is 120 seconds
            htmlToPdfConverter.NavigationTimeout = model.NavigationTimeout;

            // Set an additional delay, in seconds, to wait for asynchronous content after the initial load
            // The default value is 0
            if (model.ConversionDelay.HasValue)
                htmlToPdfConverter.ConversionDelay = model.ConversionDelay.Value;

            // The buffer to receive the generated PDF document
            byte[] outPdfBuffer = null;

            if (model.HtmlPageSource == "Url")
            {
                string url = model.Url;

                // Convert the HTML page given by an URL to a PDF document in a memory buffer
                outPdfBuffer = htmlToPdfConverter.ConvertUrl(url);
            }
            else
            {
                string htmlString = model.HtmlString;
                string baseUrl = model.BaseUrl;

                // Convert a HTML string with a base URL to a PDF document in a memory buffer
                outPdfBuffer = htmlToPdfConverter.ConvertHtml(htmlString, baseUrl);
            }

            // Send the PDF file to browser
            FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf");
            if (!model.OpenInline)
            {
                // send as attachment
                fileResult.FileDownloadName = "HTML_to_PDF_Getting_Started.pdf";
            }

            return fileResult;
        }

        private PdfPageSize SelectedPdfPageSize(string selectedValue)
        {
            switch (selectedValue)
            {
                case "A0":
                    return PdfPageSize.A0;
                case "A1":
                    return PdfPageSize.A1;
                case "A10":
                    return PdfPageSize.A10;
                case "A2":
                    return PdfPageSize.A2;
                case "A3":
                    return PdfPageSize.A3;
                case "A4":
                    return PdfPageSize.A4;
                case "A5":
                    return PdfPageSize.A5;
                case "A6":
                    return PdfPageSize.A6;
                case "A7":
                    return PdfPageSize.A7;
                case "A8":
                    return PdfPageSize.A8;
                case "A9":
                    return PdfPageSize.A9;
                case "ArchA":
                    return PdfPageSize.ArchA;
                case "ArchB":
                    return PdfPageSize.ArchB;
                case "ArchC":
                    return PdfPageSize.ArchC;
                case "ArchD":
                    return PdfPageSize.ArchD;
                case "ArchE":
                    return PdfPageSize.ArchE;
                case "B0":
                    return PdfPageSize.B0;
                case "B1":
                    return PdfPageSize.B1;
                case "B2":
                    return PdfPageSize.B2;
                case "B3":
                    return PdfPageSize.B3;
                case "B4":
                    return PdfPageSize.B4;
                case "B5":
                    return PdfPageSize.B5;
                case "Flsa":
                    return PdfPageSize.Flsa;
                case "HalfLetter":
                    return PdfPageSize.HalfLetter;
                case "Ledger":
                    return PdfPageSize.Ledger;
                case "Legal":
                    return PdfPageSize.Legal;
                case "Letter":
                    return PdfPageSize.Letter;
                case "Letter11x17":
                    return PdfPageSize.Letter11x17;
                case "Note":
                    return PdfPageSize.Note;
                default:
                    return PdfPageSize.A4;
            }
        }

        private PdfPageOrientation SelectedPdfPageOrientation(string selectedValue)
        {
            return selectedValue == "Portrait" ? PdfPageOrientation.Portrait : PdfPageOrientation.Landscape;
        }
    }
}

See Also