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

Open XML生成Word文档时编号无法重置的问题求助

Open XML生成Word文档编号无法重置的解决方案

我在用Open XML创建Word文档时,遇到了编号无法重置的问题:
期望的编号效果:

  1. Top index line A
  2. Top index line B
  3. Top index line C

但实际生成的编号是持续递增的:

  1. Top index line A
  2. Top index line B
  3. Top index line C

我尝试创建两个AbstractNum对象(abstractNumId分别为200和201)定义编号格式,对应生成两个NumberingInstance(编号ID为100、101),前两个段落绑定编号ID100,最后一个绑定101,但编号依然没有重置。

问题复现的C#代码示例

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

class Program
{
    static void Main(string[] args)
    {
        using (WordprocessingDocument doc = WordprocessingDocument.Create("TestDoc.docx", WordprocessingDocumentType.Document))
        {
            // 添加文档主体
            MainDocumentPart mainPart = doc.AddMainDocumentPart();
            mainPart.Document = new Document();
            Body body = mainPart.Document.AppendChild(new Body());

            // 添加编号部分
            NumberingPart numberingPart = mainPart.AddNewPart<NumberingPart>();
            Numbering numbering = new Numbering();
            numberingPart.Numbering = numbering;

            // 错误顺序:先添加NumberingInstance,再添加AbstractNum
            NumberingInstance numInst100 = new NumberingInstance() { NumberID = 100 };
            numInst100.AppendChild(new AbstractNumId() { Val = 200 });
            numbering.AppendChild(numInst100);

            NumberingInstance numInst101 = new NumberingInstance() { NumberID = 101 };
            numInst101.AppendChild(new AbstractNumId() { Val = 201 });
            numbering.AppendChild(numInst101);

            AbstractNum abstractNum200 = new AbstractNum() { AbstractNumberId = 200 };
            abstractNum200.AppendChild(new MultiLevelType() { Val = MultiLevelValues.HybridMultilevel });
            Level level200 = new Level() { LevelIndex = 0 };
            level200.AppendChild(new NumberingFormat() { Val = NumberFormatValues.Decimal });
            level200.AppendChild(new NumberingSymbolRunProperties());
            level200.AppendChild(new StartNumberingValue() { Val = 1 });
            abstractNum200.AppendChild(level200);
            numbering.AppendChild(abstractNum200);

            AbstractNum abstractNum201 = new AbstractNum() { AbstractNumberId = 201 };
            abstractNum201.AppendChild(new MultiLevelType() { Val = MultiLevelValues.HybridMultilevel });
            Level level201 = new Level() { LevelIndex = 0 };
            level201.AppendChild(new NumberingFormat() { Val = NumberFormatValues.Decimal });
            level201.AppendChild(new NumberingSymbolRunProperties());
            level201.AppendChild(new StartNumberingValue() { Val = 1 });
            abstractNum201.AppendChild(level201);
            numbering.AppendChild(abstractNum201);

            // 添加段落并绑定编号
            Paragraph para1 = new Paragraph();
            ParagraphProperties paraProps1 = new ParagraphProperties();
            paraProps1.AppendChild(new NumberingProperties(new NumberingLevelReference() { Val = 0 }, new NumberingId() { Val = 100 }));
            para1.AppendChild(paraProps1);
            para1.AppendChild(new Run(new Text("Top index line A")));
            body.AppendChild(para1);

            Paragraph para2 = new Paragraph();
            ParagraphProperties paraProps2 = new ParagraphProperties();
            paraProps2.AppendChild(new NumberingProperties(new NumberingLevelReference() { Val = 0 }, new NumberingId() { Val = 100 }));
            para2.AppendChild(paraProps2);
            para2.AppendChild(new Run(new Text("Top index line B")));
            body.AppendChild(para2);

            Paragraph para3 = new Paragraph();
            ParagraphProperties paraProps3 = new ParagraphProperties();
            paraProps3.AppendChild(new NumberingProperties(new NumberingLevelReference() { Val = 0 }, new NumberingId() { Val = 101 }));
            para3.AppendChild(paraProps3);
            para3.AppendChild(new Run(new Text("Top index line C")));
            body.AppendChild(para3);
        }
    }
}

排查与解决方法

排查中发现,注释掉自定义AbstractNum的代码时,编号能重置但会丢失自定义格式。最终定位问题:在Open XML的Numbering节点中,AbstractNum对象必须插入在对应的NumberingInstance之前。

调整元素插入顺序,先添加所有AbstractNum,再添加NumberingInstance,即可同时保留自定义格式并实现编号重置:

// 正确顺序:先添加AbstractNum,再添加NumberingInstance
AbstractNum abstractNum200 = new AbstractNum() { AbstractNumberId = 200 };
abstractNum200.AppendChild(new MultiLevelType() { Val = MultiLevelValues.HybridMultilevel });
Level level200 = new Level() { LevelIndex = 0 };
level200.AppendChild(new NumberingFormat() { Val = NumberFormatValues.Decimal });
level200.AppendChild(new NumberingSymbolRunProperties());
level200.AppendChild(new StartNumberingValue() { Val = 1 });
abstractNum200.AppendChild(level200);
numbering.AppendChild(abstractNum200);

AbstractNum abstractNum201 = new AbstractNum() { AbstractNumberId = 201 };
abstractNum201.AppendChild(new MultiLevelType() { Val = MultiLevelValues.HybridMultilevel });
Level level201 = new Level() { LevelIndex = 0 };
level201.AppendChild(new NumberingFormat() { Val = NumberFormatValues.Decimal });
level201.AppendChild(new NumberingSymbolRunProperties());
level201.AppendChild(new StartNumberingValue() { Val = 1 });
abstractNum201.AppendChild(level201);
numbering.AppendChild(abstractNum201);

NumberingInstance numInst100 = new NumberingInstance() { NumberID = 100 };
numInst100.AppendChild(new AbstractNumId() { Val = 200 });
numbering.AppendChild(numInst100);

NumberingInstance numInst101 = new NumberingInstance() { NumberID = 101 };
numInst101.AppendChild(new AbstractNumId() { Val = 201 });
numbering.AppendChild(numInst101);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:38:24