幻灯片上的图形本身不带说明:读屏软件读到矩形或椭圆时,只能报出形状的类型,说明不了这个图形代表什么。为形状补上一段可选文本,相当于给每个图形写一句注解,既方便读屏,也让自动化脚本能凭文字认出目标形状。页数一多,逐个人工补写与核对,费时且容易遗漏。
本文使用 Spire.Presentation for JavaScript 在浏览器中设置与获取 PowerPoint 形状的可选文本。整个处理过程基于 WebAssembly,在用户设备本地完成,无需安装 Office,也不依赖后端服务,演示文稿不必离开浏览器。
本文介绍四个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.Presentation for JavaScript。以下示例默认 Spire.Presentation for JavaScript 已安装、WebAssembly 模块已初始化。
设置 PowerPoint 形状的可选文本
图形只承载视觉信息,读屏软件无法从形状类型推断它的含义。为形状设置可选文本,相当于在形状上附一段说明,朗读时能讲清它代表什么;在需要按内容定位形状的脚本里,这段文字也可以作为稳定的匹配依据。除说明文字外,还可以为形状设置一句更短的标题,二者共同构成形状的说明信息。
| 写法 | 得到的结果 |
|---|---|
slide.Shapes.Count |
当前幻灯片上的形状总数 |
slide.Shapes.get_Item(i) |
按索引取得形状对象 |
shape.AlternativeText = '…' |
为形状设置可选文本 |
shape.AlternativeTitle = '…' |
为形状设置可选文本标题 |
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块并确认已就绪,将字体文件与演示文稿载入 VFS。
- 创建
Presentation对象并调用LoadFromFile()加载演示文稿,再用Slides.get_Item(0)取得第一张幻灯片。 - 从 0 开始遍历
Shapes.Count,用Shapes.get_Item(i)逐个取得幻灯片上的形状。 - 把准备好的说明文字与标题分别赋给形状的
AlternativeText与AlternativeTitle属性。 - 调用
Presentation.SaveToFile()保存结果文件,并用Dispose()释放演示文稿。 - 从 VFS 读出结果文件并触发浏览器下载。
设置 PowerPoint 形状的可选文本的代码如下:
function App() {
const setAlternativeText = async () => {
// 获取 Spire.Presentation WASM 模块
const pptModule = window.wasmModule?.spirepresentation;
// 检查模块是否就绪
if (!pptModule) {
alert('Spire.Presentation is not ready yet');
return;
}
// 将字体与演示文稿载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'AlternativeText.pptx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载演示文稿并取得第一张幻灯片
const ppt = new pptModule.Presentation();
ppt.LoadFromFile(inputFileName);
const slide = ppt.Slides.get_Item(0);
// 依次为四个流程形状设置可选文本与可选文本标题
const labels = ['第一步:计划', '第二步:执行', '第三步:检查', '第四步:改进'];
const titles = ['计划进度', '执行情况', '检查结果', '改进方向'];
for (let i = 0; i < slide.Shapes.Count; i++) {
const shape = slide.Shapes.get_Item(i);
if (i < labels.length) {
shape.AlternativeText = labels[i];
shape.AlternativeTitle = titles[i];
}
}
// 保存结果文件
const outputFileName = 'SetAlternativeText.pptx';
ppt.SaveToFile({ file: outputFileName, fileFormat: pptModule.FileFormat.Pptx2013 });
ppt.Dispose();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' });
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={setAlternativeText}>
设置可选文本
</button>
</div>
);
}
export default App;
为幻灯片上的形状设置可选文本后的演示文稿:

