CSharp DocumentFormat.OpenXML和Excel - 将工作表中的数据从一个电子表格复制到另一个电子表格(有代码)

时间:2017-09-07 13:13:36

标签: c# excel openxml

我想请你的帮助。我正在创建一个过程,它将读取Excel文件并将工作表复制到新的电子表格中。

我正在使用DocumentFormat.OpenXML创建一个新的电子表格,然后它将遍历每个Excel电子表格并复制工作表。

我正在使用DocumentFormat,因为我需要在生产服务器上运行该进程,强烈建议不要在服务器上使用Word / Excel库(Interop库)。

问题在于它没有复制数据。它会复制电子表格选项卡名称。我可以在新电子表格中为当前Excel文件中的每个电子表格创建一个新工作表。当我打开Excel电子表格时,应用程序显示错误消息。

“我们发现'Test.xlsx'中的某些内容存在问题。您是否希望尽可能多地尝试恢复?如果您信任此工作簿的来源,请单击是”。

我点击了是,Excel恢复了电子表格。它获得了电子表格工作表名称。作为测试,我将工作表的名称重命名为Bob,Martin,Trevor。该过程将工作表的名称复制到新电子表格中。所以我可以访问工作表。出于某种原因,它不会复制

中的数据

我的代码如下。如果您需要复制该问题,则需要在Visual Studio项目中安装DocumentFormat.OpenXML(nuget)并安装OpenXML SDK 2.5。

DocumentFormat.OpenXML(来自nuget)

https://www.nuget.org/packages/DocumentFormat.OpenXml/

OpenXML SDK 2.5

https://www.microsoft.com/en-gb/download/details.aspx?id=30425

这是我在代码顶部使用的命名空间。

命名空间

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using DocumentFormat.OpenXml;
using System.IO;
using ExcelDataReader;

测试功能 - 合并Excel文件。它将从目录中检索所有Excel文件:“C:\ lab \ excel”。然后它将在“C:\ lab \”中创建一个名为“Test.xlsx”的新电子表格。

private static void mergeExcelFiles()
        {
            string mergeFilePath = "C:\\lab\\Test.xlsx";
            string dirPath = "C:\\lab\\excel";
            string[] files = System.IO.Directory.GetFiles(dirPath, "*.xlsx");

            // delete file
            try
            {
                System.IO.File.Delete(mergeFilePath);
            } catch (Exception ex)
            {
                Console.WriteLine("Can't delete file. Ex: {0}", ex.Message);
            }             

            // CREATE SPREADSHEET
            using (SpreadsheetDocument document = SpreadsheetDocument.Create(mergeFilePath, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
            {
                int sheetID = 1;

                WorkbookPart workbookPart = document.AddWorkbookPart();
                workbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();

                WorksheetPart worksheetPart = worksheetPart = workbookPart.AddNewPart<DocumentFormat.OpenXml.Packaging.WorksheetPart>();
                DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();

                workbookPart.Workbook.Sheets = sheets;

                System.Diagnostics.Debug.WriteLine("Document: Before - How many worksheets?: " + document.WorkbookPart.WorksheetParts.Count());

                foreach (var doc in files)
                {
                    string fullDocumentPath = doc;

                    // CHECK IF FILE EXISTS
                    if (!System.IO.File.Exists(fullDocumentPath))
                    {
                        continue;
                    }

                    // CREATE WORKSHEETS
                    using (DocumentFormat.OpenXml.Packaging.SpreadsheetDocument tempSpreadsheet = DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open(fullDocumentPath, true))
                    {
                        WorkbookPart tempWorkbookPart = tempSpreadsheet.GetPartsOfType<WorkbookPart>().FirstOrDefault();
                        DocumentFormat.OpenXml.Spreadsheet.Workbook tempWorkbook = tempWorkbookPart.Workbook;

                        DocumentFormat.OpenXml.Spreadsheet.Sheet tempSheet = tempWorkbook.Sheets.FirstOrDefault() as DocumentFormat.OpenXml.Spreadsheet.Sheet;

                        if (tempSheet == null)
                        {
                            continue;
                        }

                        tempSheet.SheetId = (uint) sheetID;

                        workbookPart.Workbook.Sheets.AppendChild(tempSheet.CloneNode(true));
                        workbookPart.Workbook.Save();

                        sheetID += 1;
                    }

                }

                document.Save();

                System.Diagnostics.Debug.WriteLine("Document: After - How many worksheets?: " + document.WorkbookPart.WorksheetParts.Count());

            }

        }

有人可以建议为什么电子表格中的数据不会被复制到新的电子表格中吗?

1 个答案:

答案 0 :(得分:0)

在您的代码中:您获取excel文件名,将其存储在字符串数组中,然后尝试删除该excel文件。创建一个电子表格文档,然后尝试将其存储为您尝试删除的同一个mergeFilePath。

根据您的描述,您希望从已存储在目录中某处的模板中复制excel文件并将其复制,然后对excel文件进​​行一些修改。我简化了代码:

    public static void mergeExcelFiles()
    {
        string template = @"Template.xlsx"; // look in your bin folder
        string fileName = @"Test.xlsx";
        File.Copy(template, fileName, true);

        using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
        {
            // Instatiate new SheetData
            SheetData sheetData = new SheetData();
            // Instatiate WorkbookPart from SpreadsheetDocument
            WorkbookPart workbookPart = document.WorkbookPart;
            // Get the (first)worksheet
            //Sheet theSheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == "Sheet1").FirstOrDefault();
            Sheet theSheet = workbookPart.Workbook.Descendants<Sheet>().First();
            if (theSheet != null)
            {
                sheetData = ((WorksheetPart)workbookPart.GetPartById(theSheet.Id)).Worksheet.GetFirstChild<SheetData>();
            }

            Row row = new Row();
            Cell cell = new Cell();
            cell.DataType = CellValues.InlineString;
            cell.CellReference = "A2";
            Text text = new Text("Some text");
            InlineString inlineString = new InlineString(text);
            cell.AppendChild(inlineString);
            row.RowIndex = (UInt32)2;
            row.AppendChild(cell);
            // Append new row to SheetData
            sheetData.AppendChild(row);

            workbookPart.Workbook.Save();
        }
    }