C#将excel文件内容复制并追加到新的excel文件中

时间:2018-08-01 10:36:51

标签: c# excel visual-studio-2017

我正在尝试构建一个安装程序项目(Windows窗体),通过该项目我可以从目录中选择多个excel文件,从每个文件中复制内容,并将其附加到新的单个输出文件中。我正在VS 2017 Community Edition中使用Microsoft.Office.Interop.Excel软件包。我仍在努力,但向正确的方向稍加推动会很有帮助。

说,我的目录中有100多个excel文件,每个excel工作簿至少包含1张纸。每张纸的结构相同。使用OpenFileDialog

  1. 我选择文件,并在listbox中显示所选的文件名及其路径
  2. 我在标签中显示文件计数
  3. 读取每个文件的内容并将其粘贴到新的Excel文件中。输出文件是单个。读取每个文件后,我想将内容附加到输出文件的末尾。因此,我只想复制一个工作表中的所有行,并追加到另一工作表的末尾。

我不知道我到底要去哪里,我什至无法创建输出excel文件。到目前为止,这是我的工作:

Excel.Application excel;
    Stream myStrm;
    OpenFileDialog ofd = new OpenFileDialog();

    private void button1_Click(object sender, EventArgs e)
    {
        ofd.InitialDirectory = "c:\\";
        ofd.Title = "Please select the files to merge";
        ofd.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
        //ofd.FileName = "ExportedData";
        //ofd.DefaultExt = ".xlsx";
        ofd.RestoreDirectory = true;
        ofd.Multiselect = true;

        //To store file path info
        List<System.IO.FileInfo> fList = new List<System.IO.FileInfo>();

        if (ofd.ShowDialog() == DialogResult.OK)
        {
            var fileName = ofd.FileName;
            var tempFolderPath = Path.GetTempPath();
            var templateFileLocation = Path.Combine(Directory.GetCurrentDirectory(), "Model", "ExcelTemplate.xlsx");
            templateFileLocation = templateFileLocation.Replace("\\bin\\Debug\\", "\\");

            foreach (String file in ofd.FileNames)
            {
                try
                {
                    if((myStrm = ofd.OpenFile()) != null)
                    {
                        using (myStrm)
                        {
                            //to display file name in the 1st listbox
                            fileListBox.Items.Add(file.Substring(file.LastIndexOf('\\') + 1));
                            //to display the path of the file
                            pathListBox.Items.Add(file);
                        }
                    }
                    //to display the selected file count 
                    fileCntLbl.Text = "You have selected " + ofd.FileNames.Length + " files";

                    ApplicationClass app = new ApplicationClass();
                    Workbook curWorkBook = null;
                    Workbook destWorkbook = null;
                    Worksheet workSheet = null;
                    Worksheet newWorksheet = null;
                    Object defaultArg = Type.Missing;
                    //FileInfo fi = null;
                    Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();

                    try
                    {
                        // Copy the source sheet
                        curWorkBook = app.Workbooks.Open(file, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg);
                        workSheet = (Worksheet)curWorkBook.Sheets[1];
                        workSheet.UsedRange.Copy(defaultArg);

                        // Paste on destination sheet
                        destWorkbook = app.Workbooks.Open(@"c:\\Results.xlxs", defaultArg, false, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg, defaultArg);
                        newWorksheet = (Worksheet)destWorkbook.Worksheets.Add(defaultArg, defaultArg, defaultArg, defaultArg);
                        newWorksheet.UsedRange._PasteSpecial(XlPasteType.xlPasteValues, XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);


                        }
                    }
                    catch (Exception exc)
                    {
                        System.Windows.Forms.MessageBox.Show(exc.Message);
                    }
                    finally
                    {
                        if (curWorkBook != null)
                        {
                            curWorkBook.Save();
                            curWorkBook.Close(defaultArg, defaultArg, defaultArg);
                        }

                        if (destWorkbook != null)
                        {
                            destWorkbook.Save();
                            destWorkbook.Close(defaultArg, defaultArg, defaultArg);
                        }
                    }
                    app.Quit();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
                }
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        System.Windows.Forms.Application.Exit();
    }

solution有效,但不复制内容并产生错误。错误是这样的:

Error Screenshot

任何帮助/建议表示赞赏。感谢您的帮助。

  

我已经在stackexchange,codeproject和许多其他站点上尝试了所有解决方案。因此,请勿将其标记为重复项或家庭作业。

3 个答案:

答案 0 :(得分:1)

请尝试使用Sheet.Copy函数,而不是复制/粘贴UsedRange。它将大大简化您的代码并减少潜在的错误点。 C# - How to copy a single Excel worksheet from one workbook to another?

答案 1 :(得分:1)

我知道我来不及回答这个问题,但这仍然可以帮助某人。

您可以在此处具有两个功能,一个用于打开文件,另一个用于复制内容。

在第一个函数中,您可以通过for循环打开任意数量的文件,如下所示:

void OpenFiles()
{
    foreach (string strFile in sourceFiles) //sourceFiles is a list containing the file paths
    {
        bool b = false;
        Excel.Workbook bookSource = app.Workbooks._Open(strFile, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
        Excel.Worksheet sheetSource = bookSource.Worksheets[1] as Excel.Worksheet;

        CopyData();

    }
    //finally save the file as your requirements and close all the open workbooks
}

void CopyData()
{
    Excel.Worksheet lastsheet = null;   //last sheet in the workbook
    int limit = 1000000; //variable to check if your sheet has exceeded
    try
    {
        var sheets = bookDest.Sheets;
        lastsheet = (Excel.Worksheet)bookDest.Sheets[sheets.Count];
        hc.ReleaseObject(sheets);
        drc = lastsheet.UsedRange.Rows.Count;       //no of rows used in result workbook
        src = sheetSource.UsedRange.Rows.Count;     //no of rows used in source workbook

        //if else loop to check if you have exceeded 1st sheet limit before start copying
        if ((drc + src) <= limit)
        {
            int sheetRowCount = sheetSource.UsedRange.Rows.Count;
            Excel.Range range = sheetSource.get_Range(string.Format("A{0}", _headerRowCount), _columnEnd + sheetRowCount.ToString());
            range.Copy(lastsheet.get_Range(string.Format("A{0}", _currentRowCount), Missing.Value));
            _currentRowCount += range.Rows.Count;
        }
        else if ((drc >= limit && src >= limit) || drc >= limit || src >= limit || (drc + src) >= limit)
        {
                Excel.Worksheet newSheet = (Excel.Worksheet)bookDest.Worksheets.Add(After: lastsheet);
                newSheet.Name = "Result " + (cnt++);
                hc.ReleaseObject(lastsheet);
                lastsheet = newSheet;
                lastsheet.Activate();
                CopyHeader(lastsheet);

                //((Excel.Worksheet) this.app.ActiveWorkbook.Sheets[lastsheet]).Select();
                int sheetRowCount = sheetSource.UsedRange.Rows.Count;
                Excel.Range range = sheetSource.get_Range(string.Format("A{0}", _headerRowCount), _columnEnd + sheetRowCount.ToString());
                range.Copy(lastsheet.get_Range(string.Format("A{0}", _currentRowCount), Missing.Value));
                _currentRowCount += range.Rows.Count;
            }
        }
        else
        {
            int sheetRowCount = sheetSource.UsedRange.Rows.Count;
            Excel.Range range = sheetSource.get_Range(string.Format("A{0}", _headerRowCount), _columnEnd + sheetRowCount.ToString());
            range.Copy(lastsheet.get_Range(string.Format("A{0}", _currentRowCount), Missing.Value));
            _currentRowCount += range.Rows.Count;
        }
    }
    catch (IndexOutOfRangeException)
    {
        MessageBox.Show("Some problem with the source file", "Copy error");
    }
    finally
    {
        ReleaseObject(lastsheet);
    }
}

我已将上限限制为一百万。如果您认为此限制可能会超出您的才能,那么您可以减少它。

邀请您进行任何代码更改。

谢谢。

答案 2 :(得分:0)

或者,使用System.IO,可以使用以下命令将excel文件复制到新文件中:

File.WriteAllBytes(newFilePath, File.ReadAllBytes(initialFilePath));