Click or drag to resize
Pdf Library for .NET

Generate Table of Contents

SelectPdf Html To Pdf Converter generates easily internal links (Internal and External Links) and bookmarks (Automatic Bookmarks). Using these 2 features, a simple table of contents is automatically generated if the page being converted has a section at the top with internal links to all major sections.

A little more complicated is to generate page numbers for the table of contents. To be able to do that, the Get Web Elements Location in PDF feature will be used together with a few more settings and web element IDs patterns.

The table of contents (TOC) must already exist at the top of the web page and the items from the table of contents must link to the appropriate sections from the document (like in the test document below). The TOC elements must also have the following CSS classes or ID styles:

  • All TOC elements (both titles from the actual table of contents, but also the link targets - where the user goes when clicking on a TOC link) must have a specific CSS class ("toc" in our example).

  • All TOC titles must have similar IDs: TOC_Title{0} (TOC_Title1 to TOC_Title13 in our example).

  • All TOC targets (document content) must have similar IDs: TOC_Target{0} (TOC_Target1 to TOC_Target13 in our example).

All these elements locations are retrieved during the conversion to PDF and those locations are used to get the content page numbers to display them in the table of contents. The font for the page numbers can be specified in code. Also, that style of the line that links the TOC titles with the page numbers.

Sample Code

This sample shows how the html to pdf converter can generate page numbers for a table of contents using SelectPdf Pdf Library for .NET.

// number of items in the table of contents (TOC)
private int TOC_Items = 13;

// CSS class for TOC items (titles and targets)
private string TOC_Class = "toc";

// font size for page numbers in the table of contents
private int TOC_Page_Font_Size = 12;

// CSS class for PDF bookmarks
private string Bookmarks_Class = "bookmark";

// Each TOC item is represented by a title with ID TOC_Title{0}
// and a target (internal link) with ID TOC_Target{0}
// Both TOC titles and targets must have the same CSS Class ("toc" in our sample)

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string url = Page.ResolveUrl("~/files/document2.html");
        TxtUrl.Text = (new Uri(Request.Url, url)).AbsoluteUri;
        LnkTest.NavigateUrl = url;
    }
}

protected void BtnCreatePdf_Click(object sender, EventArgs e)
{
    // instantiate a html to pdf converter object
    HtmlToPdf converter = new HtmlToPdf();

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

    // set the css selectors for the automatic bookmarks 
    // (elements with CSS class "bookmark")
    converter.Options.PdfBookmarkOptions.CssSelectors =
        new string[] { "*." + Bookmarks_Class };

    // set the css selectors for the TOC related elements
    // (elements with CSS class "toc")
    // (alternatively, full list of IDs can be specified)
    converter.Options.WebElementsMappingOptions.CssSelectors =
        new string[] { "*." + TOC_Class };

    // display the bookmarks when the document is opened in a viewer
    converter.Options.ViewerPreferences.PageMode = PdfViewerPageMode.UseOutlines;

    // footer settings
    converter.Options.DisplayFooter = true;
    converter.Footer.Height = 30;

    // page numbers can be added using a PdfTextSection object
    PdfTextSection text = new PdfTextSection(0, 10,
        "Page: {page_number} of {total_pages}  ",
        new System.Drawing.Font("Verdana", 10));
    text.HorizontalAlign = PdfTextHorizontalAlign.Right;
    converter.Footer.Add(text);


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

    // create font for page numbers
    PdfFont pageNumberFont = doc.Fonts.Add(
        new Font("Arial", TOC_Page_Font_Size, 
            FontStyle.Regular, GraphicsUnit.Point), 
        true);

    // get the right coordinate of the table of contents 
    // to position the page numbers
    float tocRight = doc.Pages[0].ClientRectangle.Width - 50;

    // add page numbers for the table of contents items
    for (int tocItem = 1; tocItem <= TOC_Items; tocItem++)
    {
        string tocTitleID = String.Format("TOC_Title{0}", tocItem);
        string tocTargetID = String.Format("TOC_Target{0}", tocItem);

        WebElement tocTitle = converter.Options.WebElementsMappingOptions
            .Result.GetElementByHtmlId(tocTitleID);
        WebElement tocTarget = converter.Options.WebElementsMappingOptions
            .Result.GetElementByHtmlId(tocTargetID);

        if (tocTitle == null || tocTarget == null)
        {
            // TOC items not found
            continue;
        }

        // get the TOC title page and rendering rectangle
        PdfPage tocPage = doc.Pages[tocTitle.PdfRectangles[0].PageIndex];
        RectangleF tocTitleRectangle = tocTitle.PdfRectangles[0].Rectangle;

        // get the page number of target where the TOC entry points
        int tocTargetPageNumber = tocTarget.PdfRectangles[0].PageIndex + 1;

        // add dashed line from TOC title to the page number
        PdfLineElement dashedLine = new PdfLineElement(
            tocTitleRectangle.Right + 5, 
            tocTitleRectangle.Y + tocTitleRectangle.Height - 4,
            tocRight, tocTitleRectangle.Y + tocTitleRectangle.Height - 4);
        dashedLine.LineStyle.LineWidth = 1;
        dashedLine.LineStyle.LineDashStyle = PdfLineDashStyle.Dash;
        dashedLine.ForeColor = Color.Black;
        tocPage.Add(dashedLine);

        // create the page number text element to the right of the TOC title
        PdfTextElement pageNumberTextElement = new PdfTextElement(tocRight + 5, 
                tocTitleRectangle.Y, -1, tocTitleRectangle.Height,
                tocTargetPageNumber.ToString(), pageNumberFont);
        pageNumberTextElement.HorizontalAlign = PdfTextHorizontalAlign.Left;
        pageNumberTextElement.VerticalAlign = PdfTextVerticalAlign.Middle;
        pageNumberTextElement.ForeColor = Color.Black;

        // add the page number to the right of the TOC entry
        tocPage.Add(pageNumberTextElement);
    }

    // save pdf document
    doc.Save(Response, false, "Sample.pdf");

    // close pdf document
    doc.Close();
}
See Also