Concatenation of PDF files with Facades.PdfFileEditor() fails

Hello Aspose chaps,


Thanks for this excellent set of libraries - generally worth the $7.5K price!

I am having one problem however.

My aim is to convert an Outlook msg email file with attachments to a single PDF document. I want to convert the attachments to PDF and append them to the PDF version of the email.

I do NOT want to write to the file system - in memory only.

I get a 0kb corrupted file as the result. Aspose throws exception: [Aspose.Pdf.Exceptions.InvalidPdfFileFormatException] = {“Incorect file format”}

In my test case, the attachments convert individually just fine - so that is not the problem.

The email by itself also converts just fine - so that is also no the problem.

Is there a problem with my code below? Or is there a bug?

Aspose versions:
Aspose.Email: 2.6
Aspose.Pdf:7.7
Aspose.Words: 13.1

Here is my code setting the licence. I set the licence in a static method in a referenced assembly.

public static void SetAll()
{

using (var stream = new MemoryStream(Properties.Resources.Aspose_Total))
{
var words = new Aspose.Words.License();
words.SetLicense(stream);
stream.Position = 0;
var pdf = new Aspose.Pdf.License();
pdf.SetLicense(stream);
stream.Position = 0;
var email = new Aspose.Email.License();
email.SetLicense(stream);
}

}

And here is my code doing the concatenation (method on an email class):

public void SaveAsPdf(Stream targetStream)
{
//Email proper
var streamForEmail = new MemoryStream();
_mailMessage.Save(streamForEmail,MailMessageSaveType.MHtmlFromat);
streamForEmail.Position = 0;
var options = new Aspose.Words.LoadOptions() {LoadFormat = LoadFormat.Mhtml};
var doc = new Aspose.Words.Document(streamForEmail, options);

var streamForConvertedEmail = new MemoryStream();
doc.Save(streamForConvertedEmail, SaveFormat.Pdf);
streamForConvertedEmail.Position = 0;

Queue streamsToConcatenate = new Queue();
streamsToConcatenate.Enqueue(streamForConvertedEmail);

//attachments
foreach (var attachment in _attachments)
{
using (var attachmentstream = new MemoryStream())
{
attachment.SaveAsPdf(attachmentstream);
streamsToConcatenate.Enqueue(attachmentstream);
attachmentstream.Position = 0;
}
}

// Now the concatenation
var pdfFileEditor = new Aspose.Pdf.Facades.PdfFileEditor();
bool concatenatedSuccessfullyWithSideEffect = true;
var buffer = new MemoryStream();
try
{
concatenatedSuccessfullyWithSideEffect = pdfFileEditor.Concatenate(streamsToConcatenate.ToArray(),
buffer);

var completeDoc = new Aspose.Pdf.Document(buffer);
completeDoc.Save(targetStream);
}


catch (Exception e)
{
if (!concatenatedSuccessfullyWithSideEffect)
{
throw new FailedToCreateEmailAndAttachmentsCombinedPdfException(
String.Format("’{0}’ with attachments: {1}", _subject,
String.Join(",", _attachments.Select(a => a.ShortFileName))), e);
}

throw e;
}
}




Hi Nick,


Thanks for using our products.

As per my understanding, the problem is occurring when concatenating PDF files into a single resultant document, because the individual email message is properly being converted to PDF file. Can you please share the PDF files which you are trying to concatenate. We are sorry for this inconvenience.

Hi,

I have attached my test .msg file.

It contains three attachments inside the file: one .doc, one .docx, and one .pdf.

If you open the .msg file in Outlook, you will see them.

My objective is to make FIVE PDF documents from this file:
1. the email with addressee, sender, subject, body text etc
2. the first attachment
3. the second attachment
4. for the third attachment
5. single PDF which contains 1 - 4 concatenated together in order.

I have got 1 - 4 working - no problems there. I can open up the resulting PDF files and view them.

My problem is with 5. The code I posted in my original post is for 5.

Can you make it work?

Thanks,
Nick

Hi Nick,


Thanks for sharing the resource files.

I have tested the scenario where I have first converted individual input file to PDF format and then have tried concatenating all the documents into a single resultant PDF and I am unable to notice any issue. I have used the following simple code snippet to concatenate the PDF files.

For your reference, I have also attached the resultant PDF file generated with Aspose.Pdf for .NET 7.7.0. Please take a look.

[C#]

//create PdfFileEditor object<o:p></o:p>

PdfFileEditor pdfEditor = new PdfFileEditor();

//output stream

FileStream outputStream = new FileStream(@"C:\pdftest\Msg+with+three+attachments\Concatrenated_fil.pdf", FileMode.Create);

//array of streams

FileStream[] inputStreams = new FileStream[4];

inputStreams[0] = new FileStream(@"C:\pdftest\Msg+with+three+attachments\pn75 p9-11.pdf", FileMode.Open);

inputStreams[1] = new FileStream(@"C:\pdftest\Msg+with+three+attachments\Test with three attachments.pdf", FileMode.Open);

inputStreams[2] = new FileStream(@"C:\pdftest\Msg+with+three+attachments\Word Binary doc.pdf", FileMode.Open);

inputStreams[3] = new FileStream(@"C:\pdftest\Msg+with+three+attachments\Word OpenXml doc.pdf", FileMode.Open);

//concatenate file

pdfEditor.Concatenate(inputStreams, outputStream);


Furthermore, I have observed that once the PDF files are concatenated, you are saving the output in buffer (MemoryStream object) and then instantiated a new Document object which ultimately saves the output in targetStream object. You may directly save the output in targetStream object. We are really sorry for this inconvenience.

In case the problem still persists, please share the sample application so that we can test the scenario at our end.

Thanks Nayyer,


Unfortunately I can’t write to the file system in my case though.

I have the source files as byte arrays stored in the database.

Can you get the code to work if you convert the files I sent you to byte arrays first (like with File.ReadAllBytes(…))?

Nick

Hi Nick,


I am working over this query and will get back to you soon. We are sorry for this delay and inconvenience.

Hi Nick,


I have again tested the scenario using following code snippet where I have tried reading all the PDF files using File.ReadAllBytes(…) method and final output is saved in FileStream object. I have PDF files already generated so I am loading them from file system however as per your requirement, you may try using Aspose.Words and Aspose.Email to convert these documents in PDF format and save individual output in MemoryStream object and pass the same objects are an argument to Concatenate method of PdfFileEditor class. In case the problem still persists, please feel free to contact.

[C#]

MemoryStream[] inputStreams = new MemoryStream[4];<o:p></o:p>

inputStreams[0] = new System.IO.MemoryStream(File.ReadAllBytes(@"C:\pdftest\pn75 p9-11.pdf"));

inputStreams[1] = new System.IO.MemoryStream(File.ReadAllBytes(@"C:\pdftest\Test with three attachments.pdf"));

inputStreams[2] = new System.IO.MemoryStream(File.ReadAllBytes(@"C:\pdftest\Word Binary doc.pdf"));

inputStreams[3] = new System.IO.MemoryStream(File.ReadAllBytes(@"C:\pdftest\Word OpenXml doc.pdf"));

//create PdfFileEditor object

PdfFileEditor pdfEditor = new PdfFileEditor();

//output stream

FileStream outputStream = new FileStream(@"C:\pdftest\Concatrenated_fil.pdf", FileMode.Create);

//concatenate file

pdfEditor.Concatenate(inputStreams, outputStream);

// close stream object

outputStream.Close();

Thanks for this.


I haven’t had a chance to test it yet. Will let you know how it goes.