You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#移除Word文档中的重复节控件和文本内容控件并保留内容

移除Word内容控件并保留内容(OpenXml实现)

你的现有代码直接删除了整个SdtElement(内容控件节点),导致里面的内容也被一并移除。要实现只删控件、保留内容,核心是把控件内部的实际内容提取出来,替换掉控件节点本身。

修改后的完整代码

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

using (WordprocessingDocument doc = WordprocessingDocument.Open(@"C:\Temp\Test\Weekly Marketing Dashboard.docx", true))
{
    MainDocumentPart mainPart = doc.MainDocumentPart;

    // 提前转成List,避免遍历过程中集合结构变化引发异常
    var sdtElements = mainPart.Document.Descendants<SdtElement>().ToList();

    foreach (var sdtElement in sdtElements)
    {
        // 获取内容控件的内容容器节点
        var sdtContent = sdtElement.Descendants<SdtContent>().FirstOrDefault();
        
        if (sdtContent != null && sdtContent.HasChildren)
        {
            // 将内容节点逐个移到原控件的位置
            foreach (var contentNode in sdtContent.Elements().ToList())
            {
                sdtElement.Parent.InsertBefore(contentNode, sdtElement);
            }
        }

        // 删除内容控件本身
        sdtElement.Remove();
    }

    mainPart.Document.Save();
}

关键逻辑说明

  1. 定位内容容器:SdtContent是OpenXml中专门存储内容控件实际内容的节点,不管是重复节控件还是文本控件,内容都存在这里面。
  2. 迁移内容节点:把SdtContent里的所有子节点(就是你要保留的文本、段落等内容)移动到原控件节点的前方,确保内容位置不变。
  3. 删除控件节点:内容迁移完成后,删除原SdtElement节点,彻底移除控件结构。

注意事项

  • 提前调用ToList()将sdtElements转为列表:因为遍历过程中会修改文档节点结构,如果直接遍历原集合会引发InvalidOperationException,你原来的代码已经处理了这一点,无需改动。
  • 兼容多种控件类型:这段代码能处理文本内容控件、重复节控件等所有基于SdtElement的内容控件,无需针对不同控件类型单独处理。

内容的提问来源于stack exchange,提问作者M4tee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:22:27