Convert CSV/excel/pdf memory stream to PDF file with digital sign and password protection

I would appreciate if someone can point me in the right direction to solve the issue which I am facing. Below are the details.

Scope for implementation: I am trying to convert csv/excel/pdf memory stream into pdf file with digital sign and password protection.

Issue: Aspose.Cell is throwing an error (Aspose.Cells.CellsException: 'This file’s format is not supported or you don’t specify a correct format.)

Below is the code sample.

public static class Extensions
{
public static string ToCSV(this DataTable table)
{
var result = new StringBuilder();
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(table.Columns[i].ColumnName);
result.Append(i == table.Columns.Count - 1 ? “\n” : “,”);
}

        foreach (DataRow row in table.Rows)
        {
            for (int i = 0; i < table.Columns.Count; i++)
            {
                result.Append(row[i].ToString());
                result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
            }
        }
        return result.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        DataTable table = new DataTable();
        table.Columns.Add("Name");
        table.Columns.Add("Age");
        table.Rows.Add("John Doe", "45");
        table.Rows.Add("Jane Doe", "35");
        table.Rows.Add("Jack Doe", "27");
        var bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(table.ToCSV());
        MemoryStream stream = new MemoryStream(bytes);

        csvToPDF(stream);
        
        Console.ReadLine();

    }
   
    public static void csvToPDF(MemoryStream stream)
    {
        //Certificate file and its password
        string certFileName = @"C:\test\test-cert-EA.pfx";  
        string password = "2020";

        //Load the stream into workbook
        Workbook wb2 = new Workbook(stream);
        

        //Create the digital signature collection
        Aspose.Cells.DigitalSignatures.DigitalSignatureCollection dsCollection = new Aspose.Cells.DigitalSignatures.DigitalSignatureCollection();

        //Create new certificate
        System.Security.Cryptography.X509Certificates.X509Certificate2 certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(certFileName, password);

        //Create new digital signature and add it in digital signature collection
        Aspose.Cells.DigitalSignatures.DigitalSignature signature = new Aspose.Cells.DigitalSignatures.DigitalSignature(certificate, "Aspose.Cells added new digital signature.", DateTime.Now);
        dsCollection.Add(signature);

        //Add digital signature collection inside the workbook
        wb2.AddDigitalSignature(dsCollection);


        // Specify XOR encryption type.
        wb2.SetEncryptionOptions(EncryptionType.XOR, 40);

        // Specify Strong Encryption type (RC4,Microsoft Strong Cryptographic Provider).
        wb2.SetEncryptionOptions(EncryptionType.StrongCryptographicProvider, 128);

        // Password protect the file.
        wb2.Settings.Password = "1234";

        //Save the workbook and dispose it.
        //workbook.Save("outputDigitallySignedByCells.xlsx");
        MemoryStream pdfStream = new MemoryStream();
       // wb2.Save(pdfStream, Aspose.Cells.SaveFormat.Pdf);

        ////OR
        wb2.Save(@"c:\test\output.pdf", Aspose.Cells.SaveFormat.Pdf);

        wb2.Dispose();

        //return pdfStream;
    }
           
}

@nchada,
You are trying to load encoded CSV stream into workbook object which is causing this issue. Please modify your csvToPDF() function as mentioned below and share the feedback.

public static void csvToPDF(MemoryStream stream)
{
    //Certificate file and its password
    string certFileName = @"C:\test\test-cert-EA.pfx";
    string password = "2020";

    var stringReverse = Encoding.GetEncoding("iso-8859-1").GetString(stream.ToArray());

    Aspose.Cells.TxtLoadOptions opts = new Aspose.Cells.TxtLoadOptions();
    opts.Separator = ',';

    byte[] byteArray = Encoding.ASCII.GetBytes(stringReverse);
    MemoryStream stream2 = new MemoryStream(byteArray);
    //Load the stream into workbook
    Workbook wb2 = new Workbook(stream2,opts);

    //Just for testing
    wb2.Save(@"C:\Test\output.xlsx");
    wb2.Save(@"C:\Test\output.pdf", Aspose.Cells.SaveFormat.Pdf);

//Your remaining code here
...
...
...
}

Please note that if you want to sign and password protect the Excel file, then follow the code as you mentioned in your example and if you want to sign the output PDF, have a look at the following article:

