同一份演示文稿,面对不同场合往往要增减页数:给客户讲时临时补两页案例,上一版讲完又摘掉过时的内容。在桌面软件里靠手工拖拽,需要有人守着操作,也难接入批量处理的 Web 流程;放到服务端做,文件一旦上传,就离开了用户的设备。
本文用 Spire.Presentation for JavaScript 在浏览器中直接添加、删除 PowerPoint 幻灯片。整个过程基于 WebAssembly 在浏览器端完成,无需安装 Office,也不依赖任何后端,文件始终留在用户的设备上。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.Presentation for JavaScript。下面的示例假定 Spire.Presentation 已安装、WebAssembly 模块已初始化。
在末尾添加 PowerPoint 幻灯片
Spire.Presentation for JavaScript 通过 Slides.Append() 方法在演示文稿末尾添加一张新的幻灯片。追加进来的内容取决于传入的参数:
| 写法 | 追加的内容 |
|---|---|
Slides.Append() |
一张默认(空白)版式的新幻灯片 |
Slides.Append({ template: 版式对象 }) |
按指定版式新建的幻灯片 |
Slides.Append({ slide }) |
已有幻灯片的一份副本 |
要按指定版式新建,先取到「版式对象」:ppt.Masters.get_Item(0).Layouts.get_Item(i),即第 1 个主版式下的第 i 个版式(i 从 0 起)。
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块,确认已就绪。
- 读入示例演示文稿与字体,创建
Presentation对象并加载该文件。 - 使用
Presentation.Slides.Append()方法在末尾添加幻灯片(可传入template或slide指定内容)。 - 使用
Presentation.SaveToFile()方法保存结果文件。 - 从 VFS 读出结果文件并触发浏览器下载。
添加 PowerPoint 幻灯片的代码如下:
function App() {
const addSlides = async () => {
// 获取 Spire.Presentation WASM 模块
const pptModule = window.wasmModule?.spirepresentation;
// 检查模块是否就绪
if (!pptModule) {
alert('Spire.Presentation is not ready yet');
return;
}
// 载入示例演示文稿与字体
await window.spire.FetchFileToVFS('示例演示文稿.pptx', "", `${process.env.PUBLIC_URL}/data/`);
await window.spire.FetchFileToVFS('ARIALUNI.TTF', "/Library/Fonts/", `${process.env.PUBLIC_URL}/font/`);
// 创建 Presentation 实例并加载演示文稿
const ppt = new pptModule.Presentation();
ppt.LoadFromFile('示例演示文稿.pptx');
// 依次追加:默认版式、指定版式、克隆第一张幻灯片
ppt.Slides.Append();
ppt.Slides.Append({ template: ppt.Masters.get_Item(0).Layouts.get_Item(1) });
ppt.Slides.Append({ slide: ppt.Slides.get_Item(0) });
// 保存结果文件
const outputFileName = '添加幻灯片后.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>添加 PowerPoint 幻灯片</h1>
<button onClick={addSlides}>
添加幻灯片
</button>
</div>
);
}
export default App;
在末尾追加三张幻灯片后的演示文稿:

在指定位置插入 PowerPoint 幻灯片
Slides.Insert() 用 index 指定插入位置:新幻灯片插在该索引处,其后的幻灯片依次后移。插入什么内容由传入的参数决定:
| 写法 | 插入的内容 |
|---|---|
Slides.Insert({ index, template: 版式对象 }) |
按指定版式新建并插入到 index 处 |
Slides.Insert({ index, slide }) |
已有幻灯片的一份副本插入到 index 处 |
其中「版式对象」的取法与 Slides.Append() 相同。
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块,确认已就绪。
- 读入示例演示文稿与字体,创建
Presentation对象并加载该文件。 - 使用
Presentation.Slides.Insert()方法在指定位置插入幻灯片。 - 使用
Presentation.SaveToFile()方法保存结果文件。 - 从 VFS 读出结果文件并触发浏览器下载。
插入 PowerPoint 幻灯片的代码如下:
function App() {
const insertSlides = async () => {
// 获取 Spire.Presentation WASM 模块
const pptModule = window.wasmModule?.spirepresentation;
// 检查模块是否就绪
if (!pptModule) {
alert('Spire.Presentation is not ready yet');
return;
}
// 载入示例演示文稿与字体
await window.spire.FetchFileToVFS('示例演示文稿.pptx', "", `${process.env.PUBLIC_URL}/data/`);
await window.spire.FetchFileToVFS('ARIALUNI.TTF', "/Library/Fonts/", `${process.env.PUBLIC_URL}/font/`);
// 创建 Presentation 实例并加载演示文稿
const ppt = new pptModule.Presentation();
ppt.LoadFromFile('示例演示文稿.pptx');
// 依次插入:指定版式、克隆第一张幻灯片
ppt.Slides.Insert({ index: 1, template: ppt.Masters.get_Item(0).Layouts.get_Item(1) });
ppt.Slides.Insert({ index: 2, slide: ppt.Slides.get_Item(0) });
// 保存结果文件
const outputFileName = '插入幻灯片后.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>插入 PowerPoint 幻灯片</h1>
<button onClick={insertSlides}>
插入幻灯片
</button>
</div>
);
}
export default App;
在中间插入三张幻灯片后的演示文稿:

