Export C1PrintDocument to PDF with Digital Signature

ComponentOne Pdf supports the creation digital signatures. However, there is no direct method to directly add digital signatures to the pdf generated from C1PrintDocument. This blog will guide you on how to create a pdf file containing digital signature from C1PrintDocument using C1Pdf. The process is as follows : 1. Convert C1PrintDocument pages to images. 2. Add these images in C1PdfDocument using DrawImage() method. 3. Add digital signature to each page. We will start by assigning a C1PrintDocument to the C1PrintPreviewControl. For simplicity we will use a single RenderText object to the C1PrintDocument body. However, you can use the same implementation for multi-document C1PrintDocument.

//Add contents to the C1PrintDocument and assign to C1PrintPreviewControl  

RenderText rtext = new RenderText();  

rtext.Text = "ComponentOne Reports™ for WinForms provides all the tools you need to meet your reporting, printing, previewing, and exporting needs. Add Microsoft-Access style database reporting. Create complex hierarchical documents with automatic word index, TOC generation, data binding, and more. Export, print, or preview your reports and documents. This edition of Reports for WinForms combines two previous products: Reports for .NET and Preview for .NET. The full functionality of the older Reports for .NET product is preserved, but the assembly name and namespace have changed.";  

doc.Body.Children.Add(rtext);  

doc.Generate();  

c1PrintPreviewControl1.Document = doc;

To add the real digital signature it is necessary to have a Certificate object with a private key. For this we will create "_certificate" object of type System.Security.Cryptography.X509Certificates.X509Certificate. The construor includes certicate file path, password and for the object as well as keyStorage flag values that controls where and how to import the private key.

private X509Certificate _certificate;  

