combining or merging pdfs from several memorystreams

Original Post: http://www.dreamincode.net/forums/topic/349941-combining-or-merging-pdfs-from-several-memorystreams/

Question:

I am new to c# and itextsharp and have a problem merging 2 or more pdfs using itextsharp. I have 2 methods that fill a pdf template each and saves them to a memorystream and a downloadAsPDF methods to return the combined pdfs to the broswer. the downloadAsPDF works when i add only one of the memorystream but when i add both MemoryStreams to the list I receive the message…If this message is not eventually replaced by the proper contents of the document, your PDF viewer may not be able to display this type of document. Any help would be much appreciated. Thanks

public byte[] fillTemplateA()
    {
                   String NfoodAllergyTemplate = "~/pdfTemplateA.pdf";


        //setting readers and stamper and memorystream
        PdfReader ReadPdf = new PdfReader(NfoodAllergyTemplate);
        MemoryStream msNfoodAllergyTemplate = new MemoryStream();
        PdfStamper StampPdf = new PdfStamper(ReadPdf, msNfoodAllergyTemplate,'\0',true);
        AcroFields NFoodAlF = StampPdf.AcroFields;

        NFoodAlF.SetField("stdFullNameNFAAP", testObject);

        StampPdf.FormFlattening = false;
        StampPdf.Close();
        ReadPdf.Close();


        byte[] ms1 = msNfoodAllergyTemplate.ToArray();
         return ms1;
              }    

Here is my second methos that fills the 2nd pdf
public byte[] fillTemplateB()
    {
                   String NfoodAllergyTemplate = "~/pdfTemplateB.pdf";


        //setting readers and stamper and memorystream
        PdfReader ReadPdf = new PdfReader(NfoodAllergyTemplate);
        MemoryStream msNfoodAllergyTemplate = new MemoryStream();
        PdfStamper StampPdf = new PdfStamper(ReadPdf, msNfoodAllergyTemplate,'\0',true);
        AcroFields NFoodAlF = StampPdf.AcroFields;

        NFoodAlF.SetField("stdFullNameNFAAP", testObject);

        StampPdf.FormFlattening = false;
        StampPdf.Close();
        ReadPdf.Close();


        byte[] ms2 = msNfoodAllergyTemplate.ToArray();
         return ms2;
              }

merge pdf method
public MemoryStream MergePDFs(List<byte[]> pdfFiles) 
{
       if(pdfFiles.Count >1) {
        PdfReader finalPdf;
        Document pdfContainer;
        PdfWriter pdfCopy;
        MemoryStream msFinalPdf = new MemoryStream();

        finalPdf = new PdfReader(pdfFiles[0]);
        pdfContainer = new Document();
        pdfCopy = new PdfSmartCopy(pdfContainer, msFinalPdf);

        pdfContainer.Open();

        for (int k = 0; k < pdfFiles.Count; k++)
        {
            finalPdf = new PdfReader(pdfFiles[k]);
            for (int i = 1; i < finalPdf.NumberOfPages + 1; i++)
            {
                ((PdfSmartCopy)pdfCopy).AddPage(pdfCopy.GetImportedPage(finalPdf, i));
            }
            pdfCopy.FreeReader(finalPdf);

        }
        finalPdf.Close();
        pdfCopy.Close();
        pdfContainer.Close();

        return msFinalPdf;}
    else if(pdfFiles.Count==1)
{
    return new MemoryStream(pdfFiles[0]);
}
  return null;
                       }

in this last method I merge the pdfs in memorystream from FillTemplate A and B
public void finalPdf()
    {


       //List to collect all pdfs in memorystream that have been assinged to a byte array

       System.Collections.Generic.List<byte[]> collectAllForms = new List<byte[]>();
      //when i add only one of the line below it works...having both give error message...Please wait...
       collectAllForms.Add(fillTemplateA());
       collectAllForms.Add(fillTemplateB());

       //Call the downloadAsPDF method 
        DownloadAsPDF(MergePDFs(collectAllForms), "QVSD_Packet");

    }

Here is the downloadAsPDF method
public void DownloadAsPDF(MemoryStream msFinal,String theFileName)

   {
      theFileName = "attachment; filename =" + theFileName + ".pdf";

       HttpContext.Current.Response.Clear();
       HttpContext.Current.Response.ClearContent();
       HttpContext.Current.Response.ClearHeaders();
       HttpContext.Current.Response.AddHeader("Content-Disposition", theFileName);
       HttpContext.Current.Response.ContentType = "application/pdf";
       HttpContext.Current.Response.BinaryWrite(msFinal.ToArray());
       HttpContext.Current.Response.OutputStream.Flush();
       HttpContext.Current.Response.OutputStream.Close();
       HttpContext.Current.Response.End();
       msFinal.Close();
   }

