在日常办公自动化场景中,经常需要从 Excel 报表中批量提取产品图片、替换过期 Logo,或对指定图片进行单独导出。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成这些图片操作,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
提取工作表中的所有图片
批量提取工作表中的所有图片,适用于备份报表中的嵌入图像、迁移产品资料等场景。实现流程分为三个步骤:遍历 Worksheet.Pictures 集合,对每张图片调用 Picture.Save 方法将其保存到 VFS,然后逐一读取并触发浏览器下载。
function App() {
const extractAllImages = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将 Excel 文件载入 VFS
const inputFileName = 'ReadImages.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿,获取第一个工作表
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// 遍历工作表中的所有图片并逐个导出
for (let i = 0; i < sheet.Pictures.Count; i++) {
const pic = sheet.Pictures.get(i);
const outputFileName = `Image-${i + 1}.png`;
pic.Picture.Save(outputFileName);
// 从 VFS 读取导出的图片文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.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);
}
// 释放资源
workbook.Dispose();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>提取工作表中的所有图片</h1>
<button onClick={extractAllImages}>
提取全部图片
</button>
</div>
);
}
export default App;
从工作表中批量提取并下载的图片文件

提取指定图片
提取工作表中的指定图片有两种常用方式:按索引直接获取,或按图片名称遍历匹配。索引方式适合已知图片位置(如第一张图片)的场景,名称方式则适合预先知道图片标识名的情况。实现流程分为两步:先通过索引或名称定位目标图片,再将其导出为本地文件。
function App() {
const extractImage = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将 Excel 文件载入 VFS
const inputFileName = 'ReadImages.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿,获取第一个工作表
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// 方法一:按索引提取(例如提取第二张图片)
const pic = sheet.Pictures.get(1);
const outputFileName = 'ExtractByIndex.png';
// // 方法二:按图片名称遍历匹配
// let pic = null;
// const targetName = 'SpireXLS';
// for (let i = 0; i < sheet.Pictures.Count; i++) {
// if (sheet.Pictures.get(i).Name === targetName) {
// pic = sheet.Pictures.get(i);
// break;
// }
// }
// const outputFileName = 'ExtractByName.png';
// 将图片保存到 VFS 并触发下载
pic.Picture.Save(outputFileName);
const fileArray = window.dotnetRuntime.Module.FS.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);
workbook.Dispose();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>提取指定图片</h1>
<button onClick={extractImage}>
提取图片
</button>
</div>
);
}
export default App;
通过索引或图片名称提取并下载的指定图片

替换工作表中的已有图片
替换工作表中的现有图片是更新报表 Logo、更换产品展示图等场景中的常见需求。实现思路是:先获取目标图片的位置与大小信息,然后通过 XlsShape.Convert 将此图片删除,最后在相同位置插入新图片,并将新图片的大小与偏移设置为与原图片一致。
function App() {
const replaceImage = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将 Excel 文件和新图片载入 VFS
const inputFileName = 'ReadImages.xlsx';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}data/`);
const newImageFile = 'Logo.png';
await window.spire.FetchFileToVFS(newImageFile, '', `${process.env.PUBLIC_URL}data/`);
// 加载工作簿,获取第一个工作表
const workbook = new xlsModule.Workbook();
workbook.LoadFromFile({ fileName: inputFileName });
const sheet = workbook.Worksheets.get(0);
// 获取第一张图片及其位置、大小信息
const oldPic = sheet.Pictures.get(0);
const topRow = oldPic.TopRow;
const leftColumn = oldPic.LeftColumn;
const leftColumnOffset = oldPic.LeftColumnOffset;
const topRowOffset = oldPic.TopRowOffset;
const width = oldPic.Width;
const height = oldPic.Height;
// 删除原有图片
xlsModule.XlsShape.Convert(oldPic).Remove();
// 在同一位置插入新图片
let picture = sheet.Pictures.Add({ topRow: topRow, leftColumn: leftColumn, fileName: newImageFile });
// 设置新图片大小与偏移,与原图片保持一致
picture.Width = width;
picture.Height = height;
picture.LeftColumnOffset = leftColumnOffset;
picture.TopRowOffset = topRowOffset;
const outputFileName = 'ReplaceImage-out.xlsx';
// 保存修改后的工作簿
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// 释放资源
workbook.Dispose();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
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={replaceImage}>
替换图片
</button>
</div>
);
}
export default App;
替换图片后的 Excel 工作表效果

常见问题
提取的图片无法打开或格式不正确
原因:图片保存时未指定正确的扩展名,或 MIME 类型与图片格式不匹配。
解决:确保 Picture.Save 方法中使用的文件名扩展名与图片实际格式一致。如果是 PNG 格式,文件扩展名应为 .png;如果是 JPEG 格式,则使用 .jpg。下载时 Blob 的 type 也需相应设置:
// PNG 格式
const blob = new Blob([fileArray], { type: "image/png" });
// JPEG 格式
const blob = new Blob([fileArray], { type: "image/jpeg" });
替换图片后位置或大小发生变化
原因:删除原图片前未记录其位置和大小属性,导致新图片无法精确对齐到原始位置或保持原有大小。
解决:在删除前保存图片的 TopRow、LeftColumn、LeftColumnOffset、TopRowOffset 等位置属性以及 Width、Height 大小属性。插入新图片后,通过设置新图片的这些属性使其与原图片保持一致:
// 插入新图片(指定行列位置)
let picture = sheet.Pictures.Add({ topRow: topRow, leftColumn: leftColumn, fileName: newImageFile });
// 设置大小与偏移,与原图片保持一致
picture.Width = width;
picture.Height = height;
picture.LeftColumnOffset = leftColumnOffset;
picture.TopRowOffset = topRowOffset;
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







