AltChunk破坏富格文本内容控件

本文关键字:控件 文本 AltChunk | 更新日期: 2023-09-27 17:58:58

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

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

AltChunk破坏富格文本内容控件

wordDocument.MainDocumentPart.Document.Body.Descendants<SdtElement>()返回IEnumerable<SdtElement>,您正在将其分配给SdtElemtnt。尝试使用var或实际返回类型。

更新:

您的代码是有效的。你做错的是这条线路sdtElement.RemoveAllChildren();

sdt元素(内容控件)包含其他元素,如sdtP(内容控件属性)、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.
}

希望这能有所帮助!