Solution: your question help me a lot so the solution is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.Reporting.WebForms;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Drawing;
using iTextSharp.text.pdf;
using System.IO;
using iTextSharp.text;

namespace WZPDCL
{
    public partial class MasteringApplication : System.Web.UI.Page
    {
        System.Collections.Generic.List<byte[]> collectAllForms = new List<byte[]>();

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnGenerate_Click(object sender, EventArgs e)
        {
            //List<byte> list = new List<byte>();
            //byte[] all = new byte[]();
            try
            {
                ReportViewer ApplicationReportViewer = new ReportViewer();

                String APP_SN = "";

                string mimeType = "";
                string extension = "";

                DataTable dt = ClsCommon.GetAdhocResult("SELECT DISTINCT APP_SN FROM tblAapplicantGenInfo").Tables[0];

                foreach (DataRow dr in dt.Rows)
                {
                    APP_SN = dr["APP_SN"].ToString();

                    ApplicationReportViewer.Reset();
                    ApplicationReportViewer.LocalReport.Dispose();

                    DataSet ds1 = new DataSet();
                    using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["wzpdcl"].ConnectionString))
                    {
                        SqlCommand cmd1 = new SqlCommand("sp_BasicInfo", con);
                        cmd1.Parameters.AddWithValue("@APP_SN", APP_SN);
                        cmd1.CommandType = CommandType.StoredProcedure;
                        SqlDataAdapter da1 = new SqlDataAdapter();
                        da1.SelectCommand = cmd1;
                        da1.Fill(ds1);
                    }

                    DataTable dt1 = new DataTable();
                    dt1 = ds1.Tables[0];

                    // adding new column to datatable and assign value
                    System.Data.DataColumn newColumn = new System.Data.DataColumn("barCode", typeof(System.Byte[]));
                    newColumn.DefaultValue = ImageToByte(CreateBarcode(APP_SN));
                    dt1.Columns.Add(newColumn);

                    DataSet ds2 = new DataSet();
                    using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["wzpdcl"].ConnectionString))
                    {
                        SqlCommand cmd2 = new SqlCommand("sp_Education", con);
                        cmd2.Parameters.AddWithValue("@APP_SN", APP_SN);
                        cmd2.CommandType = CommandType.StoredProcedure;
                        SqlDataAdapter da2 = new SqlDataAdapter();
                        da2.SelectCommand = cmd2;
                        da2.Fill(ds2);
                    }

                    DataTable dt2 = new DataTable();
                    dt2 = ds2.Tables[0];

