我使用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
的内容控件。不知何故,此过程会破坏富文本内容控件。
我做错了什么吗?或者有更好的选择吗?
答案 0 :(得分:2)
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块插入内容控件内容元素(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.
}
希望这有帮助!