我有一个要使用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方法复制,因此这会产生损坏的文件。
关于实现我的目标的任何想法?
以下代码显示了如何执行此操作。请注意,这将删除现有的唯一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);