Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge memorystreams to one iText document

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?

like image 781
Johan Avatar asked Dec 05 '11 12:12

Johan


1 Answers

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;
        }
    }
}
like image 179
Chris Haas Avatar answered Sep 20 '22 16:09

Chris Haas