You can select the HTML elements whose position in the PDF you want to retrieve by specifying a CSS selector. Along with the position in the PDF, you can also retrieve other useful information, such as ID, tag name, CSS class and text content. This feature enables various possibilities for post-processing the PDF document generated from HTML and provides insight into how specific HTML elements are rendered in the final PDF. In the code sample, the retrieved elements are highlighted in the PDF with colored borders based on their tag names, but other useful scenarios are also possible, such as adding a PDF annotation to a specific HTML element.
The CSS selector can be assigned to the HtmlToPdfHtmlElementsInfoSelector property of the converter. For example, you can select an HTML element by its ID using the #ConvertedHtmlElementID selector, or select elements with a specific CSS class using the .ConvertedHtmlElementClass selector.
The collected information about the HTML elements is made available after the HTML to PDF conversion through the HtmlToPdfHtmlElementsInfo property of the converter, which exposes an object of the HtmlElementInfoCollection type. This class allows you to iterate through all the retrieved elements or search for specific elements by ID, tag name or CSS class name.
using System;
using System.IO;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using HiQPdf_Next_AspNetDemo.Models;
using HiQPdf.Next;
namespace HiQPdf_Next_AspNetDemo.Controllers
{
public class RetrieveHtmlElementPositionsInPdfController : Controller
{
private readonly IWebHostEnvironment m_hostingEnvironment;
public RetrieveHtmlElementPositionsInPdfController(IWebHostEnvironment hostingEnvironment)
{
m_hostingEnvironment = hostingEnvironment;
}
public ActionResult Index()
{
var model = SetViewModel();
return View(model);
}
[HttpPost]
public ActionResult ConvertHtmlToPdf(RetrieveHtmlElementPositionsViewModel model)
{
if (!ModelState.IsValid)
{
var errorMessage = ModelStateHelper.GetModelErrors(ModelState);
throw new ValidationException(errorMessage);
}
// Set the serial number received after purchase to use the library in licensed mode; leave it commented for demo mode
// Licensing.SerialNumber = "your-serial-number";
// Create a HTML to PDF converter object with default settings
HtmlToPdf htmlToPdfConverter = new HtmlToPdf();
if (model.EnableElementsInfoSelector)
{
// The CSS selector used to identify HTML elements for metadata collection.
// The retrieved information will be available in the HtmlElementsInfo object,
// which is exposed by htmlToPdfConverter after the conversion
htmlToPdfConverter.HtmlElementsInfoSelector = model.RetrieveElementsInfoSelector;
}
// Optionally generate a table of contents for the PDF document
htmlToPdfConverter.Document.GenerateTableOfContents = model.GenerateToc;
// Optionally set a conversion delay to allow asynchronous content (e.g., JavaScript)
// to load before rendering
if (model.WaitBeforeConvert.HasValue)
htmlToPdfConverter.WaitBeforeConvert = model.WaitBeforeConvert.Value;
byte[] outPdfBuffer = null;
if (model.HtmlPageSource == "Html")
{
string htmlWithForm = model.HtmlString;
string baseUrl = model.BaseUrl;
// Convert a HTML string to a PDF document
outPdfBuffer = htmlToPdfConverter.ConvertHtmlToMemory(htmlWithForm, baseUrl);
}
else
{
string url = model.Url;
// Convert the HTML page to a PDF document
outPdfBuffer = htmlToPdfConverter.ConvertUrlToMemory(url);
}
// Process the retrieved HTML elements info
if (htmlToPdfConverter.HtmlElementsInfo != null)
{
// Load the generated PDF document into a PDF editor
using PdfEditor pdfEditor = new PdfEditor(outPdfBuffer);
// Highlight each retrieved HTML element in the PDF with a colored rectangle
// based on its tag type. By default, GetHighlightColor() assigns specific colors
// to h1, h2, h3 and h4 tags while other tags are highlighted in red
foreach (HtmlElementInfo elemInfo in htmlToPdfConverter.HtmlElementsInfo.Elements)
{
// An HTML element may be rendered across multiple PDF pages,
// resulting in multiple PdfRenderedRectangle instances
foreach (PdfRenderedRectangle renderedRectangle in elemInfo.RenderedRectangles)
{
int pageNumber = renderedRectangle.PageNumber;
PdfRectangleF bounds = renderedRectangle.Bounds;
PdfColor borderColor = GetHighlightColor(elemInfo.TagName);
var rectangleElement = new PdfRectangleElement(
bounds.X, bounds.Y, bounds.Width, bounds.Height)
{
BorderColor = borderColor
};
pdfEditor.AddRectangle(pageNumber, rectangleElement);
}
}
// Save the PDF with highlighted elements into the output buffer
outPdfBuffer = pdfEditor.Save();
}
// Send the PDF file to browser
FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf");
fileResult.FileDownloadName = "RetrieveHtmlElementPositionsInPdf.pdf";
return fileResult;
}
private PdfColor GetHighlightColor(string tagName)
{
PdfColor color = PdfColor.Red;
switch (tagName)
{
case "h1":
color = PdfColor.Green;
break;
case "h2":
color = PdfColor.Blue;
break;
case "h3":
color = PdfColor.Purple;
break;
case "h4":
color = PdfColor.Yellow;
break;
default:
color = PdfColor.Red;
break;
}
return color;
}
private RetrieveHtmlElementPositionsViewModel SetViewModel()
{
var model = new RetrieveHtmlElementPositionsViewModel();
var contentRootPath = Path.Combine(m_hostingEnvironment.ContentRootPath, "wwwroot");
HttpRequest request = ControllerContext.HttpContext.Request;
UriBuilder uriBuilder = new UriBuilder();
uriBuilder.Scheme = request.Scheme;
uriBuilder.Host = request.Host.Host;
if (request.Host.Port != null)
uriBuilder.Port = (int)request.Host.Port;
uriBuilder.Path = request.PathBase.ToString() + request.Path.ToString();
uriBuilder.Query = request.QueryString.ToString();
string currentPageUrl = uriBuilder.Uri.AbsoluteUri;
string rootUrl = currentPageUrl.Substring(0, currentPageUrl.Length - "RetrieveHtmlElementPositionsInPdf".Length);
model.HtmlString = System.IO.File.ReadAllText(Path.Combine(contentRootPath, "DemoFiles/Html/HTML_Element_Positions.html"));
model.BaseUrl = rootUrl + "DemoFiles/Html/";
model.Url = rootUrl + "DemoFiles/Html/HTML_Element_Positions.html";
return model;
}
}
}