制作培训材料、产品手册或网页插图时,常常需要把幻灯片里的某个图形单独取出来使用。整页截图会把标题、背景和其他元素一并带入,再手动裁剪又难以保证边缘干净。把形状逐个渲染为独立图片,画面只保留形状本身,后续排版与拼接都更方便。
本文使用 Spire.Presentation for JavaScript 在浏览器中把 PowerPoint 形状保存为图片。PNG 保留形状的画面与透明区域,SVG 则以矢量形式记录线条与文字,放大后依然清晰。整个处理过程基于 WebAssembly,在用户设备本地完成,无需安装 Office,也不依赖后端服务,演示文稿不必离开浏览器。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.Presentation for JavaScript。以下示例默认 Spire.Presentation for JavaScript 已安装、WebAssembly 模块已初始化。
将幻灯片中的全部形状导出为 PNG 图片
一张幻灯片通常由矩形、图表、图片等多个形状组成。需要分别取用时,逐个截图既慢,也难以统一画面尺寸。按集合顺序遍历形状,可以把每个形状单独渲染成一张 PNG 图片,图片只包含形状本身,透明区域保持透明,便于再排版到其他文档或网页。
| 写法 | 得到的结果 |
|---|---|
slide.Shapes.Count |
当前幻灯片中的形状总数 |
slide.Shapes.get_Item(i) |
取索引 i 对应的形状 |
shape.SaveAsImage() |
把形状渲染为图片流 |
image.Save(fileName) |
把图片流保存为 PNG 文件 |
image.Dispose() |
释放图片流占用的资源 |
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块并确认已就绪,将字体文件与演示文稿载入 VFS。
- 创建
Presentation对象并调用LoadFromFile()加载演示文稿,再用Slides.get_Item(0)取得第一张幻灯片。 - 以
Shapes.Count为循环上限,通过Shapes.get_Item(i)依次取得每个形状。 - 对每个形状调用
SaveAsImage()得到图片流,用image.Save()写成 PNG 文件,随后调用Dispose()释放图片流。 - 调用
Presentation.Dispose()释放演示文稿,再从 VFS 逐个读出图片并触发下载。
将幻灯片中的全部形状导出为 PNG 图片的代码如下:
function App() {
const exportAllShapesToPng = 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 = 'Shapes.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);
// 逐个形状导出为 PNG 图片
const outputNames = [];
for (let i = 0; i < slide.Shapes.Count; i++) {
const shape = slide.Shapes.get_Item(i);
const image = shape.SaveAsImage();
const outputFileName = `Shape-${i + 1}.png`;
image.Save(outputFileName);
image.Dispose();
outputNames.push(outputFileName);
}
ppt.Dispose();
// 从 VFS 逐张读取图片并触发下载
const fsModule = window.dotnetRuntime.Module.FS;
for (const outputFileName of outputNames) {
const fileArray = fsModule.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'image/png' });
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={exportAllShapesToPng}>
导出全部形状
</button>
</div>
);
}
export default App;
逐个导出幻灯片形状后的 PNG 图片:

将指定形状导出为 SVG 图片
PNG 由像素构成,放大后边缘会变模糊,文字与图表在投影或印刷尺寸下尤其明显。SVG 用路径与文本描述画面,任意缩放都保持清晰,文件也更便于在网页中直接引用或继续编辑。SaveAsSvg() 把单个形状导出为一份独立的 SVG 文档,返回 SVG 文件的字节内容,写入虚拟文件系统后即可下载。
| 写法 | 得到的结果 |
|---|---|
shape.SaveAsSvg() |
把形状导出为 SVG,返回文件的字节内容 |
FS.writeFile(fileName, bytes) |
把字节内容写入 VFS 中的文件 |
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块并确认已就绪,将字体文件与演示文稿载入 VFS。
- 创建
Presentation对象并调用LoadFromFile()加载演示文稿,再用Slides.get_Item(0)取得第一张幻灯片。 - 用
Shapes.get_Item(index)按索引取得目标形状,索引从0开始。 - 调用
shape.SaveAsSvg()导出 SVG,返回值是Uint8Array形式的文件内容。 - 用
FS.writeFile()把字节内容写成.svg文件,随后调用Presentation.Dispose()释放演示文稿,再从 VFS 读出文件并触发下载。
将指定形状导出为 SVG 图片的代码如下:
function App() {
const exportShapeToSvg = 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 = 'Shapes.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 shape = slide.Shapes.get_Item(1);
// 导出为 SVG,返回的是 SVG 文件的字节内容
const svgBytes = shape.SaveAsSvg();
const outputFileName = 'Chart.svg';
window.dotnetRuntime.Module.FS.writeFile(outputFileName, svgBytes);
ppt.Dispose();
// 从 VFS 读取 SVG 并触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'image/svg+xml' });
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={exportShapeToSvg}>
导出 SVG 图片
</button>
</div>
);
}
export default App;
将指定形状导出为 SVG 图片后的矢量图:

