In this post, I demonstrate how to add a signature to a PDF using the Blazor Server.
The objective is to guide you in writing a signature in a PDF document. The project is online at https://blazorSignature.jsmotta.com/sign.
This interface allows you to draw your signature with the mouse or fingers on mobile devices.
This is a practical post and is not intended to elucidate all technologies (Blazor Server, Telerik UI for Blazor, Telerik Documents libraries, and NuGet) involved in this project.
Let’s do it!
Starting with Visual Studio in Extensions -> Telerik -> Telerik UI for Blazor -> Create new Telerik Project, follow the instructions.
- Choose the best location for your project.
- I selected the Server and Admin template.
- Open NuGet on the solution and add these Telerik Components.
The Code
We start adding the TelerikSignature, the control that interacts with the user to draw the signature.
The name of who is singing is read in the input TelerikTextBox.
<div id="about" class="k-d-flex-col k-justify-content-between k-align-items-start" style="margin:2em; width:60%;">
<h2>Pdf Sign</h2>
<br />
<label label-for="MyName">Your Name:</label><br />
<TelerikTextBox @bind-Value="@MyName"></TelerikTextBox>
<br/>
<p>Draw your signature.</p>
<TelerikSignature @bind-Value="@SignatureValue"
Width="@(PWidth+("px"))"
Height="@(PHeight+("px"))" />
</div>
Here, we draw the preview on the screen according to the emptiness of SignatureValue. This is only for this sample:
@if (!string.IsNullOrEmpty(SignatureValue))
{
<div class="k-d-flex-col k-justify-content-between k-align-items-start" style="margin:2em; width:60%;">
<p><TelerikButton OnClick="@SignPdf">Sign Document</TelerikButton></p>
@if (!string.IsNullOrEmpty(UrlSignedPdf))
{
<a class="telerik-blazor k-button k-button-solid k-rounded-md k-button-md k-button-solid-base" href="@UrlSignedPdf" target="_blank"><span class="k-buttom-text">Download</span></a>
}
<h2>Signature Value</h2>
<img alt='Signature' src="@SignatureValue" width="@PWidth" height="@PHeight" />
</div>
}
Below is the code that does the magic on SingPdf(). Here are the steps.
- Lines 15 and 16 establish compatibility.
- Assigned unique names to the files, PDFs, and images;
- Accessed the template PdfSample.pdf from wwwroot\Pdfs at line 28.
- Line 39 imports the PDF document. Line 47 defines the last page to be drawn.
- Specified a position to draw on line 60.
- Drew MyName on line 61.
- The signature was rendered at line 66.
- Exported to the new file at line 70.
- Line 76 specifies the route for downloading the link.
@code {
// Initialized the variables
const int PWidth = 500; // Default width
const int PHeight = 150; // Default height
private string MyName { get; set; } = "Your Name";
private string SignatureValue { get; set; } = string.Empty;
private string UrlSignedPdf { get; set; } = string.Empty;
private const string PngBase64Prefix = "data:image/png;base64,";
async Task SignPdf()
{
// .NET 6 removed the System.Drawing.Common package, so we need to use the Telerik.Documents.ImageUtils package to work with images
FixedExtensibilityManager.ImagePropertiesResolver = new Telerik.Documents.ImageUtils.ImagePropertiesResolver();
FixedExtensibilityManager.JpegImageConverter = new Telerik.Documents.ImageUtils.JpegImageConverter();
// Generate unique file names for the signature image and the signed PDF document
var tickUniq = DateTime.Now.Ticks;
var signaturePdfFileName = $@"\Pdfs\signature_{tickUniq}.pdf";
var signaturePngFileName = HostingEnvironment.WebRootPath + $@"\\Signatures\\ignature_{tickUniq}.png";
var filePdf2Sign = HostingEnvironment.WebRootPath + @"\\Pdfs\\PdfSample.pdf";
// Save the signature image to a file
var imageBytes = Convert.FromBase64String(SignatureValue[PngBase64Prefix.Length..]);
await using (var imageFile = new FileStream(signaturePngFileName, FileMode.Create))
{
await imageFile.WriteAsync(imageBytes, 0, imageBytes.Length);
await imageFile.FlushAsync();
}
// Load the PDF document
var provider = new PdfFormatProvider();
RadFixedDocument document;
await using (Stream input = System.IO.File.OpenRead(filePdf2Sign))
{
document = provider.Import(input);
}
// Add the signature to the last page of the document
await using (var source = System.IO.File.Open(signaturePngFileName, FileMode.Open))
{
var imageSource = new ImageSource(source);
var lastPage = document.Pages.Last();
var editor = new FixedContentEditor(lastPage);
// Add the signature to the last page of the document
var textFragment = new TextFragment(MyName)
{
Font = FontsRepository.HelveticaBoldOblique,
FontSize = 14,
Fill = new Telerik.Windows.Documents.Fixed.Model.ColorSpaces.RgbColor(0, 0, 0)
};
// Set the position of the MyName
var size = new Telerik.Documents.Primitives.Size(PWidth, PHeight);
editor.Position.Translate(offsetX: 150, offsetY: 800);
editor.DrawText(MyName);
// Set the position of the signature
editor.Position.Translate(offsetX: 150, offsetY: textFragment.FontSize + 10 + 800);
editor.DrawImage(imageSource, size);
}
// Save the signed PDF document
await using (var pdfStream = System.IO.File.Create(HostingEnvironment.WebRootPath + signaturePdfFileName))
{
provider.Export(document, pdfStream);
}
// Set the URL of the signed PDF document
UrlSignedPdf = signaturePdfFileName.Replace("\\", "/")[1..];
}
}
Conclusion
It was not easy to do without a sample at the beginning, but now I've included the source to make it easier. Feel free to access it on my GitHub: https://github.com/jssmotta/TelerikBlazorSignature24.