Tuesday, 9 December 2014

c# combine multiple pdf into one

 
*Note : Take reference of itextSharp API DLL reference to work with below application

We were facing the problem of creating the multiple PDF file and send it to clients. So they have to take the print of PDF one by one so, created the application to combine multiple PDF files into one PDF.


clip_image001




If you will see the select it will open the window to open the select the multiple files in the screen;
We have to take the reference of OpenFileDialogBox

You can see the code below; by it you can open only the PDF file. From OpenFileDialogBox
Property this.openFileDialog1.Filter to open only the PDF Files.
  private void btnMerge_Click(object sender, EventArgs e)
        {
            //if (txtFilePath.Text.Trim() != "")
            //{
            //    lstFilenames.Items.Add(txtFilePath.Text);
            //    txtFilePath.Text = "";
            //}
            if (backgroundWorker1.IsBusy != true)
            {
                this.openFileDialog1.Filter = "Pdf Files|*.pdf";
                // Allow the user to select multiple images.
                this.openFileDialog1.Multiselect = true;
                this.openFileDialog1.Title = "Select PDF";
                openFileDialog1.ShowDialog();

                List<string> strCollection = new List<string>();

                foreach (String file in openFileDialog1.FileNames)
                {
                    strCollection.Add(file);
                }

              strCollection.Sort();

                foreach (String file in strCollection)
                {
                    if (file.Trim() != string.Empty)
                    {
                        lstFilenames.Items.Add(file);
                    }
                }
            }
         

        }

Before starting the process we will check that is there any process is already combine multiple pdfs into one into. If yes than it won’t perform any operation otherwise. It will open the Mutiselet Open Dialog Box.

You need to select the mutiselect property by Multiselect of openDialogBox this.openFileDialog1.Multiselect = true;

Then we have to keep the entire file name into list. So from there we will read files openFileDialog1

as
openFileDialog1.FileNames which use to see all the list of files selected in Open Files.


clip_image002

Now to keep all the file name into list box.

clip_image003

Once you get the entire file click on Merge All file (It will merge multiple PDF file).
It will first prompt to get the Merge PDF file name.
Here I Used to SaveDialogBox;
saveFileDialog1 you don’t need to give any extension of file name automatically it will save into the .PDF format. The Title of the Save Dialog box will be appear as Save PDF File.


  SaveFileDialog saveFileDialog1 = new SaveFileDialog();
  saveFileDialog1.Title = "Save PDF File";

  saveFileDialog1.Filter = "Pdf Files|*.pdf";


Full code for merge all files;


private void button1_Click_1(object sender, EventArgs e)
        {
            if (backgroundWorker1.IsBusy != true)
            {
                saveFilePath = string.Empty;

                if (lstFilenames.Items.Count == 0)
                {
                    MessageBox.Show("No file for Merge");
                    return;
                }


                SaveFileDialog saveFileDialog1 = new SaveFileDialog();
                //   saveFileDialog1.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif";
                saveFileDialog1.Title = "Save PDF File";
                saveFileDialog1.Filter = "Pdf Files|*.pdf";


                saveFileDialog1.ShowDialog();
                saveFilePath = saveFileDialog1.FileName;
                if (saveFilePath != "")
                {



                    // create a new instance of the alert form
                    alert = new AlertForm();
                    // event handler for the Cancel button in AlertForm
                    alert.Canceled += new EventHandler<EventArgs>(buttonCancel_Click);
                    alert.Show();
                    // Start the asynchronous operation.
                    backgroundWorker1.RunWorkerAsync();


                }
                else
                {
                    MessageBox.Show("No selected File Find");
                }
            }

        }


It will look like below asking for Merging PDF file name into one.
clip_image004