将组合形状导出为单张图片
组合形状把箭头、标注文字等多个元素编成一组,整体移动与缩放时保持相对位置不变。导出组合形状时,组内元素会一并渲染到同一张图片中,适合把流程中的一步或页面上的重点标注整体取出使用。若只需要其中一个元素,也可以从组合中取出子形状单独导出。
| 写法 | 得到的结果 |
|---|---|
group.SaveAsImage() |
把整个组合渲染为一张图片 |
group.Shapes.Count |
组合内的子形状数量 |
group.Shapes.get_Item(i) |
取得组合中索引为 i 的子形状 |
child.SaveAsImage() |
把子形状单独渲染为图片 |
具体操作步骤如下:
- 获取 Spire.Presentation 的 WASM 模块并确认已就绪,将字体文件与演示文稿载入 VFS。
- 创建
Presentation对象并调用LoadFromFile()加载演示文稿,再用Slides.get_Item(0)取得第一张幻灯片。 - 用
Shapes.get_Item(index)按索引取得组合形状,可先通过group.Shapes.Count确认组内的子形状数量。 - 对组合调用
SaveAsImage(),把整组渲染为一张 PNG 图片并保存,随后调用Dispose()。 - 通过
group.Shapes.get_Item(0)取出子形状,同样用SaveAsImage()单独导出。 - 调用
Presentation.Dispose()释放演示文稿,再从 VFS 读出两张图片并触发下载。
将组合形状导出为单张图片的代码如下:
function App() {
const exportGroupShapeToPng = 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 = 'Shapes.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 group = slide.Shapes.get_Item(2);
const groupImage = group.SaveAsImage();
groupImage.Save('Group.png');
groupImage.Dispose();
// 也可以单独导出组合中的某个子形状
const child = group.Shapes.get_Item(0);
const childImage = child.SaveAsImage();
childImage.Save('GroupChild.png');
childImage.Dispose();
ppt.Dispose();
// 从 VFS 读取图片并触发下载
const fsModule = window.dotnetRuntime.Module.FS;
for (const outputFileName of ['Group.png', 'GroupChild.png']) {
const fileArray = fsModule.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'image/png' });
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={exportGroupShapeToPng}>
导出组合形状
</button>
</div>
);
}
export default App;
将组合形状与子形状分别导出后的 PNG 图片:

常见问题
导出的图片中文字显示成方框怎么办
原因:字体文件需要在创建并加载演示文稿之前放入 VFS。SaveAsImage() 在打开演示文稿时完成文字排版,之后再补充字体不会重新排版已有的形状。
解决:在 LoadFromFile() 之前调用 FetchFileToVFS() 载入文稿中使用的字体。
隐藏的形状也会被导出吗
原因:IsHidden 只控制形状在幻灯片中是否显示,不会阻止 SaveAsImage()。
解决:如果希望导出的形状不包括隐藏形状,遍历形状时先判断 IsHidden,跳过隐藏项:
for (let i = 0; i < slide.Shapes.Count; i++) {
const shape = slide.Shapes.get_Item(i);
// 跳过隐藏的形状
if (shape.IsHidden) continue;
const image = shape.SaveAsImage();
image.Save(`Shape-${i + 1}.png`);
image.Dispose();
}
SaveAsSvg() 与 SaveAsSvgInSlide() 有什么区别
原因:两者使用的画布不同。SaveAsSvg() 裁切到形状自身边界,输出的 SVG 只有形状那么大;SaveAsSvgInSlide() 保留整页画布,形状按其在幻灯片中的位置放置。
解决:只需要孤立图形时用 SaveAsSvg();需要保留页面位置、便于叠放到幻灯片背景上时用 SaveAsSvgInSlide()。两者都返回 SVG 字节,写入 VFS 的方式相同。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