Working with Security and Signatures in PDF using Aspose.PDF for .NET

1 Like

DemoGraphis-Aspose.pdf (61.5 KB)
Hi,
modified the code as you mentioned and encountered below issues.

  1. converting excel/csv stream to pdf is working but pdf format doesn’t look good (attached converted pdf)
  2. password protection is not working.
  3. I don’t see a digital sign on the pdf.

can you send a sample that converts the memory stream (pdf memory stream not the csv) into pdf file using Aspose.Pdf?

Thanks,
Narsi.

@nchada,
Could you please share the output Excel file which is created from the CSV data before saving as PDF file? It will help us to reproduce the scenario here and provide assistance accordingly.

noDemoGraphis-CSV.zip (2.1 KB)
PFA.

@nchada,

You may please try following sample code to convert the excel file to PDF in a proper format. If it does not fulfil your requirement, please share an expected PDF file created by MS Excel using the same CSV file which you have shared above.

Workbook workbook = new Workbook(@"E:\DemoGraphis-CSV\DemoGraphis-CSV.csv");
workbook.Worksheets[0].AutoFitColumns();
PdfSaveOptions saveOptions = new PdfSaveOptions(Aspose.Cells.SaveFormat.Pdf);
saveOptions.AllColumnsInOnePagePerSheet = true;
workbook.Save(@"E:\DemoGraphis-CSV\DemoGraphis-CSV.pdf", saveOptions);

Could you please share what issues have you faced while following the articles in the shared document section? Share your sample code, the template file, output file and expected output file for our reference?

Could you please share sample C# code where you convert some existing PDF file to your desired stream. We will provide you with the sample code which can convert that stream to PDF again.

can we have a call to discuss the issues ? if yes please let me know your availability and contact information.

demograph.pdf (57.2 KB)

updated the code with your changes,now format looks good. Still password protection and digital sign part is not working, below is the sample code.

attached the csv to pdf conversion file.

public void csvToPDF(MemoryStream stream)
{
//Create a template workbbok for teting
var stringReverse = Encoding.GetEncoding(“iso-8859-1”).GetString(stream.ToArray());
// var stringReverse = Encoding.UTF8.GetString(stream.ToArray());

        Aspose.Cells.TxtLoadOptions opts = new Aspose.Cells.TxtLoadOptions();
        opts.Separator = ',';

        byte[] byteArray = Encoding.ASCII.GetBytes(stringReverse);
        MemoryStream stream2 = new MemoryStream(byteArray);
        //Load the stream into workbook
        Workbook wb2 = new Workbook(stream2, opts);

        wb2.Worksheets[0].AutoFitColumns();

        PdfSaveOptions saveOptions = new PdfSaveOptions(Aspose.Cells.SaveFormat.Pdf);

        saveOptions.AllColumnsInOnePagePerSheet = true;

        //Create the digital signature collection
        Aspose.Cells.DigitalSignatures.DigitalSignatureCollection dsCollection = new Aspose.Cells.DigitalSignatures.DigitalSignatureCollection();

        //Create new certificate
        System.Security.Cryptography.X509Certificates.X509Certificate2 certificate = new System.Security.Cryptography.X509Certificates.X509Certificate2(HttpContext.Current.Server.MapPath("~") + "\\test-cert-EA.pfx", "2020");

        //Create new digital signature and add it in digital signature collection
        Aspose.Cells.DigitalSignatures.DigitalSignature signature = new Aspose.Cells.DigitalSignatures.DigitalSignature(certificate, "Aspose.Cells added new digital signature.", DateTime.Now);
        dsCollection.Add(signature);

        //Add digital signature collection inside the workbook
        wb2.AddDigitalSignature(dsCollection);


        // Specify XOR encryption type.
        wb2.SetEncryptionOptions(EncryptionType.XOR, 40);

        // Specify Strong Encryption type (RC4,Microsoft Strong Cryptographic Provider).
        wb2.SetEncryptionOptions(EncryptionType.StrongCryptographicProvider, 128);

        // Password protect the file.
        wb2.Settings.Password = "1234";

        //Save the workbook and dispose it.            
        MemoryStream pdfStream = new MemoryStream();
        wb2.Save(pdfStream, saveOptions);
                    
        

        wb2.Dispose();

       curResponse.ContentType = "application/pdf";
       curResponse.AppendHeader("content-disposition", "attachment;filename=MyExport.pdf");                                   
                               pdfStream.WriteTo(curResponse.OutputStream);

    }

