SelectPdf for .NET 10 - Generate Table of Contents with Html to Pdf Converter - C# / .NET 10 Sample

This sample shows how the html to pdf converter gives a document a table of contents with page numbers using SelectPdf Pdf Library for .NET, in one of three ways:

- Number the page's own table of contents: the page already has one (links to its sections, inside the element with the id "toc" in the first test document); each entry gets a leader and the number of the page its section is on.
- Write a table of contents into the page: the table is written into the page from its headings, styled by the page's CSS, then numbered.
- Generate table of contents pages: the table is drawn on pages of its own, inserted into the pdf document, with the fonts, colors and spacing set in code.

The page numbers are the ones the footer shows.

Test document with a table of contents  |  Test document without a table of contents

Url:


Table of contents:


Sample code · C#
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using SelectPdf.Universal;

namespace SelectPdf.Samples.Pages
{
    public class TableOfContentsModel : PageModel
    {
        public void OnGet()
        {
            DdlMode = "FillExisting";
            TxtUrl = Helper.WWWRoot(Request) + Url.Content("~/files/document2.html");
        }

        [BindProperty]
        public string TxtUrl { get; set; }

        [BindProperty]
        public string DdlMode { get; set; } = "FillExisting";

        public List<SelectListItem> Modes { get; } = new List<SelectListItem>
        {
            new SelectListItem { Value = "FillExisting", Text = "Number the page's own table of contents" },
            new SelectListItem { Value = "InsertHtml", Text = "Write a table of contents into the page" },
            new SelectListItem { Value = "GeneratePages", Text = "Generate table of contents pages" },
        };

        public IActionResult OnPost()
        {
            PdfTableOfContentsMode mode =
                SampleForm.ParseEnum(DdlMode, PdfTableOfContentsMode.FillExisting);

            // instantiate a html to pdf converter object
            HtmlToPdf converter = new HtmlToPdf();
            converter.Options.NavigationTimeout = Startup.NavigationTimeout;

            converter.Options.MarginTop = 20;
            converter.Options.MarginRight = 20;
            converter.Options.MarginBottom = 20;
            converter.Options.MarginLeft = 20;

            // the table of contents
            PdfTableOfContentsOptions toc = converter.Options.TableOfContents;
            toc.Mode = mode;
            switch (mode)
            {
                case PdfTableOfContentsMode.FillExisting:
                    // the element that holds the page's own table of contents: every internal
                    // link inside it gets a leader and the number of the page its target is on
                    toc.ContainerSelector = "#toc";
                    break;

                case PdfTableOfContentsMode.InsertHtml:
                    // a table of contents is written into the page from its headings, styled
                    // by the page's CSS (nav.selectpdf-toc), then numbered
                    toc.HeadingSelectors = new string[] { "h1", "h2" };
                    toc.Title = "Table of Contents";
                    converter.Options.CustomCSS =
                        "nav.selectpdf-toc { font-size: 18px; } " +
                        "nav.selectpdf-toc li.selectpdf-toc-level-1 > a { font-weight: bold; }";
                    break;

                case PdfTableOfContentsMode.GeneratePages:
                    // the table of contents is drawn on pages of its own, styled here
                    toc.HeadingSelectors = new string[] { "h1", "h2" };
                    toc.PagePosition = PdfTableOfContentsPagePosition.Start;
                    toc.Title = "Table of Contents";
                    toc.TitleAlign = PdfTextHorizontalAlign.Center;
                    toc.TitleColor = new PdfColor(26, 75, 140);
                    toc.NumberEntries = true;
                    toc.LevelStyles = new PdfTableOfContentsLevelStyle[]
                    {
                        new PdfTableOfContentsLevelStyle
                        {
                            Font = PdfFont.CreateStandardFont(PdfStandardFont.HelveticaBold, 13),
                            Color = new PdfColor(26, 75, 140),
                            SpacingBefore = 10,
                        },
                        new PdfTableOfContentsLevelStyle
                        {
                            Font = PdfFont.CreateStandardFont(PdfStandardFont.Helvetica, 11),
                            Indent = 20,
                        },
                    };
                    break;
            }
            toc.Leader = PdfTableOfContentsLeader.Dots;

            // bookmarks for the headings, shown when the document is opened in a viewer
            converter.Options.PdfBookmarkOptions.CssSelectors = new string[] { "h1", "h2" };
            converter.Options.ViewerPreferences.PageMode = PdfViewerPageMode.UseOutlines;

            // footer with page numbers - the table of contents uses the same numbering
            converter.Options.DisplayFooter = true;
            converter.Footer.Height = 30;
            PdfFont footerFont = PdfFont.CreateFromSystemFont("Liberation Sans", 10);
            PdfTextSection text = new PdfTextSection(0, 10,
                "Page: {page_number} of {total_pages}  ", footerFont);
            text.HorizontalAlign = PdfTextHorizontalAlign.Right;
            converter.Footer.Add(text);

            // create a new pdf document converting an url
            PdfDocument doc = converter.ConvertUrl(TxtUrl);

            // save pdf document
            byte[] pdf = doc.Save();

            // close pdf document
            doc.Close();

            // return resulted pdf document
            FileResult fileResult = new FileContentResult(pdf, "application/pdf");
            fileResult.FileDownloadName = "Document.pdf";
            return fileResult;
        }
    }
}