读取 PowerPoint 形状的可选文本
可选文本既可以逐个人工查看,也可以在脚本中批量读出。遍历形状集合、把各形状的可选文本集中到一处,哪些图形已有说明、哪些仍是空白,一眼就能分辨,便于在发布前补齐。
| 写法 | 得到的结果 |
|---|---|
shape.AlternativeText |
读取形状的可选文本,未设置时为空 |
shape.AlternativeTitle |
读取形状的可选文本标题,未设置时为空 |
new TextEncoder().encode(text) |
把文本编码为字节,供写入文件 |
window.dotnetRuntime.Module.FS.writeFile(fileName, bytes) |
把字节写入 VFS 中的文件 |
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块并确认已就绪,将演示文稿载入 VFS。
- 创建
Presentation对象并调用LoadFromFile()加载演示文稿,再用Slides.get_Item(1)取得存放形状的第二张幻灯片。 - 遍历
Shapes.Count,用Shapes.get_Item(i)取得形状并读取AlternativeText与AlternativeTitle,非空的值逐个收集起来。 - 把收集到的文本按行拼接,用
TextEncoder编码为字节,再调用FS.writeFile()写入GetAlternativeText.txt。 - 调用
Dispose()释放演示文稿,随后从 VFS 读出文本文件并触发下载。
读取 PowerPoint 形状的可选文本的代码如下:
function App() {
const getAlternativeText = async () => {
// 获取 Spire.Presentation WASM 模块
const pptModule = window.wasmModule?.spirepresentation;
if (!pptModule) {
alert('Spire.Presentation is not ready yet');
return;
}
const inputFileName = 'AlternativeText.pptx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载演示文稿并取得第二张幻灯片
const ppt = new pptModule.Presentation();
ppt.LoadFromFile(inputFileName);
const slide = ppt.Slides.get_Item(1);
// 逐个读取形状的可选文本,跳过没有设置可选文本的形状
const lines = [];
for (let i = 0; i < slide.Shapes.Count; i++) {
const shape = slide.Shapes.get_Item(i);
if (shape.AlternativeText) {
const title = shape.AlternativeTitle ? `(标题:${shape.AlternativeTitle})` : '';
lines.push(`形状 ${i + 1}:${shape.AlternativeText}${title}`);
}
}
// 把读取结果写入文本文件
const outputFileName = 'GetAlternativeText.txt';
window.dotnetRuntime.Module.FS.writeFile(outputFileName, new TextEncoder().encode(lines.join('\n')));
ppt.Dispose();
// 从 VFS 读取生成的文本文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'text/plain;charset=utf-8' });
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={getAlternativeText}>
读取可选文本
</button>
</div>
);
}
export default App;
读取各形状可选文本后生成的文本文件:

按可选文本查找 PowerPoint 形状
形状在集合中的顺序会随增删而变化,按索引定位并不稳妥。当形状带有可选文本时,可以按这段说明文字检索,把目标形状从集合中找出来,再进行后续处理,例如更换填充与轮廓,以提示需要核对的位置。
| 写法 | 得到的结果 |
|---|---|
slide.Shapes.get_Item(i) |
按索引取得形状 |
shape.AlternativeText === target |
判断形状的可选文本是否与目标值一致 |
shape.Fill.FillType 与 Fill.SolidColor.Color |
修改找到的形状的填充 |
shape.Line.Width 与 Line.SolidFillColor.Color |
修改找到的形状的轮廓 |
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块并确认已就绪,将字体文件与演示文稿载入 VFS。
- 创建
Presentation对象并调用LoadFromFile()加载演示文稿,再用Slides.get_Item(2)取得第三张幻灯片。 - 从 0 开始遍历
Shapes.Count,用Shapes.get_Item(i)取得形状,比较AlternativeText与目标文字,命中后记下该形状并跳出循环。 - 把找到的形状的
Fill.FillType设为FillFormatType.Solid,用Fill.SolidColor.Color更换填充色;再把Line.FillType设为实线,用Line.Width与Line.SolidFillColor.Color调整轮廓。 - 调用
Presentation.SaveToFile()保存结果文件,并用Dispose()释放演示文稿,随后从 VFS 读出文件并触发下载。
按可选文本查找 PowerPoint 形状的代码如下:
function App() {
const findShapeByAlternativeText = async () => {
// 获取 Spire.Presentation WASM 模块
const pptModule = window.wasmModule?.spirepresentation;
if (!pptModule) {
alert('Spire.Presentation is not ready yet');
return;
}
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'AlternativeText.pptx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载演示文稿并取得第三张幻灯片
const ppt = new pptModule.Presentation();
ppt.LoadFromFile(inputFileName);
const slide = ppt.Slides.get_Item(2);
// 按可选文本找到品牌标识形状
const target = '品牌标识';
let found = null;
for (let i = 0; i < slide.Shapes.Count; i++) {
const shape = slide.Shapes.get_Item(i);
if (shape.AlternativeText === target) {
found = shape;
break;
}
}
// 为找到的形状更换填充与轮廓,便于确认定位结果
if (found) {
found.Fill.FillType = pptModule.FillFormatType.Solid;
found.Fill.SolidColor.Color = pptModule.Color.get_Purple();
found.Line.FillType = pptModule.FillFormatType.Solid;
found.Line.Width = 4;
found.Line.SolidFillColor.Color = pptModule.Color.get_LightGray();
}
// 保存结果文件
const outputFileName = 'FindShapeByAlternativeText.pptx';
ppt.SaveToFile({ file: outputFileName, fileFormat: pptModule.FileFormat.Pptx2013 });
ppt.Dispose();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' });
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={findShapeByAlternativeText}>
按可选文本查找
</button>
</div>
);
}
export default App;
按可选文本定位并标记目标形状后的演示文稿:

读取组合形状内的可选文本
组合形状把多个图形收拢为一个整体,组内各图形仍各自保留可选文本。直接读取外层组合上的属性取不到这些说明,需要进入组合的形状集合逐个读取,才能完整收集组内的文字。
| 写法 | 得到的结果 |
|---|---|
shape instanceof pptModule.GroupShape |
判断形状是否为组合形状 |
shape.Shapes.Count |
组合内形状的数量 |
shape.Shapes.get_Item(j) |
取得组合内的第 j 个形状 |
shape.Shapes.get_Item(j).AlternativeText |
读取组合内形状的可选文本 |
shape.Shapes.get_Item(j).AlternativeTitle |
读取组合内形状的可选文本标题 |
new TextEncoder().encode(text) |
把汇总的文本编码为字节 |
window.dotnetRuntime.Module.FS.writeFile(fileName, bytes) |
把汇总结果写入 VFS 中的文本文件 |
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块并确认已就绪,将演示文稿载入 VFS。
- 创建
Presentation对象并调用LoadFromFile()加载演示文稿,再用Slides.get_Item(3)取得第四张幻灯片。 - 从 0 开始遍历
Shapes.Count,用Shapes.get_Item(i)取得形状,并以shape instanceof pptModule.GroupShape判断它是否为组合。 - 在组合内部从 0 遍历
shape.Shapes.Count,用shape.Shapes.get_Item(j)取得子形状并读取其AlternativeText与AlternativeTitle。 - 把收集到的文本按行拼接,用
TextEncoder编码为字节,再调用FS.writeFile()写入GetGroupAlternativeText.txt。 - 调用
Dispose()释放演示文稿,随后从 VFS 读出文本文件并触发下载。
读取组合形状内的可选文本的代码如下:
function App() {
const getGroupAlternativeText = async () => {
// 获取 Spire.Presentation WASM 模块
const pptModule = window.wasmModule?.spirepresentation;
if (!pptModule) {
alert('Spire.Presentation is not ready yet');
return;
}
const inputFileName = 'AlternativeText.pptx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载演示文稿并取得第四张幻灯片
const ppt = new pptModule.Presentation();
ppt.LoadFromFile(inputFileName);
const slide = ppt.Slides.get_Item(3);
// 找到组合形状,逐个读取其内部形状的可选文本
const lines = [];
for (let i = 0; i < slide.Shapes.Count; i++) {
const shape = slide.Shapes.get_Item(i);
if (shape instanceof pptModule.GroupShape) {
for (let j = 0; j < shape.Shapes.Count; j++) {
const child = shape.Shapes.get_Item(j);
const title = child.AlternativeTitle ? `(标题:${child.AlternativeTitle})` : '';
lines.push(`组合内形状 ${j + 1}:${child.AlternativeText}${title}`);
}
}
}
// 把读取结果写入文本文件
const outputFileName = 'GetGroupAlternativeText.txt';
window.dotnetRuntime.Module.FS.writeFile(outputFileName, new TextEncoder().encode(lines.join('\n')));
ppt.Dispose();
// 从 VFS 读取生成的文本文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'text/plain;charset=utf-8' });
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={getGroupAlternativeText}>
读取组合内可选文本
</button>
</div>
);
}
export default App;
读取组合内各形状可选文本后生成的文本文件:

常见问题
可选文本与形状名称有什么区别
解决:AlternativeText 是给屏幕阅读器和检索用的说明文字,对应 PowerPoint 中的「替代文字」;Name 是形状在文件中的内部名称,主要用于程序引用。二者互不影响,修改其中一个不会改变另一个。
可选文本标题与可选文本有什么区别
解决:AlternativeText 是一段完整说明,读屏时会逐句朗读;AlternativeTitle 是一句更短的标题,用于快速概括形状。二者分别存放在形状的两个不同属性中,读写互不影响,可以只设置其中一项,也可以两项同时设置。
隐藏的形状还能读取可选文本吗
原因:隐藏只改变显示状态,形状本身仍保留在幻灯片中。
解决:把 IsHidden 设为 true 后,形状仍在 Shapes 集合里,AlternativeText 与 AlternativeTitle 均可照常读取;隐藏状态随文件保存,重新显示后说明文字保持不变。
组合形状本身能设置可选文本吗
原因:组合本身也是形状的一种,组内形状的说明则各自挂在子形状上。
解决:可以直接对 GroupShape 的 AlternativeText 与 AlternativeTitle 赋值;组内各形状仍通过 group.Shapes 逐个读写,两层互不影响。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