_certificate = new X509Certificate2(@"..\\..\\C1PdfTest.pfx", "pdftest", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

The C1PrintDocument pages can be rendered as images using doc.Pages[i].AsMetafile() where i is the page number. The PrintDocument page can be rendered in pdf using C1PdfDocument object using DrawImage() method as :

//Clear the C1PdfDocument object  

c1PdfDocument1.Clear();  

//Pdf file path  

string fileName = Application.StartupPath + "\\\test.pdf";  

Image img;  

foreach (C1Page page in doc.Pages)  

{  

    //Convert C1PrintDocument page to an image  

    img = page.AsMetafile();  

    c1PdfDocument1.DrawImage(img, c1PdfDocument1.PageRectangle);  

}  

c1PdfDocument1.Save(fileName);

The C1Pdf supports the creation digital signatures in two mode. By default using the Windows mode and includes the hash of PDF file in the signature. For more reliable (but needs more memory to do it) use detached mode. To add a digital signature, we can use any field of the PDF acroform:

PdfSignature signature = new PdfSignature();  

c1PdfDocument1.AddField(signature, new RectangleF(100, 100, 200, 50));

So the invisible empty field without the digital signature will be inserted. In our implementation, we will add the real digital signature by setting Certificate property. We will also set Visibility, Reason, Handler properties of the signature.

PdfSignature signature = new PdfSignature();  

signature.Reason = "Test";  

signature.Certificate = _certificate as X509Certificate2;  

signature.Visibility = FieldVisibility.Visible;  

signature.Handler = SignatureHandler.PPKLite;

The signature field allows us to either set an image or display text in the pdf document. To show an image we will set the Image property.

signature.Image = img as Image;

If you do not want to show image, then you can display text by setting Text property.

signature.Text = "ComponentOne" + Environment.NewLine + "Signature field of C1Pdf";  

signature.Font = new Font("Tahoma", 14, FontStyle.Italic | FontStyle.Bold);

So Image property takes precedence over Text property. Now all we need do is add this field to the pdf document as :

c1PdfDocument1.AddField(signature, new RectangleF(100, c1PdfDocument1.PageRectangle.Height - 100, 200, 50));

So the pdf generation code becomes :

//Clear the C1PdfDocument object  

c1PdfDocument1.Clear();  

//Pdf file path  

string fileName = Application.StartupPath + "\\\test.pdf";  

Image img;  

foreach (C1Page page in doc.Pages)  

{  

    //Convert C1PrintDocument page to an image  

    img = page.AsMetafile();  

    c1PdfDocument1.DrawImage(img, c1PdfDocument1.PageRectangle);  

    PdfSignature signature = new PdfSignature();  

    signature.Reason = "Test";  

    signature.Certificate = _certificate as X509Certificate2;  

    signature.Visibility = FieldVisibility.Visible;  

    signature.Handler = SignatureHandler.PPKLite;  

    Image signImage = Properties.Resources.c1logo;  

    if (_rbImage.Checked)  

    {  

        signature.BorderWidth = FieldBorderWidth.Thin;  

        signature.BorderColor = Color.Gray;  

        signature.BackColor = Color.DarkGray;  

        signature.Image = signImage;  

    }  

    else  

    {  

        signature.BorderWidth = FieldBorderWidth.Medium;  

        signature.BorderColor = Color.Blue;  

        signature.BackColor = Color.White;  

        signature.Text = "ComponentOne" + Environment.NewLine + "Signature field of C1Pdf";  

        signature.Font = new Font("Tahoma", 14, FontStyle.Italic | FontStyle.Bold);  

    }  

    c1PdfDocument1.AddField(signature, new RectangleF(100, c1PdfDocument1.PageRectangle.Height - 100, 200, 50));  

}  

c1PdfDocument1.Save(fileName);  

System.Diagnostics.Process.Start(fileName);

Please download the Sample_DocDigitalSignature for the above implementation.

ComponentOne Pdf supports the creation digital signatures. However, there is no direct method to directly add digital signatures to the pdf generated from C1PrintDocument. This blog will guide you on how to create a pdf file containing digital signature from C1PrintDocument. The process is as follows : 1. Convert C1PrintDocument pages to images. 2. Add these images in C1PdfDocument using DrawImage() method. 3. Add digital signature to each page. We will start by assigning a C1PrintDocument to the C1PrintPreviewControl. For simplicity we will use a single RenderText object to the C1PrintDocument body. However, you can use the same implementation for multi-document C1PrintDocument.

//Add contents to the C1PrintDocument and assign to C1PrintPreviewControl  
RenderText rtext = new RenderText();  
rtext.Text = "ComponentOne Reports™ for WinForms provides all the tools you need to meet your reporting, printing, previewing, and exporting needs. Add Microsoft-Access style database reporting. Create complex hierarchical documents with automatic word index, TOC generation, data binding, and more. Export, print, or preview your reports and documents. This edition of Reports for WinForms combines two previous products: Reports for .NET and Preview for .NET. The full functionality of the older Reports for .NET product is preserved, but the assembly name and namespace have changed.";  
doc.Body.Children.Add(rtext);  
doc.Generate();  
c1PrintPreviewControl1.Document = doc;

To add the real digital signature it is necessary to have a Certificate object with a private key. For this we will create "_certificate" object of type System.Security.Cryptography.X509Certificates.X509Certificate. The construor includes certicate file path, password and for the object as well as keyStorage flag values that controls where and how to import the private key.

private X509Certificate _certificate;  
_certificate = new X509Certificate2(@"..\\..\\C1PdfTest.pfx", "pdftest", X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

The C1PrintDocument pages can be rendered as images using doc.Pages[i].AsMetafile() where i is the page number. The PrintDocumnet page can be rendered in pdf using C1Pdf object using DrawImage() method as :

//Clear the C1PdfDocument object  
c1PdfDocument1.Clear();  
//Pdf file path  
string fileName = Application.StartupPath + "\\\test.pdf";  

Image img;  
foreach (C1Page page in doc.Pages)  
{  
//Convert C1PrintDocument page to an image  
img = page.AsMetafile();  

c1PdfDocument1.DrawImage(img, c1PdfDocument1.PageRectangle);  
}  
c1PdfDocument1.Save(fileName);

The C1Pdf supports the creation digital signatures in two mode. By default using the Windows mode and includes the hash of PDF file in the signature. For more reliable (but needs more memory to do it) use detached mode. To add a digital signature, we can use any field of the PDF acroform:

PdfSignature signature = new PdfSignature();  
c1PdfDocument1.AddField(signature, new RectangleF(100, 100, 200, 50));

So the invisible empty field without the digital signature will be inserted. In our implementation, we will add the real digital signature by setting "Certificate" property. We will also set Visibility, Reason, Handler properties of the signature.

PdfSignature signature = new PdfSignature();  
signature.Reason = "Test";  
signature.Certificate = _certificate as X509Certificate2;  
signature.Visibility = FieldVisibility.Visible;  
signature.Handler = SignatureHandler.PPKLite;

The signature field allows us to either set an image or display text in the pdf document. To show an image we will set the Image property.

signature.Image = img as Image;

If you do not want to show image, then you can display text by setting Text property.

signature.Text = "ComponentOne" + Environment.NewLine + "Signature field of C1Pdf";  
signature.Font = new Font("Tahoma", 14, FontStyle.Italic | FontStyle.Bold);

So Image property takes precedence over Text property. Now all we need do is add this field to the pdf document as : c1PdfDocument1.AddField(signature, new RectangleF(100, c1PdfDocument1.PageRectangle.Height - 100, 200, 50)); So the pdf generation code becomes :

//Clear the C1PdfDocument object  
c1PdfDocument1.Clear();  
//Pdf file path  
string fileName = Application.StartupPath + "\\\test.pdf";  

Image img;  
foreach (C1Page page in doc.Pages)  
{  
//Convert C1PrintDocument page to an image  
img = page.AsMetafile();  

c1PdfDocument1.DrawImage(img, c1PdfDocument1.PageRectangle);  

PdfSignature signature = new PdfSignature();  
signature.Reason = "Test";  
signature.Certificate = _certificate as X509Certificate2;  
signature.Visibility = FieldVisibility.Visible;  
signature.Handler = SignatureHandler.PPKLite;  
Image signImage = Properties.Resources.c1logo;  

if (_rbImage.Checked)  
{  
signature.BorderWidth = FieldBorderWidth.Thin;  
signature.BorderColor = Color.Gray;  
signature.BackColor = Color.DarkGray;  
signature.Image = signImage;  
}  
else  
{  
signature.BorderWidth = FieldBorderWidth.Medium;  
signature.BorderColor = Color.Blue;  
signature.BackColor = Color.White;  
signature.Text = "ComponentOne" + Environment.NewLine + "Signature field of C1Pdf";  
signature.Font = new Font("Tahoma", 14, FontStyle.Italic | FontStyle.Bold);  
}  

c1PdfDocument1.AddField(signature, new RectangleF(100, c1PdfDocument1.PageRectangle.Height - 100, 200, 50));  
}  
c1PdfDocument1.Save(fileName);  
System.Diagnostics.Process.Start(fileName);

Please download the sample for the above implementation.

GrapeCity

GrapeCity Developer Tools
comments powered by Disqus