使用OpenXml.WordProcessing .NET以编程方式将重复节添加到Word文档中

问题描述 投票:-1回答:1

我有一个要使用C#动态填充的文档模板。该模板包含一个重复部分,其中包含一些文本框和一些静态文本。我希望能够填充文本框,并在需要时添加新的部分项目。

几乎起作用的代码如下:

WordprocessingDocument doc = WordprocessingDocument.Open(@"C:\in\test.docx", true);
var mainDoc = doc.MainDocumentPart.Document.Body
    .GetFirstChild<DocumentFormat.OpenXml.Wordprocessing.SdtBlock>()                    
    .GetFirstChild<DocumentFormat.OpenXml.Wordprocessing.SdtContentBlock>();

var person = mainDoc.ChildElements[mainDoc.ChildElements.Count-1];
person.InsertAfterSelf<DocumentFormat.OpenXml.Wordprocessing.SdtBlock>(
    (DocumentFormat.OpenXml.Wordprocessing.SdtBlock) person.Clone());

但是,由于唯一的ID也被Clone方法复制,因此这会产生损坏的文件。

关于实现我的目标的任何想法?

ms-word openxml openxml-sdk
1个回答
0
投票

以下代码显示了如何执行此操作。请注意,这将删除现有的唯一ID(w:id元素),以确保不会重复此操作。

using WordprocessingDocument doc = WordprocessingDocument.Open(@"C:\in\test.docx", true);

// Get the w:sdtContent element of the first block-level w:sdt element,
// noting that "sdtContent" is called "mainDoc" in the question.
SdtContentBlock sdtContent = doc.MainDocumentPart.Document.Body
    .Elements<SdtBlock>()
    .Select(sdt => sdt.SdtContentBlock)
    .First();

// Get last element within SdtContentBlock. This seems to represent a "person".
SdtBlock person = sdtContent.Elements<SdtBlock>().Last();

// Create a clone and remove an existing w:id element from the clone's w:sdtPr
// element, to ensure we don't repeat it. Note that the w:id element is optional
// and Word will add one when it saves the document.
var clone = (SdtBlock) person.CloneNode(true);
SdtId id = clone.SdtProperties?.Elements<SdtId>().FirstOrDefault();
id?.Remove();

// Add the clone as the new last element.
person.InsertAfterSelf(clone);
© www.soinside.com 2019 - 2024. All rights reserved.