The Telerik UI for ASP.NET AJAX RadSignature allows you to add a signature spot to PDFs and includes customization options like brush, stroke and background color. Learn how to add it to your PDF.
In the world of digital signatures, the ability to sign PDF documents is a game changer. And with the RadSignature component from Progress Telerik UI for ASP.NET AJAX, this process has never been easier!
Read on to find out how to effortlessly save a signature within a PDF file using the Telerik Document Processing Libraries (DPL) and to present the signed document in the RadPdfViewer control.
Whether you’re a developer wanting to integrate a digital signature into your project, or just looking to explore the world of digital signatures, this blog post is the perfect starting point.
Join us as we show you how to:
With the help of Telerik UI for ASP.NET AJAX, we’ll demonstrate how to convert the signature content to PDF and base64 string representation. And the best part—you can preview the PDF file using the built-in RadPdfViewer, and even save the new document with the click of a button. So why wait? Let’s dive into the world of digital signatures and explore the possibilities with RadSignature for ASP.NET AJAX.
Let’s start with declaring the needed controls on the page:
ASPX
<telerik:RadSignature runat="server" ID="RadSignature1" Maximizable="false" Height="150" Width="100%" Rounded="None"></telerik:RadSignature>
ASPX
<telerik:RadPdfViewer runat="server" ID="RadPdfViewer1" Height="700px">
<PdfjsProcessingSettings>
<FileSettings Url="Documents/Document.pdf" />
</PdfjsProcessingSettings>
</telerik:RadPdfViewer>
In this sample, we are passing the unsigned PDF file by a relative path through the FileSettings of the PdfViewer. Yet, there are multiple other ways you can populate the Viewer. The most common ones you can find explained in the 5 Different Approaches of Setting up the Content in RadPdfViewer for ASP.NET AJAX blog post.
ASPX
<telerik:RadToolBar runat="server" ID="RadToolBar1" AutoPostBack="false" OnClientButtonClicked="clientToolBarButtonClicked">
<Items>
...
</Items>
</telerik:RadToolBar>
The ToolBar is not under the spotlight now, so we will not dig into its details now. It is here just to sweeten the UX of the demo.
ASPX
<telerik:RadButton runat="server" ID="RadButton1" Text="Place Your Signature" Icon-PrimaryIconCssClass="rbSave" AutoPostBack="false" Primary="true" OnClientClicked="processSignature" />
Not all heroes wear capes, right? Just like that, not all components are on the front stage—some stay behind the scenes but are still needed:
ASPX
<telerik:RadClientExportManager runat="server" ID="RadClientExportManager1" OnClientPdfExporting="clientPdfExporting"></telerik:RadClientExportManager>
ASPX
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server" OnAjaxRequest="RadAjaxManager1_AjaxRequest" DefaultLoadingPanelID="RadAjaxLoadingPanel1">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadPdfViewer1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
ASPX
<telerik:RadAjaxLoadingPanel runat="server" ID="RadAjaxLoadingPanel1"></telerik:RadAjaxLoadingPanel>
Alongside all the above-mentioned components, we will also need to reference the Telerik Document Processing Libraries (DPL) and specifically the RadPdfProcessing library assemblies necessary for manipulating the content of a PDF file. Find the list of the .dll files required for the RadPdfProcessing in the dedicated documentation page.
Once we have the components defined, the DPL referenced and the unsigned PDF loaded in the view, we can go ahead with the logic.
I bet you’ve noticed that the event handlers we are going to use are already defined in the control snippets above. So, let’s go through the process after the user has applied their signature and clicks the blue “Place Your Signature” button.
The OnClientClicked
event of the button fires upon clicking the blue button. In its listener, we can get the canvas element with the applied signature with a bit of jQuery help, and also get the ClientExportManager client-side
control. Via the exportToPdf()
method of the export manager we can trigger exporting the canvas to a pdf:
JavaScript
processSignature = function (sender, args) {
//get the ClientExportManager client-side control object
var clientExportManager = $telerik.findControl(document, "RadClientExportManager1");
//get the canvas element holding the applied signature
var signatureElement = $(".k-signature-canvas > canvas");
//trigger exporting to pdf procedure via the built-in method of the ExportManager
clientExportManager.exportPDF(signatureElement);
}
After that, the OnClientPdfExporting
event of the export manager fires. Here we can get the PDF representation of the signature as a base64string directly from the event arguments (get_dataURI()
).
Get the AJAX manager and send an AJAX request to the server with the signature data optionally along with a custom file name:
JavaScript
clientPdfExporting = function (sender, args) {
//get the base64string of the pdf passed for exporting
var dataRaw = args.get_dataURI();
//get the RadAjaxManager control object
var ajaxManager = $telerik.findControl(document, "RadAjaxManager1");
var fileName = "signature.png";
//send an ajax request to the server with the signature data and the filename
ajaxManager.ajaxRequest(fileName + ";" + dataRaw);
//prevent further execution of the built-in exporting logic of the ExportManager
args.set_cancel(true);
}
Once the request reaches the server, the AjaxRequest event of the RadAjaxManager fires. There we can get the base64 string of the signature and pass it to the function responsible for generating a signed PDF. Finally, pass the base64 string representation of the signed PDF as content of the PdfViewer.
C#
protected void RadAjaxManager1_AjaxRequest(object sender, Telerik.Web.UI.AjaxRequestEventArgs e)
{
var base64 = e.Argument.Split(',')[1];
RadPdfViewer1.PdfjsProcessingSettings.FileSettings.Data = PreparePdf(base64);
}
Let’s explore the exact purpose of the PreparePdf()
method.
With the help of the Document Processing Libraries (DPL), we can easily generate an all-new copy of the unsigned PDF document that we have. Then we can append the signature content we already extracted into the new Pdf document at a desired position.
C#
public string PreparePdf(string pdfData)
{
byte[] resultingBytes = null;
byte[] finalBytes = null;
//initialize a PdfFormatProvider that will be used for processing the pdf conent
PdfFormatProvider provider = new PdfFormatProvider();
byte[] renderedBytes = Convert.FromBase64String(pdfData);
RadFixedDocument document1 = null;
//generate a RadFixedDocument object holding the signature data
RadFixedDocument document2 = provider.Import(renderedBytes);
//import the existing unsigned pdf file in another RadFixedDocument
string filePath = Server.MapPath("Documents/Document.pdf");
using (FileStream input = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
document1 = provider.Import(input);
}
//export the unsigned pdf as byte array
using (MemoryStream ms = new MemoryStream())
{
provider.Export(document1, ms);
resultingBytes = ms.ToArray();
}
//pass the byte array of the unsigned pdf and the RadFixedDocument with the applied signature to method that will combine them in a single byte array
finalBytes = AppendContent(resultingBytes, document2);
//convert the result to a base64 string and return it so it can be passed as content of the PdfViewer
string result = Convert.ToBase64String(finalBytes);
return result;
}
The actual manipulation of the PDF content happens in the AppendContent()
method. Its logic heavily relies on the functionalities exposed by the RadPdfProcessing library:
C#
private byte[] AppendContent(byte[] resultingBytes, RadFixedDocument document2)
{
RadFixedPage foregroundContentOwner = document2.Pages[0];
MemoryStream ms = new MemoryStream();
byte[] renderedBytes = null;
using (MemoryStream stream = new MemoryStream(resultingBytes))
{
using (PdfFileSource fileSource = new PdfFileSource(stream))
{
using (PdfStreamWriter fileWriter = new PdfStreamWriter(ms, true))
{
foreach (PdfPageSource pageSource in fileSource.Pages)
{
using (PdfPageStreamWriter pageWriter = fileWriter.BeginPage(pageSource.Size, pageSource.Rotation))
{
pageWriter.WriteContent(pageSource);
using (pageWriter.SaveContentPosition())
{
double xCenteringTranslation = (pageSource.Size.Width - foregroundContentOwner.Size.Width) - 320;
double yCenteringTranslation = (pageSource.Size.Height - foregroundContentOwner.Size.Height) - 110;
pageWriter.ContentPosition.Translate(xCenteringTranslation, yCenteringTranslation);
pageWriter.WriteContent(foregroundContentOwner);
}
}
}
}
}
}
renderedBytes = ms.ToArray();
return renderedBytes;
}
We will not go through each separate class and method of the DPL that is used, but I highly recommend spending some time getting familiar with the RadPdfProcessing Model and Concepts.
Everything written here is live and accessible in this demo. Go on and give it a try right away!
If you like what you see, you can further play with the RadSignature in the online demos or download its absolutely free and fully functional trial and give it a spin.
We value any feedback and the community voice, which you can share at the Feedback Portal too.
Doncho Milkov was a Technical Support Officer working with the Progress Telerik UI for ASP.NET AJAX components.