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

This sample shows how the html to pdf converter can generate page numbers for a table of contents using SelectPdf Pdf Library for .NET. 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.

Test document

Url:



Sample Code C#



using System;
using System.Drawing;
using System.Web.Mvc;

namespace SelectPdf.Samples.Controllers
{
    public class TableOfContentsController : Controller
    {
        // 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)


        // GET: TableOfContents
        public ActionResult Index()
        {
            string url = 
                System.Web.VirtualPathUtility.ToAbsolute("~/files/document2.html");
            ViewData.Add("ViewTxtUrl", (new Uri(Request.Url, url)).AbsoluteUri);
            return View();
        }

        [HttpPost]
        public ActionResult SubmitAction(FormCollection fields)
        {
            // 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(fields["TxtUrl"]);

            // 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
            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;
        }
    }
}