将多个excel文件合并为一个

时间:2011-09-01 14:25:37

标签: c# excel com

问题在于,我生成了几个excel文件,每个文件都有1个标签(但这并不代表将来会有更多文件)。

我需要编写的是一个可以打开每个文件的过程,并将所有文件的工作表(标签)复制到一个新文件中。

最后,该新文件应包含所有其他文件的工作表。

目前,我创建了以下内容以完成excel格式之间的转换。

我不太确定从哪里开始,我没有任何我用来创建这个的源...并且我不太确定对象模型(为了将标签复制到一个新文件)或我将面临的问题,并确保我保持一切清理。

        object excelApplication = null;
        object workbook = null;
        object workbooks = null;

        try
        {
            // Get the Remote Type
            var excelType = Type.GetTypeFromProgID("Excel.Application", Properties.Settings.Default.ExcelServer, true);

            // Instantiate the type
            excelApplication = Activator.CreateInstance(excelType);

            // Turn off Prompts
            excelApplication.GetType().InvokeMember(
                "DisplayAlerts",
                BindingFlags.SetProperty,
                null,
                excelApplication,
                new Object[] { false });

            // Get a reference to the workbooks object
            workbooks = excelApplication.GetType().InvokeMember(
                "Workbooks",
                BindingFlags.GetProperty,
                null,
                excelApplication,
                null);

            // Open the input file
            workbook = workbooks.GetType().InvokeMember(
                "Open",
                BindingFlags.InvokeMethod,
                null,
                workbooks,
                new object[] { inputFilePath });

            // If overwrite is turned off, and the file exist, the save as line will throw an error
            if (File.Exists(outputFilePath) && overwriteIfExists)
            {
                File.Delete(outputFilePath);
            }

            // Save the workbook
            workbook.GetType().InvokeMember(
                "SaveAs",
                BindingFlags.InvokeMethod,
                null,
                workbook,
                new object[] { outputFilePath, saveAsFileFormat, null, null, null, null, 1, null, null, null, null, null });
        }
        finally
        {
            // Cleanup all created COM objects
            if (workbook != null)
            {
                workbook.GetType().InvokeMember(
                    "Close",
                    BindingFlags.InvokeMethod,
                    null,
                    workbook,
                    null);
                Marshal.ReleaseComObject(workbook);
                workbook = null;
            }

            if (workbooks != null)
            {
                Marshal.ReleaseComObject(workbooks);
                workbooks = null;
            }

            if (excelApplication != null)
            {
                excelApplication.GetType().InvokeMember(
                    "Quit",
                    BindingFlags.InvokeMethod,
                    null,
                    excelApplication,
                    null);
                Marshal.ReleaseComObject(excelApplication);
                excelApplication = null;
            }
        }