                    DataSet ds3 = new DataSet();
                    using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["wzpdcl"].ConnectionString))
                    {
                        SqlCommand cmd3 = new SqlCommand("sp_Experience", con);
                        cmd3.Parameters.AddWithValue("@APP_SN", APP_SN);
                        cmd3.CommandType = CommandType.StoredProcedure;
                        SqlDataAdapter da3 = new SqlDataAdapter();
                        da3.SelectCommand = cmd3;
                        da3.Fill(ds3);
                    }

                    DataTable dt3 = new DataTable();
                    dt3 = ds3.Tables[0];

                    DataSet ds4 = new DataSet();
                    using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["wzpdcl"].ConnectionString))
                    {
                        SqlCommand cmd4 = new SqlCommand("sp_Training", con);
                        cmd4.Parameters.AddWithValue("@APP_SN", APP_SN);
                        cmd4.CommandType = CommandType.StoredProcedure;
                        SqlDataAdapter da4 = new SqlDataAdapter();
                        da4.SelectCommand = cmd4;
                        da4.Fill(ds4);
                    }

                    DataTable dt4 = new DataTable();
                    dt4 = ds4.Tables[0];

                    DataSet ds5 = new DataSet();
                    using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["wzpdcl"].ConnectionString))
                    {
                        SqlCommand cmd5 = new SqlCommand("sp_Payment", con);
                        cmd5.Parameters.AddWithValue("@APP_SN", APP_SN);
                        cmd5.CommandType = CommandType.StoredProcedure;
                        SqlDataAdapter da5 = new SqlDataAdapter();
                        da5.SelectCommand = cmd5;
                        da5.Fill(ds5);
                    }

                    DataTable dt5 = new DataTable();
                    dt5 = ds5.Tables[0];

                    ReportDataSource rds1 = new ReportDataSource("dsApplication1", dt1);
                    ReportDataSource rds2 = new ReportDataSource("dsEducation", dt2);
                    ReportDataSource rds3 = new ReportDataSource("dsExperience", dt3);
                    ReportDataSource rds4 = new ReportDataSource("dsTraining", dt4);
                    ReportDataSource rds5 = new ReportDataSource("dsPayment", dt5);

                    ApplicationReportViewer.ProcessingMode = ProcessingMode.Local;
                    ApplicationReportViewer.LocalReport.ReportPath = Server.MapPath("Application.rdlc");

                    ApplicationReportViewer.LocalReport.DataSources.Add(rds1);
                    ApplicationReportViewer.LocalReport.DataSources.Add(rds2);
                    ApplicationReportViewer.LocalReport.DataSources.Add(rds3);
                    ApplicationReportViewer.LocalReport.DataSources.Add(rds4);
                    ApplicationReportViewer.LocalReport.DataSources.Add(rds5);

                    ApplicationReportViewer.LocalReport.Refresh();

                    Warning[] warnings;
                    string[] streamIds;
                    mimeType = string.Empty;
                    string encoding = string.Empty;
                    extension = string.Empty;
                    byte[] bytes = ApplicationReportViewer.LocalReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamIds, out warnings);

                    collectAllForms.Add(bytes);
                }

                DownloadAsPDF(MergePDFs(collectAllForms), "AllApplicant");
            }
            catch (Exception ex) { }
        }

        public void DownloadAsPDF(MemoryStream msFinal, String theFileName)
        {
            theFileName = "attachment; filename =" + theFileName + ".pdf";

            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.ClearContent();
            HttpContext.Current.Response.ClearHeaders();
            HttpContext.Current.Response.AddHeader("Content-Disposition", theFileName);
            HttpContext.Current.Response.ContentType = "application/pdf";
            HttpContext.Current.Response.BinaryWrite(msFinal.ToArray());
            HttpContext.Current.Response.OutputStream.Flush();
            HttpContext.Current.Response.OutputStream.Close();
            HttpContext.Current.Response.End();
            msFinal.Close();
        }

        public MemoryStream MergePDFs(List<byte[]> pdfFiles)
        {
            if (pdfFiles.Count > 1)
            {
                PdfReader finalPdf;
                Document pdfContainer;
                PdfWriter pdfCopy;
                MemoryStream msFinalPdf = new MemoryStream();

                finalPdf = new PdfReader(pdfFiles[0]);
                pdfContainer = new Document();
                pdfCopy = new PdfSmartCopy(pdfContainer, msFinalPdf);

                pdfContainer.Open();

                for (int k = 0; k < pdfFiles.Count; k++)
                {
                    finalPdf = new PdfReader(pdfFiles[k]);
                    for (int i = 1; i < finalPdf.NumberOfPages + 1; i++)
                    {
                        ((PdfSmartCopy)pdfCopy).AddPage(pdfCopy.GetImportedPage(finalPdf, i));
                    }
                    pdfCopy.FreeReader(finalPdf);

                }
                finalPdf.Close();
                pdfCopy.Close();
                pdfContainer.Close();

                return msFinalPdf;
            }
            else if (pdfFiles.Count == 1)
            {
                return new MemoryStream(pdfFiles[0]);
            }
            return null;
        }


        private System.Drawing.Image CreateBarcode(string data)
        {
            // iTextShirp
            //Bitmap barCode = new Bitmap(1, 1);
            Barcode128 code128 = new Barcode128(); // barcode type 
            //BarcodeQRCode codeQR = new BarcodeQRCode(data, 400, 300,null);
            code128.Code = data;
            System.Drawing.Image barCode = code128.CreateDrawingImage(System.Drawing.Color.Black, System.Drawing.Color.White);
            //barCode.Save(Server.MapPath("~/barcode.gif"), System.Drawing.Imaging.ImageFormat.Gif); //save file            
            return barCode;
        }

        public static byte[] ImageToByte(System.Drawing.Image img)
        {
            ImageConverter converter = new ImageConverter();
            return (byte[])converter.ConvertTo(img, typeof(byte[]));
        }
    }
}
Advertisements

One thought on “combining or merging pdfs from several memorystreams

  1. This solution doesn’t work. Still the fillable form PDF is not coming in the merged PDF. Instad the “Please wait….” message is coming in single page.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s