Open XML生成Word文档时编号无法重置的问题求助
Open XML生成Word文档编号无法重置的解决方案
我在用Open XML创建Word文档时,遇到了编号无法重置的问题:
期望的编号效果:
- Top index line A
- Top index line B
- Top index line C
但实际生成的编号是持续递增的:
- Top index line A
- Top index line B
- 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
相关产品推荐
相关产品推荐