Once get the Save Dialog box automatically asynchronous process for the background will be started.
Now it is the heart of the application and it will be like below code; By this code only you can mearge the two PDF into single one;

     // This event handler is where the time-consuming work is done.
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
              //  break;
            }
            else
            {
                // Perform a time consuming operation and report progress.
               
                PdfReader reader = null;
                Document sourceDocument = null;
                PdfCopy pdfCopyProvider = null;
                PdfImportedPage importedPage;

                List<string> lst = new List<string>();
                foreach (var item in lstFilenames.Items)
                {
                    if (item.ToString() != string.Empty)
                    {
                        lst.Add(item.ToString());
                    }
                }

                string[] lstFiles = lst.ToArray();

                sourceDocument = new Document();
                pdfCopyProvider = new PdfCopy(sourceDocument, new System.IO.FileStream(saveFilePath, System.IO.FileMode.Create)); //outputPdfPath

                //Open the output file
                sourceDocument.Open();

                //try
                //{

                    //Loop through the files list
                    for (int f = 0; f < lstFiles.Length; f++)
                    {
                       
                        int pages = get_pageCcount(lstFiles[f]);

                        reader = new PdfReader(lstFiles[f]);
                        //Add pages of current file
                        for (int i = 1; i <= pages; i++)
                        {
                            importedPage = pdfCopyProvider.GetImportedPage(reader, i);
                            pdfCopyProvider.AddPage(importedPage);
                        }

                        reader.Close();


                        (sender as BackgroundWorker).ReportProgress((int)(100 / lstFiles.Length) * f, null);

                        if (f == lstFiles.Length)
                        {
                            (sender as BackgroundWorker).ReportProgress(100, null);
                        }
                    }
                    //At the end save the output file
                    sourceDocument.Close();
                  
                //}
                //catch (Exception ex)
                //{
                //    MessageBox.Show(ex.Message);
                //}
            }
        }



Yellow marked Code is the important one which will just merge two PDF files.
clip_image005
Code that will start the background process and maintain the status of the process.
You need to take the reference of background Thread control as backgroundWorker1.
Need to check the events of ProgressChanged


private void backgroundWorker1_ProgressChanged
(object sender, ProgressChangedEventArgs e)
        {
            // Show the progress in main form (GUI)
          //  labelResult.Text = (e.ProgressPercentage.ToString() + "%");
            // Pass the progress to AlertForm label and progressbar
            alert.Message = "In progress, please wait... " + e.ProgressPercentage.ToString() + "%";
            alert.ProgressValue = e.ProgressPercentage;
        }


/// Need to look into if the BackGroundWorker process complete the task RunWorkerCompleted

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                DialogResult result = MessageBox.Show("Process has cancelled", "Cancelled", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            else if (e.Error != null)
            {
                DialogResult result = MessageBox.Show("Error: " + e.Error.Message,"Error File Creation", MessageBoxButtons.OK, MessageBoxIcon.Error );

             //   labelResult.Text = "Error: " + e.Error.Message;
            }
            else
            {
                alert.ProgressValue = 100;
                alert.Message = "In progress, please wait... 100%";
                DialogResult result = MessageBox.Show("File merge Successfully with Path " + saveFilePath + "\nWould you like to open?", "Success", MessageBoxButtons.YesNo,MessageBoxIcon.Information);
                if (result == DialogResult.Yes)
                {
                    Process.Start(saveFilePath);
                }
            }
            // Close the AlertForm
            alert.Close();

        }


Create a form which will use to show only the progress of the task; It should have only progress bar and the lable



public partial class AlertForm : Form
    {

        #region PROPERTIES

        public string Message
        {
            set { labelMessage.Text = value; }
        }

        public int ProgressValue
        {
            set { progressBar1.Value = value; }
        }

        #endregion

        #region METHODS

        public AlertForm()
        {
            InitializeComponent();
        }

        #endregion

        #region EVENTS

        public event EventHandler<EventArgs> Canceled;

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            // Create a copy of the event to work with
            EventHandler<EventArgs> ea = Canceled;
            /* If there are no subscribers, eh will be null so we need to check
             * to avoid a NullReferenceException. */
            if (ea != null)
                ea(this, e);
        }

        #endregion


    }


When user will click on cancel button it will stop the process.
Once process of merging the PDF will complete it will show the confirmation message to open the file
clip_image007
When you click on yes it will open the file;
Code for opening the Merged PDF file is below:


DialogResult result = MessageBox.Show("File merge Successfully with Path " + saveFilePath + "\nWould you like to open?", "Success", MessageBoxButtons.YesNo,MessageBoxIcon.Information);
                if (result == DialogResult.Yes)
                {
                    Process.Start(saveFilePath);

                }


It will be Under backgroundWorker1_RunWorkerCompleted; that I demonstrated before.
Just showing the form design how it will look; which help to design the application.
clip_image008


No comments:

Post a Comment