Search code examples
c#exceloffice-interopexcel-interop

How do I merge multiple excel files to a single excel file


So I was trying to make an excel sheet aggregator. In my line of work we get people who send us a bunch of individual excel files that are all related each with only 1 sheet used.

I was following to some degree this previous post's ideas. But upon doing so, some of the excel sheets I copied were coming up blank. Only certain ones. I have no idea why some are blank and others are fine.

Here is the code I use to open and copy the excel files

         OpenFileDialog browse = new OpenFileDialog();
            browse.Multiselect = true;
            DialogResult result = browse.ShowDialog();

            if (result == DialogResult.OK)

                try //try to open it. If its a proper excel file
                {   
                    excel = new Excel.Application();
                    excel.Workbooks.Add("");
                    finalized = excel.Workbooks[1];
                    excel.SheetsInNewWorkbook = 1;
                    for(int i=0; i< browse.FileNames.Length; i++)
                    {
                        excel.Workbooks.Add(browse.FileNames[i]);
                    }
                    //skip the first workbook as it is the finalized one
                    //also note everything in excel starts at 1 and not 0
                    for(int i=2; i<excel.Workbooks.Count; i++)
                    {
                        int count = excel.Workbooks[i].Worksheets.Count;
                        excel.Workbooks[i].Activate();
                        for (int j = 1; j < count; j++)
                        {

                            Excel._Worksheet pastee = (Excel._Worksheet)excel.Workbooks[i].Worksheets[j];
                            Excel._Worksheet sheet = (Excel._Worksheet)finalized.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                            //Excel._Worksheet sheet = finalized.Sheets[1];
                            pastee.Copy(Before: sheet);


                        }//end of for j
                    }//end of for i
                }//end of try

Here is the code I use to save the excel file

            SaveFileDialog browse = new SaveFileDialog();
            browse.Title = "Save as Excel";
            browse.Filter = "Excel workbook | *.xlsx";
            DialogResult result = browse.ShowDialog();

            finalized.SaveAs(browse.FileName, Excel.XlFileFormat.xlWorkbookDefault);

            MessageBox.Show("Success", "Message");
            //unlock the file
            Global.releaseComObjects(finalized, excel);

Solution

  • In your inner loop you add a new worksheet to your 'finalized' workbook ('sheet') AND copy a worksheet before it for every source sheet. So every 'sheet' created by your Add command will be empty as in fact you create two sheets for each source sheet. Another problem is, that - as you mentioned - arrays in excel are 1-based; so you have to loop until j <= count not j < count.

    So I think that code would work better:

    Excel.Worksheet dummy = finalized.Worksheets[1];
    
    for (int i = 2; i <= excel.Workbooks.Count; i++)
    {
        int count = excel.Workbooks[i].Worksheets.Count;
    
        for (int j = 1; j <= count; j++)
        {
            Excel._Worksheet pastee = (Excel._Worksheet)excel.Workbooks[i].Worksheets[j];
            pastee.Copy(dummy);
        }
    }
    
    dummy.Delete();