编辑:此代码几乎正常工作,问题就在于应该实际执行复制的问题......

    public byte[] MergeFiles(FileFormat saveAsFileFormat, List<byte[]> inputFileBytesList)
    {
        var outputFilePath = Path.Combine(Properties.Settings.Default.WorkingFolder, Guid.NewGuid() + ".target.xls");

        Impersonate(
            Properties.Settings.Default.ImpersonationUser.Decrypt(),
            Properties.Settings.Default.ImpersonationDomain,
            Properties.Settings.Default.ImpersonationPassword.Decrypt()
        );

        var convertedFileList = new List<string>();
        foreach (var inputFileBytes in inputFileBytesList)
        {
            var inputFileExtension = GetExtension(inputFileBytes);
            var inputFilePath = Path.Combine(Properties.Settings.Default.WorkingFolder, Guid.NewGuid() + inputFileExtension);
            var convertedFileBytes = SaveAs(saveAsFileFormat, inputFileBytes);
            File.WriteAllBytes(inputFilePath, convertedFileBytes);
            convertedFileList.Add(inputFilePath);
        }

        // Target Excel File
        object targetExcelApplication = null;
        object targetWorkbook = null;
        object targetWorkbooks = null;
        object targetWorksheets = null;
        object targetWorksheet = null;

        try
        {
            // Get the Remote Type
            var excelType = Type.GetTypeFromProgID("Excel.Application", Properties.Settings.Default.ExcelServer, true);

            // Instantiate the type
            targetExcelApplication = Activator.CreateInstance(excelType);

            // Turn off Prompts
            targetExcelApplication.GetType().InvokeMember(
                "DisplayAlerts",
                BindingFlags.SetProperty,
                null,
                targetExcelApplication,
                new Object[] { false });

            // Get a reference to the workbooks object
            targetWorkbooks = targetExcelApplication.GetType().InvokeMember(
                "Workbooks",
                BindingFlags.GetProperty,
                null,
                targetExcelApplication,
                null);

            // Create a workbook to add the sheets to
            targetWorkbook = targetWorkbooks.GetType().InvokeMember(
                "Add",
                BindingFlags.InvokeMethod,
                null,
                targetWorkbooks,
                new object[] { 1 });

            // Get a reference to the worksheets object
            targetWorksheets = targetWorkbook.GetType().InvokeMember(
                "Sheets",
                BindingFlags.GetProperty,
                null,
                targetExcelApplication,
                null
                );

            foreach (var inputFilePath in convertedFileList)
            {
                // Open each File, grabbing all tabs
                object sourceExcelApplication = null;
                object sourceWorkbooks = null;
                object sourceWorkbook = null;
                object sourceWorksheets = null;

                try
                {
                    // Instantiate the type
                    sourceExcelApplication = Activator.CreateInstance(excelType);

                    // Turn off Prompts
                    sourceExcelApplication.GetType().InvokeMember(
                        "DisplayAlerts",
                        BindingFlags.SetProperty,
                        null,
                        sourceExcelApplication,
                        new Object[] {false});

                    // Get a reference to the workbooks object
                    sourceWorkbooks = sourceExcelApplication.GetType().InvokeMember(
                        "Workbooks",
                        BindingFlags.GetProperty,
                        null,
                        sourceExcelApplication,
                        null);

                    // Open the input file
                    sourceWorkbook = sourceWorkbooks.GetType().InvokeMember(
                        "Open",
                        BindingFlags.InvokeMethod,
                        null,
                        sourceWorkbooks,
                        new object[] {inputFilePath});

                    // Get a reference to the worksheets object
                    sourceWorksheets = sourceWorkbook.GetType().InvokeMember(
                        "Sheets",
                        BindingFlags.GetProperty,
                        null,
                        sourceExcelApplication,
                        null);

                    var sourceSheetCount = (int)(sourceWorksheets.GetType().InvokeMember(
                        "Count",
                        BindingFlags.GetProperty,
                        null,
                        sourceWorksheets,
                        null));

                    for (var i = 1; i <= sourceSheetCount; i++)
                    {
                        var targetSheetCount = (int)(targetWorksheets.GetType().InvokeMember(
                            "Count",
                            BindingFlags.GetProperty,
                            null,
                            targetWorksheets,
                            null));

                        var sourceWorksheet = sourceWorksheets.GetType().InvokeMember(
                            "Item",
                            BindingFlags.GetProperty,
                            null,
                            sourceWorksheets,
                            new Object[] { i });

                        targetWorksheet = targetWorksheets.GetType().InvokeMember(
                            "Item",
                            BindingFlags.GetProperty,
                            null,
                            targetWorksheets,
                            new Object[] { targetSheetCount });

                        // TODO: Copy into target file

                        sourceWorksheet.GetType().InvokeMember(
                            "Copy",
                            BindingFlags.InvokeMethod,
                            null,
                            sourceWorksheet,
                            new[] { Type.Missing, targetWorksheet }
                            );

                        if (sourceWorksheet != null)
                        {
                            Marshal.ReleaseComObject(sourceWorksheet);
                            sourceWorksheet = null;
                        }
                    }
                }
                finally
                {
                    // Cleanup all created COM objects
                    if (sourceWorksheets != null)
                    {
                        Marshal.ReleaseComObject(sourceWorksheets);
                        sourceWorksheets = null;
                    }

                    if (sourceWorkbook != null)
                    {
                        sourceWorkbook.GetType().InvokeMember(
                            "Close",
                            BindingFlags.InvokeMethod,
                            null,
                            sourceWorkbook,
                            null);
                        Marshal.ReleaseComObject(sourceWorkbook);
                        sourceWorkbook = null;
                    }

                    if (sourceWorkbooks != null)
                    {
                        Marshal.ReleaseComObject(sourceWorkbooks);
                        sourceWorkbooks = null;
                    }

                    if (sourceExcelApplication != null)
                    {
                        sourceExcelApplication.GetType().InvokeMember(
                            "Quit",
                            BindingFlags.InvokeMethod,
                            null,
                            sourceExcelApplication,
                            null);
                        Marshal.ReleaseComObject(sourceExcelApplication);
                        sourceExcelApplication = null;
                    }
                }
            }

            // If overwrite is turned off, and the file exist, the save as line will throw an error
            if (File.Exists(outputFilePath))
            {
                File.Delete(outputFilePath);
            }

            // Save the workbook
            targetWorkbook.GetType().InvokeMember(
                "SaveAs",
                BindingFlags.InvokeMethod,
                null,
                targetWorkbook,
                new object[] { outputFilePath, saveAsFileFormat, null, null, null, null, 1, null, null, null, null, null });
        }
        finally
        {
            // Cleanup all created COM objects
            if (targetWorksheets != null)
            {
                Marshal.ReleaseComObject(targetWorksheets);
                targetWorksheets = null;
            }

            if (targetWorkbook != null)
            {
                targetWorkbook.GetType().InvokeMember(
                    "Close",
                    BindingFlags.InvokeMethod,
                    null,
                    targetWorkbook,
                    null);
                Marshal.ReleaseComObject(targetWorkbook);
                targetWorkbook = null;
            }

            if (targetWorkbooks != null)
            {
                Marshal.ReleaseComObject(targetWorkbooks);
                targetWorkbooks = null;
            }

            if (targetExcelApplication != null)
            {
                targetExcelApplication.GetType().InvokeMember(
                    "Quit",
                    BindingFlags.InvokeMethod,
                    null,
                    targetExcelApplication,
                    null);
                Marshal.ReleaseComObject(targetExcelApplication);
                targetExcelApplication = null;
            }
        }

        // Read target file bytes
        var resultBytes = (File.Exists(outputFilePath))
            ? File.ReadAllBytes(outputFilePath)
            : new byte[] { };

        // Delete working files
        if (File.Exists(outputFilePath))
            File.Delete(outputFilePath);
        foreach (var inputFilePath in convertedFileList.Where(File.Exists))
        {
            File.Delete(inputFilePath);
        }

        Repersonate();

        // Return result
        return resultBytes;
    }

