段落是 Word 排版的基准单位。文档里的每一个段落都挂着两个格式对象:Paragraph.Format 管段落自身的排版——边框、对齐方式、底纹、缩进、段前段后间距与行距;Paragraph.ListFormat 管它作为列表项时的编号与项目符号。两者互相独立,同一个段落可以既有居中缩进,又是三级编号列表中的一项。Spire.Doc for JavaScript 基于 WebAssembly 在浏览器端直接操作这两个对象。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.Doc for JavaScript 的方法。以下示例默认已安装 Spire.Doc 并完成 WebAssembly 模块初始化。
设置段落格式
段落格式通过 paragraph.Format 设置。下面的示例把边框、五种对齐方式、底纹、三类缩进和间距规则各演示一遍:
function App() {
const ParagraphFormatting = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) {
alert('Spire.Doc is not ready yet');
return;
}
// 创建文档与节
let doc = new docModule.Document();
let sec = doc.AddSection();
// 标题
let para = sec.AddParagraph();
para.AppendText("段落格式一览");
para.ApplyStyle({ builtinStyle: docModule.BuiltinStyle.Title });
// 段落边框
para = sec.AddParagraph();
para.AppendText("这个段落带有红色边框。");
para.Format.Borders.BorderType = docModule.BorderStyle.Single;
para.Format.Borders.Color = docModule.Color.get_Red();
// 五种水平对齐:左、居中、右、两端、分散
para = sec.AddParagraph();
para.AppendText("这个段落左对齐。");
para.Format.HorizontalAlignment = docModule.HorizontalAlignment.Left;
para = sec.AddParagraph();
para.AppendText("这个段落居中对齐。");
para.Format.HorizontalAlignment = docModule.HorizontalAlignment.Center;
para = sec.AddParagraph();
para.AppendText("这个段落右对齐。");
para.Format.HorizontalAlignment = docModule.HorizontalAlignment.Right;
para = sec.AddParagraph();
para.AppendText("这个段落两端对齐。");
para.Format.HorizontalAlignment = docModule.HorizontalAlignment.Justify;
para = sec.AddParagraph();
para.AppendText("这个段落分散对齐。");
para.Format.HorizontalAlignment = docModule.HorizontalAlignment.Distribute;
// 段落底纹
para = sec.AddParagraph();
para.AppendText("这个段落带灰色底纹。");
para.Format.BackColor = docModule.Color.get_Gray();
// 左缩进 10 磅、右缩进 10 磅、首行缩进 15 磅
para = sec.AddParagraph();
para.AppendText("这个段落左缩进 10 磅、右缩进 10 磅、首行缩进 15 磅。");
para.Format.SetLeftIndent(10);
para.Format.SetRightIndent(10);
para.Format.SetFirstLineIndent(15);
// 首行缩进传负值即为悬挂缩进
para = sec.AddParagraph();
para.AppendText("这个段落的悬挂缩进为 15 磅。");
para.Format.SetFirstLineIndent(-15);
// 段前 10 磅、段后 20 磅、行距至少 10 磅
para = sec.AddParagraph();
para.AppendText("这个段落段前 10 磅、段后 20 磅、行距至少 10 磅。");
para.Format.AfterSpacing = 20;
para.Format.BeforeSpacing = 10;
para.Format.LineSpacingRule = docModule.LineSpacingRule.AtLeast;
para.Format.LineSpacing = 10;
// 定义输出文件名
const outputFileName = "ParagraphFormatting-result.docx";
// 保存文档到指定路径
doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });
// 释放资源
doc.Dispose();
// 读取保存的文件并转换为 Blob 对象
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], {type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>设置各类段落格式</h1>
<button onClick={ParagraphFormatting}>开始</button>
</div>
);
}
export default App;
生成的文件中,各段落分别呈现出边框、不同对齐方式与缩进间距效果