C#.zip (9.1 MB)

attached a sample project for converting pdf stream to PDF file. Please have a look at the CustomExportPdf.aspx.cs for the stream conversion.

we would like to pass this pdf stream to Aspose.pdf to digital sign and password protection.

@nchada,
As you are able to create the PDF file now. You can sign and password protect it with Aspose.PDF API. See the document with example code for your reference:

Let us know your feedback.

As I said earlier we have to sign pdf stream and post into response Not the physical file.

I sent you a sample project , please provide the digital sign and password protection steps.

@nchada

Steps and instructions have already been shared with you which are present in the documentation article(s). Regarding, sending PDF file to browser for download, please check following article that explains the steps and contains a working code example.

In case you face any issue, please feel free to let us know.

Given code example is not working for our requirement.

requirement:
public static void AsposePdf(MemoryStream stream)
{
Aspose.Pdf.Document doc = new Aspose.Pdf.Document();
doc.Save(stream);
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.Charset = “UTF-8”;
Response.AddHeader(“content-length”, stream.Length.ToString());
Response.AddHeader(“content-disposition”, String.Format(“attachment;filename=TestDocument.pdf”, “FileName”));
Response.ContentType = “application/pdf”;
Response.BinaryWrite(stream.ToArray());
Response.Flush();
Response.End();
}

the following function successfully generating and signing the pdf from memorystream, but pdf is not protecting with the password.

can you help on this?

public MemoryStream AsposePDF(MemoryStream pdfStream)
{
Aspose.Pdf.Document exportDoc = new Aspose.Pdf.Document(pdfStream);

        PdfFileSecurity fileSecurity = new PdfFileSecurity();
        fileSecurity.BindPdf(exportDoc);
        fileSecurity.EncryptFile("user", "owner", DocumentPrivilege.Print, KeySize.x256, Algorithm.AES);

        MemoryStream stream = new MemoryStream();

        using (PdfFileSignature signature = new PdfFileSignature(exportDoc))
        {
            PKCS7 pkcs = new PKCS7(HttpContext.Current.Server.MapPath("~") + "\\test-cert-EA.pfx", "2020");// Use PKCS7/PKCS7Detached objects
            DocMDPSignature docMdpSignature = new DocMDPSignature(pkcs, DocMDPAccessPermissions.FillingInForms);
            System.Drawing.Rectangle rect = new System.Drawing.Rectangle(100, 100, 200, 100);
            // Set signature appearance
            signature.SignatureAppearance = HttpContext.Current.Server.MapPath("~") + "\\images\\Logo.png";
            // Create any of the three signature types
            signature.Certify(1, "Signature Reason", "Contact", "Location", true, rect, docMdpSignature);
            // Save output PDF file
            signature.Save(stream);
        }

        // Close the stream object
        pdfStream.Close();

        return stream;          
    }

trying to do sign and encrypt a document using the current version of Aspose.Pdf for .NET

is this possible?

@nchada

Please save document into memory stream after protecting it with password and use same memory stream to reload document for signing purposes as following:

fileSecurity.EncryptFile("user", "owner", DocumentPrivilege.Print, KeySize.x256, Algorithm.AES);
MemoryStream stream = new MemoryStream();
fileSecurity.Save(stream);
stream.Seek(0, SeekOrigin.Begin);
using (PdfFileSignature signature = new PdfFileSignature(stream))
{
 // signing the document
}

Furthermore, would you please share what type of issue you are facing while using the code snippet. Please note that this code downloads the PDF file from Response and if you need send the file, you can use standard Post method of C# in order to achieve that.

image.png (151.4 KB)
still getting an error. PFA.

Error: System.ApplicationException: ‘Pdf document has not been provided yet or it was closed after changing document security properties.’

