# Word 创建项目符号

## 概述

本文介绍如何使用 aardio 通过 NPOI 库创建带有项目符号列表的 Word 文档（.docx 格式）。我们将演示如何创建单级和多级项目符号列表。

## 基础用法

### 1. 创建文档和编号样式

```aardio
import NPOI.XWPF.UserModel;

// 创建新的 Word 文档
var doc = NPOI.XWPF.UserModel.XWPFDocument();

// 创建编号样式
var numbering = doc.CreateNumbering();

// 添加抽象编号和实际编号
var abstractNumId = numbering.AddAbstractNum();
var numId = numbering.AddNum(abstractNumId);
```

### 2. 添加带项目符号的段落

```aardio
// 创建第一个段落（标题）
var p0 = doc.CreateParagraph();
var r0 = p0.CreateRun();
r0.SetText("简单项目符号");
r0.IsBold = true;
r0.FontFamily = "Courier";
r0.FontSize = 12;

// 创建带项目符号的段落1
var p1 = doc.CreateParagraph();
var r1 = p1.CreateRun();
r1.SetText("第一步，创建段落和运行对象，设置文本");
p1.SetNumID(numId);

// 创建带项目符号的段落2
var p2 = doc.CreateParagraph();
var r2 = p2.CreateRun();
r2.SetText("第二步，调用 XWPFDocument.CreateNumbering() 创建编号样式");
p2.SetNumID(numId);

// 创建带项目符号的段落3
var p3 = doc.CreateParagraph();
var r3 = p3.CreateRun();
r3.SetText("第三步，添加 AbstractNum[numbering.AddAbstractNum()] 和 Num(numbering.AddNum(abstractNumId))");
p3.SetNumID(numId);

// 创建带项目符号的段落4
var p4 = doc.CreateParagraph();
var r4 = p4.CreateRun();
r4.SetText("最后，调用 XWPFParagraph.SetNumID(numId) 设置段落属性，CT_P.pPr.numPr");
p4.SetNumID(numId);
```

## 多级项目符号

```aardio
// 创建多级项目符号
abstractNumId = numbering.AddAbstractNum();
numId = numbering.AddNum(abstractNumId);

// 添加两个空段落
doc.CreateParagraph();
doc.CreateParagraph();

// 添加多级项目符号标题
var p1 = doc.CreateParagraph();
var r1 = p1.CreateRun();
r1.SetText("多级项目符号");
r1.IsBold = true;
r1.FontFamily = "Courier";
r1.FontSize = 12;

// 第一级
p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第一级");
p1.SetNumID(numId, "0");

// 第二级
p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第一级的第一个子项");
p1.SetNumID(numId, "1");

p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第一级的第二个子项");
p1.SetNumID(numId, "1");

p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第一级的第三个子项");
p1.SetNumID(numId, "1");

// 返回第一级
p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第二级");
p1.SetNumID(numId, "0");

// 第二级
p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第二级的第一个子项");
p1.SetNumID(numId, "1");

p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第二级的第二个子项");
p1.SetNumID(numId, "1");

// 第三级
p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第二级的第三个子项的第一个子项");
p1.SetNumID(numId, "2");

p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第二级的第三个子项的第二个子项");
p1.SetNumID(numId, "2");

// 返回第一级
p1 = doc.CreateParagraph();
r1 = p1.CreateRun();
r1.SetText("第三级");
p1.SetNumID(numId, "0");
```

## 保存文档

```aardio
// 保存文档到文件
import System.IO;
var fs = System.IO.FileStream("sample.docx", System.IO.FileMode.Create);
doc.Write(fs);
fs.Close();
```

## 关键点说明

1. **编号系统**：
   - `AddAbstractNum()` 创建抽象的编号定义
   - `AddNum()` 基于抽象定义创建具体编号实例
   - `SetNumID()` 将编号应用到段落

2. **多级编号**：
   - 通过 `SetNumID()` 的第二个参数指定级别（"0"为第一级，"1"为第二级，以此类推）

3. **文本样式**：
   - 通过 `XWPFRun` 对象设置字体、加粗、大小等样式
   - 段落和文本内容需要分别创建

4. **文件保存**：
   - 使用 `FileStream` 将文档写入文件
   - 完成后需要手动关闭文件流

这个示例展示了 NPOI 创建 Word 文档项目符号列表的基本方法，可以根据需要调整样式和层级结构。