创建列表样式并应用到段落
列表样式属于文档样式的一种,通过 document.Styles.Add({ listType, name }) 新建。listType 取 ListType.Numbered(编号)或 ListType.Bulleted(项目符号),name 是自定义的样式名。
新建之后还要配置各级别的编号规则,这些参数位于 ListRef.Levels 中,下标从 0 开始:
NumberPrefix—— 编号的前缀模板,%1代表第 1 级的序号,%2代表第 2 级,依此类推;PatternType—— 编号的呈现格式,如ListPatternType.Arabic是阿拉伯数字;- 段落侧则用
ListFormat.ApplyStyle(样式名)挂上列表样式,再用ListFormat.ListLevelNumber指定所在层级(0 为第一级)。
function App() {
const Lists = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) {
alert('Spire.Doc is not ready yet');
return;
}
// 创建文档与节
const doc = new docModule.Document();
let sec = doc.AddSection();
// 标题与分组小标题
let paragraph = sec.AddParagraph();
paragraph.AppendText("列表样式一览");
paragraph.ApplyStyle({ builtinStyle: docModule.BuiltinStyle.Title });
paragraph = sec.AddParagraph();
paragraph.AppendText("编号列表:").CharacterFormat.Bold = true;
// 新建编号列表样式,配置第 1、2 级的编号格式
let numberList = doc.Styles.Add({ listType: docModule.ListType.Numbered, name: "numberList" });
numberList.ListRef.Levels.get_Item(1).NumberPrefix = "%1.";
numberList.ListRef.Levels.get_Item(1).PatternType = docModule.ListPatternType.Arabic;
numberList.ListRef.Levels.get_Item(2).NumberPrefix = "%1.%2.";
numberList.ListRef.Levels.get_Item(2).PatternType = docModule.ListPatternType.Arabic;
// 新建项目符号列表样式
let bulletList = doc.Styles.Add({ listType: docModule.ListType.Bulleted, name: "bulletList" });
// 将两个列表样式加入文档样式集合
doc.Styles.Add(numberList);
doc.Styles.Add(bulletList);
// 逐段应用编号列表样式,并用 ListLevelNumber 指定层级
paragraph = sec.AddParagraph();
paragraph.AppendText("概要说明");
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph = sec.AddParagraph();
paragraph.AppendText("交付范围");
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph = sec.AddParagraph();
paragraph.AppendText("三个业务板块");
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph.ListFormat.ListLevelNumber = 1;
paragraph = sec.AddParagraph();
paragraph.AppendText("数据接入");
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph.ListFormat.ListLevelNumber = 1;
paragraph = sec.AddParagraph();
paragraph.AppendText("接口联调");
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph.ListFormat.ListLevelNumber = 2;
paragraph = sec.AddParagraph();
paragraph.AppendText("字段核对");
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph.ListFormat.ListLevelNumber = 2;
paragraph = sec.AddParagraph();
paragraph.AppendText("灰度发布");
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph.ListFormat.ListLevelNumber = 2;
paragraph = sec.AddParagraph();
paragraph.AppendText("验收标准");
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph.ListFormat.ListLevelNumber = 1;
paragraph = sec.AddParagraph();
paragraph.AppendText("后续安排");
paragraph.ListFormat.ApplyStyle(numberList.Name);
// 项目符号列表
paragraph = sec.AddParagraph();
paragraph.AppendText("项目符号列表:").CharacterFormat.Bold = true;
paragraph = sec.AddParagraph();
paragraph.AppendText("条款一");
paragraph.ListFormat.ApplyStyle(bulletList.Name);
paragraph = sec.AddParagraph();
paragraph.AppendText("条款二");
paragraph.ListFormat.ApplyStyle(bulletList.Name);
paragraph = sec.AddParagraph();
paragraph.AppendText("补充说明");
paragraph.ListFormat.ApplyStyle(bulletList.Name);
paragraph.ListFormat.ListLevelNumber = 1;
paragraph = sec.AddParagraph();
paragraph.AppendText("例外情形");
paragraph.ListFormat.ApplyStyle(bulletList.Name);
paragraph.ListFormat.ListLevelNumber = 1;
paragraph = sec.AddParagraph();
paragraph.AppendText("条款三");
paragraph.ListFormat.ApplyStyle(bulletList.Name);
// 定义输出文件名
const outputFileName = "Lists-result.docx";
// 保存文档到指定路径
doc.SaveToFile({ fileName: outputFileName, fileFormat: docModule.FileFormat.Docx2013 });
doc.Dispose();
// 读取保存的文件并转换为 Blob 对象
const modifiedFileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([modifiedFileArray], {type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>创建列表样式并应用到段落</h1>
<button onClick={Lists}>开始</button>
</div>
);
}
export default App;
编号列表按层级自动生成 1. / 1.1. 形式的序号,项目符号列表则按层级缩进

常见问题
悬挂缩进设置后没有生效
原因:SetFirstLineIndent 传入负值表示悬挂缩进,但如果段落本身没有左缩进,悬挂部分没有可回退的空间,视觉上几乎看不出来。
解决:先给段落设置左缩进,再用负的首行缩进实现悬挂效果:
para.Format.SetLeftIndent(20);
para.Format.SetFirstLineIndent(-15);
列表编号没有按预期层级显示
原因:ListLevelNumber 未设置时默认为 0(第一级),子级段落若不显式指定层级,就会与父级并列编号。
解决:每设定一个层级都要显式赋值,注意它同样从 0 开始计数:
paragraph.ListFormat.ApplyStyle(numberList.Name);
paragraph.ListFormat.ListLevelNumber = 1; // 第二级,编号形如 1.1.
段落同时设置了底纹与边框,但只显示了一种
原因:Format.BackColor 是段落底纹,Format.Borders 是段落边框,两者写在同一个段落属性节点下,属性名拼写错误时会被静默忽略。
解决:分别确认属性归属——底纹用 BackColor,边框用 Borders.BorderType:
para.Format.BackColor = docModule.Color.get_Gray();
para.Format.Borders.BorderType = docModule.BorderStyle.Single;
para.Format.Borders.Color = docModule.Color.get_Red();
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