删除 PowerPoint 幻灯片
Spire.Presentation for JavaScript 也支持删除幻灯片,可以用 Slides.RemoveAt() 或 Slides.Remove()。两者定位幻灯片的方式不同:
| 方法 | 依据 |
|---|---|
Slides.RemoveAt(index) |
幻灯片的位置(0 基索引) |
Slides.Remove(slide) |
幻灯片对象本身 |
每删掉一张,其后幻灯片的索引都会前移一位。
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块,确认已就绪。
- 读入示例演示文稿与字体,创建
Presentation对象并加载该文件。 - 使用
Presentation.Slides.RemoveAt()方法按照索引删除幻灯片。 - 使用
Presentation.SaveToFile()方法保存结果文件。 - 从 VFS 读出结果文件并触发浏览器下载。
删除 PowerPoint 幻灯片的代码如下:
function App() {
const removeSlides = async () => {
// 获取 Spire.Presentation WASM 模块
const pptModule = window.wasmModule?.spirepresentation;
// 检查模块是否就绪
if (!pptModule) {
alert('Spire.Presentation is not ready yet');
return;
}
// 载入示例演示文稿与字体
await window.spire.FetchFileToVFS('示例演示文稿.pptx', "", `${process.env.PUBLIC_URL}/data/`);
await window.spire.FetchFileToVFS('ARIALUNI.TTF', "/Library/Fonts/", `${process.env.PUBLIC_URL}/font/`);
// 创建 Presentation 实例并加载演示文稿
const ppt = new pptModule.Presentation();
ppt.LoadFromFile('示例演示文稿.pptx');
// RemoveAt 按索引删除:删掉第 1 张后,其后幻灯片索引整体前移
ppt.Slides.RemoveAt(0);
// 保存结果文件
const outputFileName = '删除幻灯片后.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>删除 PowerPoint 幻灯片</h1>
<button onClick={removeSlides}>
删除幻灯片
</button>
</div>
);
}
export default App;
删掉幻灯片后的演示文稿:

按对象删除幻灯片
上面介绍的 Slides.RemoveAt() 是按索引删除,Slides.Remove() 则直接接收一张幻灯片对象。要指向某一页时,先用 Slides.get_Item(index) 把该页取出来,再交给 Slides.Remove() 删除:
// 按对象删除:先取出第 2 张幻灯片,再删除它
ppt.Slides.Remove(ppt.Slides.get_Item(1));
常见问题
文件需要上传到服务器吗
本文的用法不需要上传。Spire.Presentation for JavaScript 基于 WebAssembly 在浏览器端运行,演示文稿通过虚拟文件系统(VFS)在本地读写,添加、删除、保存都在本地完成,库本身不会把文件发往服务器。文件最终是否会离开设备,取决于你在页面上另外接入的代码。
一次可以添加或删除多张幻灯片吗
可以,循环调用即可:添加或插入时多次调用 Slides.Append() / Slides.Insert();删除多张时下标要按顺序处理,否则容易删错页或越界(见下条)。
新建的 Presentation 为什么自带一张空白幻灯片
原因:new Presentation() 初始化出来的演示文稿里已经有一张空白幻灯片;Append() 只是在末尾追加,并不会替换它。
解决:想从空白开始,先把它删掉,再追加所需的幻灯片:
let ppt = new pptModule.Presentation();
// 移除自带的这张空白幻灯片
ppt.Slides.RemoveAt(0);
// 之后再按需追加
ppt.Slides.Append({ template: ppt.Masters.get_Item(0).Layouts.get_Item(1) });
不带参数的 Append() 为什么是空白页
原因:不带参数时按默认(空白)版式新建,页面上没有现成的标题、正文占位符,所以看上去是一张空白页。
解决:需要现成的占位符,就指定带占位符的版式,或直接克隆已有幻灯片;也可以在新增页上自行用 Shapes.AppendShape() 添加内容:
// 按指定版式新建,页面上自带标题与内容占位符
ppt.Slides.Append({ template: ppt.Masters.get_Item(0).Layouts.get_Item(1) });
// 克隆第一张幻灯片,内容随之复制过来
ppt.Slides.Append({ slide: ppt.Slides.get_Item(0) });
删除多张幻灯片时,为什么会删错页或提示索引越界
原因:Slides 按位置索引,且每删掉一张,其后幻灯片的索引都会前移一位。用固定索引「从前往后」连着删时(依次 RemoveAt(0)、RemoveAt(1)……),第二步删的往往已经不是原来那几张;索引一旦超过当前张数(Slides.Count - 1),RemoveAt 还会直接报错。
解决:删多张时别用递增的固定索引,改成每次都删当前的第 1 张(索引 0)——删掉后后面的幻灯片会自动补位:
// 删掉前 3 张:每次都删索引 0,后面的幻灯片自动补位
for (let i = 0; i < 3; i++) {
ppt.Slides.RemoveAt(0);
}
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







