I have four MemoryStreams of data that I want to merge and then open the pdfDocument, without creating a single file.
It's possible to write them down to files and then merge them but that would be bad practice and that can also cause a few issues so I want to avoid that.
However, I can not find a way to merge the MemoryStreams with iText5 for .NET.
Right now, this is how I do it with files:
private static void ConcatenateDocuments()
{
var stream = new MemoryStream();
var readerFrontPage = new PdfReader(Folder + FrontPageName);
var readerDocA = new PdfReader(Folder + docA);
var readerDocB = new PdfReader(Folder + DocB);
var readerAppendix = new PdfReader(Folder + Appendix);
var pdfCopyFields = new PdfCopyFields(stream);
pdfCopyFields.AddDocument(readerFrontPage);
pdfCopyFields.AddDocument(readerDocA );
pdfCopyFields.AddDocument(readerDocB);
pdfCopyFields.AddDocument(readerAppendix);
pdfCopyFields.Close();
SavePdf(stream, FilenameReport);
}
Since I need to remove the use of files, I keep the MemoryStream's as the different parts are built from different resources. So I have references to these memorystreams.
How can this be done?
The error PDF header signature not found can be fixed in this case by setting the stream's Position back to 0. Since you're not getting the error Cannot access a closed Stream I'm assuming that you are already correctly setting the PdfWriter's CloseStream to false.
Below is a full working C# 2010 WinForm app targeting iTextSharp 5.1.1.0 that creates three PDFs in MemoryStreams and combines them. Since I don't have a web server handy I'm writing them to disk.
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Create three MemoryStreams
MemoryStream[] streams = { CreateDoc("Page 1"), CreateDoc("Page 2"), CreateDoc("Page 3") };
//I don't have a web server handy so I'm going to write my final MemoryStream to a byte array and then to disk
byte[] bytes;
//Create our final combined MemoryStream
using (MemoryStream finalStream = new MemoryStream())
{
//Create our copy object
PdfCopyFields copy = new PdfCopyFields(finalStream);
//Loop through each MemoryStream
foreach (MemoryStream ms in streams)
{
//Reset the position back to zero
ms.Position = 0;
//Add it to the copy object
copy.AddDocument(new PdfReader(ms));
//Clean up
ms.Dispose();
}
//Close the copy object
copy.Close();
//Get the raw bytes to save to disk
bytes = finalStream.ToArray();
}
//Write out the file to the desktop
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Combined.pdf");
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
fs.Write(bytes, 0, bytes.Length);
}
this.Close();
}
/// <summary>
/// Helper method to create temporary documents
/// </summary>
private MemoryStream CreateDoc(string name)
{
MemoryStream ms = new MemoryStream();
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(doc, ms))
{
writer.CloseStream = false;
doc.Open();
doc.Add(new Paragraph(name));
doc.Close();
}
}
return ms;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With