public MemoryStream AsposePDF(MemoryStream pdfStream)
{
Aspose.Pdf.Document exportDoc = new Aspose.Pdf.Document(pdfStream);

        PdfFileSecurity fileSecurity = new PdfFileSecurity();
        fileSecurity.EncryptFile("user", "owner", DocumentPrivilege.Print, KeySize.x256, Algorithm.AES);
        MemoryStream stream = new MemoryStream();
        fileSecurity.Save(stream);
        stream.Seek(0, SeekOrigin.Begin);

        using (PdfFileSignature signature = new PdfFileSignature(exportDoc))
        {
            PKCS7 pkcs = new PKCS7(HttpContext.Current.Server.MapPath("~") + "\\test-cert-EA.pfx", "2020");// Use PKCS7/PKCS7Detached objects
            DocMDPSignature docMdpSignature = new DocMDPSignature(pkcs, DocMDPAccessPermissions.NoChanges);
            System.Drawing.Rectangle rect = new System.Drawing.Rectangle(100, 100, 200, 100);
            // Set signature appearance
            signature.SignatureAppearance = HttpContext.Current.Server.MapPath("~") + "\\images\\Logo.png";
            // Create any of the three signature types
            signature.Certify(1, "Signature Reason", "Contact", "Location", true, rect, docMdpSignature);
            // Save output PDF file
            signature.Save(stream);
        }
     
        // Close the stream object
        pdfStream.Close();

        return stream;          
    }

@nchada

Please provide document to fileSecurity instance as following:

fileSecurity.BindPdf(exportDoc);

And then change your using statement as follows:

using (PdfFileSignature signature = new PdfFileSignature(stream))
{
 // signing the document
}

image.png (8.7 KB)

now error while opening pdf. PFA.

public MemoryStream AsposePDF(MemoryStream pdfStream)
{
Aspose.Pdf.Document exportDoc = new Aspose.Pdf.Document(pdfStream);

        PdfFileSecurity fileSecurity = new PdfFileSecurity();
        fileSecurity.BindPdf(exportDoc);
        fileSecurity.EncryptFile("user", "owner", DocumentPrivilege.Print, KeySize.x256, Algorithm.AES);
        MemoryStream stream = new MemoryStream();
        fileSecurity.Save(stream);
        stream.Seek(0, SeekOrigin.Begin);

        using (PdfFileSignature signature = new PdfFileSignature(exportDoc))
        {
            PKCS7 pkcs = new PKCS7(HttpContext.Current.Server.MapPath("~") + "\\test-cert-EA.pfx", "2020");// Use PKCS7/PKCS7Detached objects
            DocMDPSignature docMdpSignature = new DocMDPSignature(pkcs, DocMDPAccessPermissions.NoChanges);
            System.Drawing.Rectangle rect = new System.Drawing.Rectangle(100, 100, 200, 100);
            // Set signature appearance
            signature.SignatureAppearance = HttpContext.Current.Server.MapPath("~") + "\\images\\Logo.png";
            // Create any of the three signature types
            signature.Certify(1, "Signature Reason", "Contact", "Location", true, rect, docMdpSignature);
            // Save output PDF file
            signature.Save(stream);
        }
     
        // Close the stream object
        pdfStream.Close();

        return stream;          
    }

@nchada

Please check following complete code snippet that we have used in our environment to secure and sign the PDF.

Aspose.Pdf.Document exportDoc = new Aspose.Pdf.Document(dataDir + "demograph.pdf");

Facades.PdfFileSecurity fileSecurity = new Facades.PdfFileSecurity();
fileSecurity.BindPdf(exportDoc);
fileSecurity.EncryptFile("user", "owner", Facades.DocumentPrivilege.Print, Facades.KeySize.x256, Facades.Algorithm.AES);
MemoryStream stream = new MemoryStream();
fileSecurity.Save(stream);
stream.Seek(0, SeekOrigin.Begin);
exportDoc = new Document(stream, "owner");
using (Facades.PdfFileSignature signature = new Facades.PdfFileSignature(exportDoc))
{
  PKCS7 pkcs = new PKCS7(dataDir + "mykey2.pfx", "aa");
  DocMDPSignature docMdpSignature = new DocMDPSignature(pkcs, DocMDPAccessPermissions.NoChanges);
  System.Drawing.Rectangle rect = new System.Drawing.Rectangle(100, 100, 200, 100);
  // Set signature appearance
  signature.SignatureAppearance = dataDir + "aspose.png";
  // Create any of the three signature types
  signature.Certify(1, "Signature Reason", "Contact", "Location", true, rect, docMdpSignature);
  // Save output PDF file
  signature.Save(dataDir + "output.pdf");
}

We changed file names as we used our sample signature and image files. You may please change file names and modify above code as per your requirements. In case you still face any issue, please let us know.