我使用 AltChunk
对象将数据从 docx
文件复制到另一个文件中的富文本内容控件。副本效果很好。但现在内容控件无法转换为 OpenXml 中的 SdtElement
或 VSTO 中的 ContentControl
。
这是我使用的代码
SdtElement sdtElement = destinationdocument.MainDocumentPart.Document.Body.Descendants<SdtElement>().Where(b => b.SdtProperties.GetFirstChild<Tag>() != null).FirstOrDefault();
string altChunkId = "AltChunkId" + Guid.NewGuid().ToString();
AlternativeFormatImportPart chunk = destinationdocument.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImport PartType.WordprocessingML, altChunkId);
chunk.FeedData(File.Open("sourceFile", FileMode.OpenOrCreate));
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
sdtElement.RemoveAllChildren();
sdtElement.Append(altChunk);
代码第一次运行良好。但在第二次运行时,第一行抛出无法转换异常。在客户端使用 VSTO 时会出现同样的问题,ContentControl
对象无法保存插入 AltChunk
的内容控件。不知何故,此过程会损坏富文本内容控件。
我是不是做错了什么?或者有更好的选择吗?
最佳答案
wordDocument.MainDocumentPart.Document.Body.Descendants<SdtElement>()
返回IEnumerable<SdtElement>
并且您将其分配给 SdtElemtnt
。尝试使用var
或实际的返回类型。
更新:
您的代码是有效的。你做错的是这一行 sdtElement.RemoveAllChildren();
sdt 元素(内容控件)包含其他元素,如 sdtPr(内容控件属性)、sdtContent(内容控件内的实际内容)等,如下例所示。
<w:sdt>
<w:sdtPr>
...
</w:sdtPr>
<w:sdtContent>
....
</w:sdtContent>
</w:sdt>
你的sdtElement.RemoveAllChildren();
要做的就是删除 sdt 元素内的所有内容并将它们替换为:
<w:sdt>
<w:altChunk r:id="AltChunkIdffebf242-30b3-4905-bf39-fc0077be9474" />
</w:sdt>
这使得您的程序在第二次运行时抛出异常,如行destinationdocument.MainDocumentPart.Document.Body.Descendants<SdtElement>().Where(b => b.SdtProperties.GetFirstChild<Tag>() != null).FirstOrDefault();
所示您替换的文档 sdt 元素没有 SdtProperties
也没有 Tag
或sdtContent
。
要解决此问题,请尝试将 altchunk block 插入内容控制内容元素 ( sdtContent
),而不是直接插入 sdt 元素,如下所示:
using (
FileStream fileStream = File.Open("file.docx",
FileMode.Open))
{
chunk.FeedData(fileStream);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
//sdtElement.RemoveAllChildren();
sdtElement.Elements<SdtContentBlock>().FirstOrDefault().Append(altChunk); // This is going to add to the existing content.
}
希望这有帮助!
关于c# - AltChunk 破坏富文本内容控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14831570/