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 { // 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) public void OnGet() { DdlRenderingEngine = "Chromium"; TxtUrl = Helper.WWWRoot(Request) + Url.Content("~/files/document2.html"); } [BindProperty] public string TxtUrl { get; set; } [BindProperty] public string DdlRenderingEngine { get; set; } = "Chromium"; public List<SelectListItem> RenderingEngines { get; } = new List<SelectListItem> { new SelectListItem { Value = "Chromium", Text = "Chromium" }, }; public IActionResult OnPost() { RenderingEngine renderingEngine = SampleForm.ParseEnum(DdlRenderingEngine, RenderingEngine.Chromium); // instantiate a html to pdf converter object HtmlToPdf converter = new HtmlToPdf(); converter.Options.NavigationTimeout = Startup.NavigationTimeout; converter.Options.RenderingEngine = renderingEngine; 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, using a system font // (subset-embedded) — cross-platform replacement for System.Drawing.Font. Liberation // Sans resolves on any host: the library bundles it and serves it from embedded bytes // when it is not installed. 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); // create font for page numbers PdfFont pageNumberFont = doc.Fonts.Add( PdfFont.CreateStandardFont(PdfStandardFont.Helvetica, TOC_Page_Font_Size)); // 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]; SelectPdf.Universal.Drawing.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 = new PdfColor(0, 0, 0); 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 = new PdfColor(0, 0, 0); // 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; } } }