AltChunk破坏了丰富的文本内容控制

时间:2013-02-12 11:33:27

标签: c# ms-word vsto openxml

我使用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的内容控件。不知何故,此过程会破坏富文本内容控件。

我做错了什么吗?或者有更好的选择吗?

1 个答案:

答案 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,也没有TagsdtContent

要解决此问题,请尝试将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.
}

希望这有帮助!