我收到错误 System.Runtime.InteropServices.COMException:Worksheet类的复制方法失败,这没有多大帮助......我不知道它失败的原因...... < / p>

2 个答案:

答案 0 :(得分:2)

这似乎有效,只需要添加一点清理来删除最初创建的空白工作表,然后在保存之前激活文件中的第一个工作表

    [WebMethod]
    public byte[] MergeFiles(FileFormat saveAsFileFormat, List<byte[]> inputFileBytesList)
    {
        //var outputFilePath = Path.Combine(Properties.Settings.Default.WorkingFolder, Guid.NewGuid() + ".xls");
        var outputFilePath = Path.Combine(Properties.Settings.Default.WorkingFolder, "target.xls");

        Impersonate(
            Properties.Settings.Default.ImpersonationUser.Decrypt(),
            Properties.Settings.Default.ImpersonationDomain,
            Properties.Settings.Default.ImpersonationPassword.Decrypt()
        );

        var convertedFileList = new List<string>();
        foreach (var inputFileBytes in inputFileBytesList)
        {
            var inputFileExtension = GetExtension(inputFileBytes);
            var inputFilePath = Path.Combine(Properties.Settings.Default.WorkingFolder, Guid.NewGuid() + inputFileExtension);
            File.WriteAllBytes(inputFilePath, inputFileBytes);

            var convertedFilePath = Path.Combine(Properties.Settings.Default.WorkingFolder, Guid.NewGuid() + inputFileExtension);
            SaveAsInternal(saveAsFileFormat, inputFilePath, convertedFilePath, true);
            convertedFileList.Add(convertedFilePath);
        }

        // Target Excel File
        object excelApplication = null;
        object excelWorkbooks = null;
        object targetWorkbook = null;
        object targetWorksheets = null;
        object targetWorksheet = null;

        try
        {
            // Get the Remote Type
            var excelType = Type.GetTypeFromProgID("Excel.Application", Properties.Settings.Default.ExcelServer, true);

            // Instantiate the type
            excelApplication = Activator.CreateInstance(excelType);

            // Turn off Prompts
            excelApplication.GetType().InvokeMember(
                "DisplayAlerts",
                BindingFlags.SetProperty,
                null,
                excelApplication,
                new Object[] { false });

            // Get a reference to the workbooks object
            excelWorkbooks = excelApplication.GetType().InvokeMember(
                "Workbooks",
                BindingFlags.GetProperty,
                null,
                excelApplication,
                null);

            // Create a workbook to add the sheets to
            targetWorkbook = excelWorkbooks.GetType().InvokeMember(
                "Add",
                BindingFlags.InvokeMethod,
                null,
                excelWorkbooks,
                new object[] { 1 });

            // Get a reference to the worksheets object
            targetWorksheets = targetWorkbook.GetType().InvokeMember(
                "Sheets",
                BindingFlags.GetProperty,
                null,
                excelApplication,
                null
                );

            // Open each File, grabbing all tabs
            foreach (var inputFilePath in convertedFileList)
            {
                object sourceWorkbook = null;
                object sourceWorksheets = null;

                try
                {
                    // Open the input file
                    sourceWorkbook = excelWorkbooks.GetType().InvokeMember(
                        "Open",
                        BindingFlags.InvokeMethod,
                        null,
                        excelWorkbooks,
                        new object[] {inputFilePath});

                    // Get a reference to the worksheets object
                    sourceWorksheets = sourceWorkbook.GetType().InvokeMember(
                        "Sheets",
                        BindingFlags.GetProperty,
                        null,
                        excelApplication,
                        null);

                    var sourceSheetCount = (int)(sourceWorksheets.GetType().InvokeMember(
                        "Count",
                        BindingFlags.GetProperty,
                        null,
                        sourceWorksheets,
                        null));

                    for (var i = 1; i <= sourceSheetCount; i++)
                    {
                        var targetSheetCount = (int)(targetWorksheets.GetType().InvokeMember(
                            "Count",
                            BindingFlags.GetProperty,
                            null,
                            targetWorksheets,
                            null));

                        var sourceWorksheet = sourceWorksheets.GetType().InvokeMember(
                            "Item",
                            BindingFlags.GetProperty,
                            null,
                            sourceWorksheets,
                            new Object[] { i });

                        targetWorksheet = targetWorksheets.GetType().InvokeMember(
                            "Item",
                            BindingFlags.GetProperty,
                            null,
                            targetWorksheets,
                            new Object[] { targetSheetCount });

                        // TODO: Copy into target file

                        sourceWorksheet.GetType().InvokeMember(
                            "Copy",
                            BindingFlags.InvokeMethod,
                            null,
                            sourceWorksheet,
                            new[] { Type.Missing, targetWorksheet }
                            );

                        if (sourceWorksheet != null)
                        {
                            Marshal.ReleaseComObject(sourceWorksheet);
                            sourceWorksheet = null;
                        }
                    }
                }
                finally
                {
                    // Cleanup all created COM objects
                    if (sourceWorksheets != null)
                    {
                        Marshal.ReleaseComObject(sourceWorksheets);
                        sourceWorksheets = null;
                    }

                    if (sourceWorkbook != null)
                    {
                        sourceWorkbook.GetType().InvokeMember(
                            "Close",
                            BindingFlags.InvokeMethod,
                            null,
                            sourceWorkbook,
                            null);
                        Marshal.ReleaseComObject(sourceWorkbook);
                        sourceWorkbook = null;
                    }
                }
            }

            // If overwrite is turned off, and the file exist, the save as line will throw an error
            if (File.Exists(outputFilePath))
            {
                File.Delete(outputFilePath);
            }

            // Save the workbook
            targetWorkbook.GetType().InvokeMember(
                "SaveAs",
                BindingFlags.InvokeMethod,
                null,
                targetWorkbook,
                new object[] { outputFilePath, saveAsFileFormat, null, null, null, null, 1, null, null, null, null, null });
        }
        finally
        {
            // Cleanup all created COM objects
            if (targetWorksheets != null)
            {
                Marshal.ReleaseComObject(targetWorksheets);
                targetWorksheets = null;
            }

            if (targetWorkbook != null)
            {
                targetWorkbook.GetType().InvokeMember(
                    "Close",
                    BindingFlags.InvokeMethod,
                    null,
                    targetWorkbook,
                    null);
                Marshal.ReleaseComObject(excelWorkbooks);
                excelWorkbooks = null;
            }

            if (excelWorkbooks != null)
            {
                Marshal.ReleaseComObject(excelWorkbooks);
                excelWorkbooks = null;
            }

            if (excelApplication != null)
            {
                excelApplication.GetType().InvokeMember(
                    "Quit",
                    BindingFlags.InvokeMethod,
                    null,
                    excelApplication,
                    null);
                Marshal.ReleaseComObject(excelApplication);
                excelApplication = null;
            }
        }

        // Read target file bytes
        var resultBytes = (File.Exists(outputFilePath))
            ? File.ReadAllBytes(outputFilePath)
            : new byte[] { };

        // Delete working files
        if (File.Exists(outputFilePath))
            File.Delete(outputFilePath);
        foreach (var inputFilePath in convertedFileList.Where(File.Exists))
        {
            File.Delete(inputFilePath);
        }

        Repersonate();

        // Return result
        return resultBytes;
    }

答案 1 :(得分:0)

使用ADO连接选择值,并使用范围内的copyFromRecordset方法粘贴到其他工作簿中。