Create multiple PDFs in memory from rendered byte arrays- then merge (updated)

Hi,


I would like to create a PDF in memory from the rendered byte array I get from the ReportExecutionService after running a report with parameters.

I would like to do this multiple times for several reports, then merge all of the results into one in-memory PDF file.

Is this possible?

Ok, I know this is possible. However, I’m having a problem with the length of the concatenated memory stream is not equal to the sum of the list of memory streams I pass in when I concatenate.

Any ideas? I’m using Aspose.Pdf version 10.7.0.0

Something like:

using System.Collections.Generic;
using System.Linq;
using System.Drawing.Printing;
using Aspose.Pdf;
using Aspose.Pdf.Facades;
using Aspose.Pdf.Generator;
using Microsoft.Reporting.WebForms.Internal.Soap.ReportingServices2005.Execution;
using PageSettings = System.Drawing.Printing.PageSettings;

public byte[] ExecuteReport(string reportPath, ParameterValue[] parameterValues, string format, string language)
{
var rs = new ReportExecutionService
{
Url = ReportServerUrl,
Credentials =
new System.Net.NetworkCredential(ReportServerUserName, ReportServerPassword, ReportServerDomain)
};
string encoding;
string mimeType;
string extension;
Warning[] warnings;
string[] streamIDs;
var execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
rs.LoadReport(reportPath, null);
rs.SetExecutionParameters(parameterValues, language);
return rs.Render(format, null, out extension, out encoding, out mimeType, out warnings, out streamIDs);
}

publicvoid ProcessPrintDocuments(string[] reports)
{
var parameterValues = new List()
{
new ParameterValue
{
Name = “LanguageId”,
Value = UserLanguageId.ToString()
},
new ParameterValue
{
Name = “CompanyId”,
Value = CompanyId.ToString()
},
new ParameterValue
{
Name = “UserId”,
Value = UserId.ToString()
}
};

// Step #1: Loop through all of the reports and create PDF from rendered byte arrays
// Maintain a list of memorystreams
var memoryStreamList = new List();
foreach(var reportPath in reports)
{
var memoryStream = new MemoryStream();
var renderedReportBytes = ExecuteReport(reportPath, parameterValues.ToArray(), “PDF”, “en-US”);
memoryStream.Write(renderedReportBytes, 0, renderedReportBytes.Length);

// Create PDF from bytes in memory stream
var pdf = new Pdf(memoryStream);
pdf.Close();

var numPages = pdf.PageCount;

memoryStreamList.Add(memoryStream);
}

// Step #2: Merge all memory streams in list…

// Merge all documents into large pdf
var pdfEditor = new PdfFileEditor();
var mergedMemoryStream = new MemoryStream();
pdfEditor.Concatenate(memoryStreamList.ToArray(), mergedMemoryStream);

//Problem
// The total length of all streams in memoryStreamList is 841,154.
// mergedMemoryStream.Length = 3,204
// mergedMemoryStream.Position = 0


// Step #3: Create merged PDF instance from the merged memory stream
var mergedPdf = new Pdf(mergedMemoryStream);
mergedPdf.Close();
mergedMemoryStream.Close();

// Step #3: Get the total number of pages in the merged PDF
var numMergedPages = mergedPdf.PageCount;

// Step #4: Merge one more report at the beginning and Print merged PDF
// Load the rendered cover report byte array into memory
var coverPageReportBytes = _reportHandler.ExecuteReport(CoverPageReportPath, parameterValues.ToArray(), “PDF”, “en-US”);
var coverPageMemoryStream = new MemoryStream();
coverPageMemoryStream.Write(coverPageReportBytes, 0, coverPageReportBytes.Length);
var coverPagePdf = new Pdf(coverPageMemoryStream);
coverPagePdf.Close();

// Add to list of streams
memoryStreamList.Insert(0, coverPageMemoryStream);

// Concatenate cover page with merged
var finalMemoryStream = new MemoryStream();
pdfEditor.Concatenate(memoryStreamList.ToArray(), finalMemoryStream);

// Send final to printer

foreach(var ms in memoryStreamList)
ms.Close();

finalMemoryStream.Close();


}

Hi Mark,


Thanks for using our API’s.

It appears that you are creating new PDF file instance using Aspose.Pdf.Generator.Pdf object and creating new instance by passing MemoryStream as argument. Furthermore, you are saving PDF instances to MemoryStream list and then using PdfFileEditor to concatenate PDF files. Please note that Aspose.Pdf.Generator.Pdf object is used to create PDF files from scratch and it might not work in situation when you are trying to load any existing file contents to this object. Therefore when checking the size of MergedStream, the size is different and resultant concatenated file page count is also different.

However we suggest you to please try using Aspose.Pdf.Document class (based on new Document Object Model) which can used to create new PDF file, as well as to manipulate any existing document. So as per your requirement, you can instantiate Aspose.Pdf.Document object by passing ReportExecutionService contents as argument and then generate a merged output with same instance. Please visit the following link for more information on


In case you still face any issue, please share the sample project, so that we can further look into this matter. We are sorry for this inconvenience.