字符格式决定了文字在页面上「长什么样」——用哪种字体、多大字号、什么颜色,以及是否加粗、倾斜、带下划线或删除线。在 Word 的开放 XML 结构里,这些属性都挂在**文本块(run)**上,而不是段落上;一段话里每个 run 都可以有自己的一套格式。Spire.Doc for JavaScript 把这套结构映射为 TextRange.CharacterFormat 对象,基于 WebAssembly 在浏览器端直接读写,无需后端服务。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.Doc for JavaScript 的方法。以下示例默认已安装 Spire.Doc 并完成 WebAssembly 模块初始化。
设置字符格式
Document.AddSection() 新建节之后调用 section.AddParagraph() 得到段落,再调用 paragraph.AppendText() 追加文字——AppendText 的返回值就是一个 TextRange 对象,拿到它就能直接设置 CharacterFormat。要换行但不换段,调用 paragraph.AppendBreak(wasmModule.BreakType.LineBreak) 即可。
下面的示例把常用的字符格式逐个演示一遍,每一行文字只改一项属性,便于对照观察效果:
function App() {
const CharacterFormatting = 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 titleParagraph = sec.AddParagraph();
titleParagraph.AppendText("字符格式一览");
titleParagraph.ApplyStyle({ builtinStyle: docModule.BuiltinStyle.Title });
let paragraph = sec.AddParagraph();
// 删除线
let tr = paragraph.AppendText("Strikethough Text");
tr.CharacterFormat.IsStrikeout = true;
// 阴影
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Shadow Text");
tr.CharacterFormat.IsShadow = true;
// 小型大写字母
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Small caps Text");
tr.CharacterFormat.IsSmallCaps = true;
// 双删除线
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Double Strikethough Text");
tr.CharacterFormat.DoubleStrike = true;
// 空心字
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Outline Text");
tr.CharacterFormat.IsOutLine = true;
// 全部大写
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("AllCaps Text");
tr.CharacterFormat.AllCaps = true;
// 下标与上标
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Text");
tr = paragraph.AppendText("SubScript");
tr.CharacterFormat.SubSuperScript = docModule.SubSuperScript.SubScript;
tr = paragraph.AppendText("And");
tr = paragraph.AppendText("SuperScript");
tr.CharacterFormat.SubSuperScript = docModule.SubSuperScript.SuperScript;
// 阳文(凸起),白色字色让效果更明显
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Emboss Text");
tr.CharacterFormat.Emboss = true;
tr.CharacterFormat.TextColor = docModule.Color.get_White();
// 隐藏文字
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Hidden:");
tr = paragraph.AppendText("Hidden Text");
tr.CharacterFormat.Hidden = true;
// 阴文(凹陷)
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Engrave Text");
tr.CharacterFormat.Engrave = true;
tr.CharacterFormat.TextColor = docModule.Color.get_White();
// 西文 / 非远东 / 远东三种字体名分开设置
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("WesternFonts中文字体");
tr.CharacterFormat.FontNameAscii = "Calibri";
tr.CharacterFormat.FontNameNonFarEast = "Calibri";
tr.CharacterFormat.FontNameFarEast = "Simsun";
// 字号
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Font Size");
tr.CharacterFormat.FontSize = 20;
// 字色
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Font Color");
tr.CharacterFormat.TextColor = docModule.Color.get_Red();
// 加粗 + 斜体
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Bold Italic Text");
tr.CharacterFormat.Bold = true;
tr.CharacterFormat.Italic = true;
// 下划线
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Underline Style");
tr.CharacterFormat.UnderlineStyle = docModule.UnderlineStyle.Single;
// 突出显示(背景高亮)
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Highlight Text");
tr.CharacterFormat.HighlightColor = docModule.Color.get_Yellow();
// 字符底纹
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Text has shading");
tr.CharacterFormat.TextBackgroundColor = docModule.Color.get_Green();
// 字符边框
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Border Around Text");
tr.CharacterFormat.Border.BorderType = docModule.BorderStyle.Single;
// 字符缩放 150%
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Text Scale");
tr.CharacterFormat.TextScale = 150;
// 字符间距 2 磅
paragraph.AppendBreak(docModule.BreakType.LineBreak);
tr = paragraph.AppendText("Character Spacing is 2 point");
tr.CharacterFormat.CharacterSpacing = 2;
// 定义输出文件名
const outputFileName = "CharacterFormatting-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={CharacterFormatting}>开始</button>
</div>
);
}
export default App;
生成的文件中,每一行文字都呈现出对应的字符效果,可逐行与代码对照

在同一个段落中应用多种字符格式
一个段落可以包含多个 TextRange,每个 TextRange 都有独立的 CharacterFormat。这意味着「前半句加粗蓝色、后半句常规字号」这类排版不需要拆成两个段落——连续调用 AppendText 即可,格式只作用于当前这一次追加的文本。
function App() {
const MultiStylesInAParagraph = async () => {
const docModule = window.wasmModule?.spiredoc;
if (!docModule) {
alert('Spire.Doc is not ready yet');
return;
}
// 创建文档与节
let doc = new docModule.Document();
let section = doc.AddSection();
// 新建一个段落
let para = section.AddParagraph();
// 第一个 TextRange:Calibri 16 磅、蓝色、加粗、单下划线
let range = para.AppendText("季度交付说明 ");
range.CharacterFormat.FontName = "Calibri";
range.CharacterFormat.FontSize = 16;
range.CharacterFormat.TextColor = docModule.Color.get_Blue();
range.CharacterFormat.Bold = true;
range.CharacterFormat.UnderlineStyle = docModule.UnderlineStyle.Single;
// 第二个 TextRange:同一个段落内,换成 Calibri 15 磅常规字
range = para.AppendText("本次交付覆盖三个业务板块,验收以线上试运行结果为准");
range.CharacterFormat.FontName = "Calibri";
range.CharacterFormat.FontSize = 15;
// 定义输出文件名
const outputFileName = "MultiStylesInAParagraph-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={MultiStylesInAParagraph}>开始</button>
</div>
);
}
export default App;
段落中前半句为加粗蓝色下划线样式,后半句恢复为常规字重

常见问题
设置了 FontName,但中文部分没有变化
原因:CharacterFormat.FontName 在部分场景下只写入西文(ascii/hAnsi)字体槽位,中文字符走的是「东亚字体」槽位,两者是分开存储的。
解决:需要分别指定中英文使用的字体,FontNameAscii / FontNameNonFarEast 管西文,FontNameFarEast 管中文:
tr.CharacterFormat.FontNameAscii = "Calibri";
tr.CharacterFormat.FontNameNonFarEast = "Calibri";
tr.CharacterFormat.FontNameFarEast = "Simsun";
阳文(Emboss)和阴文(Engrave)看不出效果
原因:这两种效果依赖明暗对比,默认的黑色文字在白色背景上几乎没有视觉差异。
解决:把字色设为白色,让文字只靠高光与阴影成形:
tr.CharacterFormat.Emboss = true;
tr.CharacterFormat.TextColor = wasmModule.Color.get_White();
下载的 Word 文档无法打开或提示损坏
原因:创建 Blob 时 MIME 类型设置错误,浏览器无法正确识别文件格式。
解决:确保使用准确的 docx MIME 类型:
const modifiedFile = new Blob([modifiedFileArray], {
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。









