The HiQPdf Chromium library allows you to add stamps to an existing PDF document using any valid HTML markup and elements. The HTML content can also include the template variables {page_number} and {total_pages} to insert page numbering.
HTML stamps can be added to an existing PDF using the PdfEditorAddHtmlTemplate(Int32, Int32, Int32, PdfTemplateHorizontalAlign, PdfTemplateVerticalAlign, String, String) method.
An object of type PdfEditor can be created by loading an existing PDF document either from a memory buffer containing the PDF data using the PdfEditorPdfEditor(Byte, String) constructor, or from a PDF file using the PdfEditorPdfEditor(String, String) constructor. You can optionally specify a user or owner password if the PDF document is password protected.
There are overloaded versions of the AddHtmlTemplate() method that allow you to create HTML templates rendered in PDF pages, using either a URL to an HTML page or an HTML string with an optional base URL.
You can specify the horizontal and vertical alignment of the template on the PDF page, or use absolute X and Y coordinates. The alignment takes precedence over the coordinates when set to a value other than None.
The template height can be auto-resized based on the HTML content or set to a fixed height, depending on the method parameters.
The most important options related to adding HTML stamps are:
HTML Stamp Options
HTML Template Source. The source of the HTML template used by the stamp can be specified when calling the AddHtmlTemplate() method and can also be modified after the stamp object is created by setting either the Html or the HtmlSourceUrl property, to provide the HTML content directly or specify a URL from which to retrieve the HTML. If both properties are set, the directly provided HTML code takes precedence. When setting the Html property, you must also set the HtmlBaseUrl property, which is used to resolve external resources in the HTML.
Stamp Positioning. The stamp can be positioned using absolute X and Y coordinates, relative to the top-left corner of the PDF page, through the X and Y properties. However, in many cases, it's easier to use alignment options instead, by setting the HorizontalAlign and VerticalAlign properties.
You can specify the positioning parameters when calling the PdfEditorAddHtmlTemplate(Int32, Int32, Int32, PdfTemplateHorizontalAlign, PdfTemplateVerticalAlign, String, String) method and later update them using the properties mentioned above.
If both absolute coordinates and alignment values are provided, the alignment settings will override the corresponding absolute positions.
Stamp Visibility. You can control the visibility of stamp on the first PDF page, odd pages, and even pages using the ShowInFirstPage, ShowInOddPages and ShowInEvenPages properties.
The first page refers to the first page generated from the HTML content if ShowOnlyInHtmlToPdfPages is set to true, or to the first page of the final PDF document, which may include table of contents pages or pages from external PDF documents, if it is set to false. The page following the first is considered even, the next one odd, and so on.
Stamp Opacity. You can control the opacity setting the Opacity property to a value between 0 and 1 to be applied to entire template. For example, setting the property to 0.75 will lower the opacity to 75% . The default value is 1 and the rendered PDF content will have its original opacity.
If you want to control only the opacity of the HTML template background, you can do this by setting the body element style to background-color: rgba(255, 255, 255, 0.75), which will set the opacity to 0.75, as exemplified in HTML code below.
<!-- Use background-color: rgba(r, g, b, a) to apply background opacity (a = 0 transparent, 1 opaque) -->
<body style="background-color: rgba(255, 255, 255, 0.75)">
HTML Template Variables. The HTML used in stamp can include variables for page numbering which are replaced with the actual values when the PDF pages are generated. The following template variable can be used:
{page_number}: Current page number
{total_pages}: Total pages in the document
Auto Size Content Height. The AutoSizeContentHeight property allows the stamp content height to be auto resized based on the rendered HTML content height.
The minimum and maximum heights are controlled by the MinContentHeight and MaxContentHeight properties.
When this property is false, the content height is given by the Height property. When this property is true, if the Height property is set with a positive value and the FitHeight property is also true, the content may be scaled down to fit the specified height. The default value is true.
Stamp Height. You can specify a fixed height for the stamp in PDF pages using the Height property, in combination with the AutoSizeContentHeight property, to control the final height of the stamp in the PDF page.
When the height is set to a positive value, it defines the stamp height if AutoSizeContentHeight is false, or if it is true and FitHeight is also true.
When the height is set to 0 or a negative value and AutoSizeContentHeight is true, the stamp height is automatically determined based on the HTML content height. The default value is 0.
Fit Height. You can use the FitHeight property in combination with the AutoSizeContentHeight property to control the final height of the stamp in the PDF page.
If this property is set to true, and AutoSizeContentHeight is also true and Height has a positive value, then the HTML content may be scaled down to fit within the specified stamp height in the PDF. The default value is true.
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using HiQPdf.Chromium;
namespace HiQPdf_Chromium_AspNetDemo.Controllers
{
public class Stamp_with_HTML_Existing_PDFController : Controller
{
private readonly IWebHostEnvironment m_hostingEnvironment;
public Stamp_with_HTML_Existing_PDFController(IWebHostEnvironment hostingEnvironment)
{
m_hostingEnvironment = hostingEnvironment;
}
public IActionResult Index()
{
SetCurrentViewData();
return View();
}
[HttpPost]
public async Task<IActionResult> StampPdf(IFormCollection collection)
{
// Replace the demo serial number with the serial number received upon purchase
// to run the converter in licensed mode
Licensing.SerialNumber = "YCgJMTAE-BiwJAhIB-EhlWTlBA-UEBRQFBA-U1FOUVJO-WVlZWQ==";
// Get the pdf file to convert
string pdfUrl = collection["pdfFileUrlTextBox"][0].Trim();
if (string.IsNullOrWhiteSpace(pdfUrl))
throw new Exception("No PDF file to stamp");
byte[] inputPdfBytes;
if (pdfUrl.StartsWith("file://", StringComparison.OrdinalIgnoreCase))
{
string localPath = new Uri(pdfUrl).LocalPath;
inputPdfBytes = await System.IO.File.ReadAllBytesAsync(localPath);
}
else
{
using var httpClient = new System.Net.Http.HttpClient();
inputPdfBytes = await httpClient.GetByteArrayAsync(pdfUrl);
}
var pdfEditor = new PdfEditor(inputPdfBytes);
bool stampEnabled = collection["stampEnabledCheckBox"].Count > 0;
if (stampEnabled)
{
PdfHtmlTemplate stamp = null;
// Get stamp width
int stampWidth = int.Parse(collection["stampWidthTextBox"]);
// Get stamp height
int stampHeight = 0;
string stampHeightValueString = collection["stampHeightTextBox"];
if (!string.IsNullOrEmpty(stampHeightValueString))
stampHeight = int.Parse(stampHeightValueString);
// Get stamp top left corner X and Y position
int x = int.Parse(collection["stampXPositionTextBox"]);
int y = int.Parse(collection["stampYPositionTextBox"]);
// Get horizontal alignment, which takes precedence over the X coordinate when specified
PdfTemplateHorizontalAlign horizontalAlign = SelectedHorizontalAlign(collection["horizontalAlignDropDownList"]);
// Get vertical alignment, which takes precedence over the Y coordinate when specified
PdfTemplateVerticalAlign verticalAlign = SelectedVerticalAlign(collection["verticalAlignDropDownList"]);
// Set the stamp HTML from an URL or from a HTML string
bool stampHtmlFromUrl = collection["StampHtmlSource"] == "stampUrlRadioButton";
if (stampHtmlFromUrl)
{
string stampUrl = collection["stampUrlTextBox"];
if (stampHeight > 0)
{
// The stamp has a specified height
stamp = pdfEditor.AddHtmlTemplate(x, y, stampWidth, stampHeight,
horizontalAlign, verticalAlign, stampUrl);
}
else
{
// The stamp size is automatically determined from the HTML content when AutoSizeContentHeight is true
stamp = pdfEditor.AddHtmlTemplate(x, y, stampWidth, stampHeight,
horizontalAlign, verticalAlign, stampUrl);
}
}
else
{
string stampHtml = collection["stampHtmlTextBox"];
string stampHtmlBaseUrl = collection["stampHtmlBaseUrlTextBox"];
if (stampHeight > 0)
{
// The stamp has a specified height
stamp = pdfEditor.AddHtmlTemplate(x, y, stampWidth, stampHeight,
horizontalAlign, verticalAlign, stampHtml, stampHtmlBaseUrl);
}
else
{
// The stamp size is automatically determined from the HTML content when AutoSizeContentHeight is true
stamp = pdfEditor.AddHtmlTemplate(x, y, stampWidth, stampHeight,
horizontalAlign, verticalAlign, stampHtml, stampHtmlBaseUrl);
}
}
// If AutoSizeContentHeight is true, the Height property is positive and FitHeight is true,
// the content may be scaled down to fit the specified height
bool fitStampHeight = collection["fitStampHeightCheckBox"].Count > 0;
stamp.FitHeight = fitStampHeight;
// Set the auto resize stamp option to allow the stamp height adjust based on HTML content
bool autoSizeStampContentHeight = collection["autoSizeStampContentHeightCheckBox"].Count > 0;
stamp.AutoSizeContentHeight = autoSizeStampContentHeight;
// Set Min and Max content height used when the AutoSizeContentHeight property is true
stamp.MinContentHeight = int.Parse(collection["stampMinContentHeightTextBox"]);
stamp.MaxContentHeight = int.Parse(collection["stampMaxContentHeightTextBox"]);
// Set stamp visibility in PDF for the first page, odd pages, and even pages
stamp.ShowInFirstPage = collection["showStampInFirstPageCheckBox"].Count > 0;
stamp.ShowInOddPages = collection["showStampInOddPagesCheckBox"].Count > 0;
stamp.ShowInEvenPages = collection["showStampInEvenPagesCheckBox"].Count > 0;
// Sets the opacity for the entire stamp content, including text.
// To apply opacity only to the background, use the alpha channel
// in the CSS background-color property of the body element,
// e.g., background-color: rgba(255, 255, 255, 0.75);
int opacity = int.Parse(collection["stampOpacityTextBox"]);
stamp.Opacity = ((float)opacity) / 100;
// Optimize the stamp rendering time by providing a hint if the HTML template contains variables such as { page_number} or { total_pages}
stamp.SkipVariablesParsing = collection["skipVariablesParsingCheckBox"].Count > 0;
// Optionally set additional time to wait for the asynchronous stamp HTML content before rendering
if (collection["waitBeforeConvertTextBox"][0].Length > 0)
stamp.WaitBeforeConvert = int.Parse(collection["waitBeforeConvertTextBox"]);
}
// Stamp the PDF and save the resulted PDF document in a memory buffer
byte[] outPdfBuffer = pdfEditor.Save();
// Send the PDF file to browser
FileResult fileResult = new FileContentResult(outPdfBuffer, "application/pdf");
fileResult.FileDownloadName = "Stamp_with_HTML_Existing_PDF.pdf";
return fileResult;
}
private PdfTemplateHorizontalAlign SelectedHorizontalAlign(string selectedValue)
{
switch (selectedValue)
{
case "None":
return PdfTemplateHorizontalAlign.None;
case "Left":
return PdfTemplateHorizontalAlign.Left;
case "Center":
return PdfTemplateHorizontalAlign.Center;
case "Right":
return PdfTemplateHorizontalAlign.Right;
default:
return PdfTemplateHorizontalAlign.None;
}
}
private PdfTemplateVerticalAlign SelectedVerticalAlign(string selectedValue)
{
switch (selectedValue)
{
case "None":
return PdfTemplateVerticalAlign.None;
case "Top":
return PdfTemplateVerticalAlign.Top;
case "Center":
return PdfTemplateVerticalAlign.Center;
case "Bottom":
return PdfTemplateVerticalAlign.Bottom;
default:
return PdfTemplateVerticalAlign.None;
}
}
private void SetCurrentViewData()
{
ViewData["ContentRootPath"] = 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();
ViewData["CurrentPageUrl"] = uriBuilder.Uri.AbsoluteUri;
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>HTML Stamp with Page Numbers</title>
</head>
<!-- Use background-color: rgba(r, g, b, a) to apply background opacity (a = 0 transparent, 1 opaque) -->
<body style="background-color: rgba(255, 255, 255, 0.9); font-family: 'Times New Roman'; font-size: 16px; margin: 5px">
<table style="width: 100%; border: 3px solid royalblue">
<tr>
<td>
<a href="http://www.hiqpdf.com">
<img alt="Logo Image" src="Images/HiQPdfLogo.png" />
</a>
</td>
<td>
<table>
<tr>
<td style="font-size: 30px; font-weight: bold; color: #BE1200">
HTML Stamp with Page Numbers
</td>
</tr>
<tr>
<td>
<span style="font-size: 16px">Page <span style="color:blue">{page_number}</span> of <span style="color:green">{total_pages}</span> pages</span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>