OpenXML:如何将工作表复制到另一个工作簿?

OpenXML: How to copy a worksheet to another workbook?

我需要将一些工作簿的工作表合并到一个新工作簿中。我尝试的是这个,但我得到 "Cannot insert the OpenXmlElement "newChild" 因为它是树的一部分。".

using (var document = SpreadsheetDocument.Create(destinationFileName, SpreadsheetDocumentType.Workbook))
{
    // Add a WorkbookPart to the document
    var workbookPart = document.AddWorkbookPart();
    workbookPart.Workbook = new Workbook();

    // Add a WorksheetPart to the WorkbookPart
    var worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
    worksheetPart.Worksheet = new Worksheet(new SheetData());

    foreach (var sourceFileName in sourceFileNames)
    {
        using (var sourceDocument = SpreadsheetDocument.Open(sourceFileName, false))
        {
            var sheet = (Sheet)sourceDocument.WorkbookPart.Workbook.Sheets.FirstChild;
            workbookPart.Workbook.AppendChild(new Worksheet(sheet));
        }
    }
}

该错误消息表示您正在尝试添加一个 OpenXmlElement(在本例中为 Sheet),而该 parent OpenXmlCompositeElement(一个 Sheets object 在这种情况下)作为另一个 OpenXmlCompositeElement 的新 child (在这种情况下是 Worksheet)。

在以下行项目中,您正在获取对 Sheet object 的引用,该引用已经有 parent Sheets object。

var sheet = (Sheet)sourceDocument.WorkbookPart.Workbook.Sheets.FirstChild;

使用 new Worksheet(sheet),您正试图将相同的 sheet 添加到另一个 parent,即您正在创建的 Worksheet 实例。那行不通。

暂时假设将 Sheet 添加到 Worksheet 是有意义的,您的第二行必须重写如下:

workbookPart.Workbook.AppendChild(new Worksheet(sheet.CloneNode(true)));

在上面的代码行中,sheet 被替换为 sheet.CloneNode(true),这对原始 Sheet object 进行了深度复制,没有 parent。因此,克隆可以作为新的 child 添加到另一个 parent.

虽然上述解决方案是对您直接问题的回答(因为它避免了错误消息),但您的代码没有意义,因为它没有创建有效的 Open XML 标记。 Worksheet 个实例不应添加到 Workbook 个实例,Sheet 个实例不应添加到 Worksheet 个实例。这不是复制多个工作表的方式,这是一项非常复杂的任务,需要您创建多个工作表部分,link 将这些工作表部分添加到您的工作簿部分,并考虑共享字符串、样式和其他内容。