在 Web 应用中,将 Excel 文件以流(Stream)的形式进行操作,开发者可以动态地创建、加载、修改和保存 Excel 文件,从而实现灵活高效的数据处理。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成 Excel 文件的流式读写,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。它提供了简单易用的 Stream API,让通过流创建和保存 Excel 文件变得更加便捷。
通过流操作,可以在很大程度上减少直接的磁盘 I/O 操作,不仅提升应用的性能,还增强了响应能力,尤其适用于实时数据处理或存储受限的场景。借助 Spire.XLS for JavaScript,您可以在浏览器中动态创建 Excel 文件并保存到流,从流中加载并读取工作簿数据,或在流中修改内容后保存为新的 Excel 文件,从而简化数据交换和系统集成。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
动态创建 Excel 文件并保存到流
利用 Spire.XLS for JavaScript,您可以在浏览器中动态创建 Excel 文件,填充数据并设置格式后,通过 SaveToStream() 方法将工作簿保存到文件流。这种方法可以省去直接对磁盘进行文件存储的需求,同时提升应用的性能和响应速度。具体操作步骤如下:
- 创建
Workbook实例以生成新的 Excel 工作簿,清除默认工作表并添加新工作表。 - 使用
Worksheets.get()方法访问特定的工作表。 - 定义要写入工作表的数据,例如使用二维数组组织数据。
- 通过
Range.get_Item()方法获取单元格并逐一设置值。 - 对工作表单元格进行格式化,例如设置颜色、字体、边框,或调整列宽。
- 创建
Stream对象,使用SaveToStream()方法将工作簿保存到文件流。保存后的流可直接用于进一步处理,例如下载为文件或通过网络进行传输。
下面是一个完整的代码示例,展示了在 React 中动态创建 Excel 文件并保存到流:
function App() {
const createAndSaveToStream = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 加载字体文件以确保文本正确渲染
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}font/`);
// 创建新的工作簿实例
const workbook = new xlsModule.Workbook();
// 清除默认工作表并添加新工作表
workbook.Worksheets.Clear();
const sheet = workbook.Worksheets.Add('Data');
// 定义要写入工作表的示例数据(二维数组)
const headers = ['编号', '姓名', '年龄', '国家', '工资 (¥)'];
const data = [
[1, '张伟', 29, '中国', 8000],
[2, '李娜', 35, '中国', 12000],
[3, '王强', 42, '中国', 15000],
[4, '杰克', 26, '美国', 9500],
[5, '陈思', 31, '中国', 11000],
[6, '石原安子', 28, '日本', 8800]
];
// 将表头写入第一行
for (let col = 0; col < headers.length; col++) {
sheet.Range.get_Item({ row: 1, column: col + 1 }).Text = headers[col];
}
// 将数据写入后续行
for (let row = 0; row < data.length; row++) {
for (let col = 0; col < data[row].length; col++) {
sheet.Range.get_Item({ row: row + 2, column: col + 1 }).Text = String(data[row][col]);
}
}
// 格式化表头行
sheet.Range.get('A1:E1').Style.Color = xlsModule.Color.get_LightSkyBlue();
sheet.Range.get('A1:E1').Style.Font.FontName = 'Arial';
sheet.Range.get('A1:E1').Style.Font.Size = 12;
sheet.Range.get('A1:E1').Style.Font.IsBold = true;
// 格式化数据行
for (let i = 2; i <= data.length + 1; i++) {
const dataRange = sheet.Range.get({
row: i, column: 1,
lastRow: i, lastColumn: headers.length
});
dataRange.Style.Color = xlsModule.Color.get_LightGray();
dataRange.Style.Font.FontName = 'Arial';
dataRange.Style.Font.Size = 11;
}
// 为表头和所有数据单元格添加边框
const usedRange = sheet.Range.get({
row: 1, column: 1,
lastRow: data.length + 1,
lastColumn: headers.length
});
usedRange.Borders.LineStyle = xlsModule.LineStyleType.Thin;
usedRange.Borders.Color = xlsModule.Color.get_LightSteelBlue();
// 调整列宽以适应内容
for (let col = 1; col <= headers.length; col++) {
sheet.AutoFitColumn(col);
}
// 创建流并将工作簿保存到流
const outputFileName = 'CreateExcelToStream.xlsx';
const fileStream = new xlsModule.Stream(outputFileName);
workbook.SaveToStream(fileStream, xlsModule.FileFormat.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>动态创建 Excel 并保存到流</h1>
<button onClick={createAndSaveToStream}>
生成
</button>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 动态创建 Excel 文件并保存到流

从流中加载并读取 Excel 文件
通过 Spire.XLS for JavaScript,您可以使用 LoadFromStream() 方法直接从流中加载 Excel 文件。加载完成后,可以轻松读取流中 Excel 文件的单元格数据,实现快速灵活的数据处理,而无需进行文件 I/O 操作。具体操作步骤如下:
- 创建指向待加载 Excel 文件的
Stream对象。 - 创建
Workbook对象,调用LoadFromStream()方法从流中加载文件。 - 使用
Worksheets.get()方法获取第一个工作表。 - 遍历工作表的行和列,通过
Range.get()方法提取单元格数据。 - 将提取的数据显示在页面上,或用于其他操作。
下面是一个完整的代码示例,展示了在 React 中从流中加载并读取 Excel 文件:
import React, { useState } from 'react';
function App() {
const [extractedData, setExtractedData] = useState('');
const loadAndReadFromStream = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 加载字体文件以确保文本正确渲染
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}font/`);
// 将示例 Excel 文件加载到 VFS
await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);
// 创建工作簿对象并从流中加载 Excel 文件
const workbook = new xlsModule.Workbook();
const fileStream = new xlsModule.Stream('Sample.xlsx');
workbook.LoadFromStream(fileStream, xlsModule.FileFormat.Auto);
// 获取工作簿中的第一个工作表
const sheet = workbook.Worksheets.get(0);
// 遍历工作表的行和列,提取单元格数据
const data = [];
for (let row = sheet.FirstRow; row <= sheet.LastRow; row++) {
const line = [];
for (let col = sheet.FirstColumn; col <= sheet.LastColumn; col++) {
line.push(sheet.Range.get({ row: row, column: col }).Text);
}
data.push(line.join(' | '));
}
// 释放工作簿对象以释放资源
workbook.Dispose();
// 在页面上显示提取的数据
setExtractedData(data.join('\n'));
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>从流中加载并读取 Excel 数据</h1>
<button onClick={loadAndReadFromStream}>
读取
</button>
<pre style={{ marginTop: '20px', textAlign: 'left' }}>{extractedData}</pre>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 从流中加载并读取 Excel 文件

在流中修改并保存 Excel 文件
借助 Spire.XLS for JavaScript,您可以在内存中修改 Excel 文件。首先通过 LoadFromStream() 方法将流中的 Excel 文件加载到 Workbook 对象中,完成修改(例如更改单元格样式或内容)后,再使用 SaveToStream() 方法将文件保存回流。无需依赖直接的文件存储操作即可实现实时的 Excel 文件数据更改。具体操作步骤如下:
- 创建指向 Excel 文件的
Stream对象,并通过LoadFromStream()方法从流中加载文件。 - 使用
Worksheets.get()方法访问工作表。 - 修改表头行及数据行的样式(字体、字号、背景色等),通过
CellRange.Style属性完成。 - 使用
AutoFitColumn()方法自动调整列宽以适应内容。 - 设置单元格的边框样式。
- 创建新的
Stream对象,使用SaveToStream()方法将修改后的工作簿保存到流,并从 VFS 读取结果文件触发下载。
下面是一个完整的代码示例,展示了在 React 中修改流中的 Excel 文件并保存:
function App() {
const modifyAndSaveInStream = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 加载字体文件以确保文本正确渲染
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}font/`);
// 将示例 Excel 文件加载到 VFS
await window.spire.FetchFileToVFS('Sample.xlsx', '', `${process.env.PUBLIC_URL}data/`);
// 创建工作簿对象并从流中加载 Excel 文件
const workbook = new xlsModule.Workbook();
const fileStream = new xlsModule.Stream('Sample.xlsx');
workbook.LoadFromStream(fileStream, xlsModule.FileFormat.Auto);
// 获取工作簿中的第一个工作表
const sheet = workbook.Worksheets.get(0);
// 修改表头行的样式
const headerRow = sheet.Range.get({
row: sheet.FirstRow, column: sheet.FirstColumn,
lastRow: sheet.FirstRow, lastColumn: sheet.LastColumn
});
headerRow.Style.Font.FontName = 'Arial';
headerRow.Style.Font.Size = 12;
headerRow.Style.Font.IsBold = true;
headerRow.Style.Color = xlsModule.Color.get_LightSkyBlue();
// 修改数据行的样式,并交替着色(偶数行)
for (let i = sheet.FirstRow + 1; i <= sheet.LastRow; i++) {
const dataRow = sheet.Range.get({
row: i, column: sheet.FirstColumn,
lastRow: i, lastColumn: sheet.LastColumn
});
dataRow.Style.Font.FontName = 'Arial';
dataRow.Style.Font.Size = 10;
dataRow.Style.Color = xlsModule.Color.get_LightGray();
if (i % 2 === 0) {
dataRow.Style.Color = xlsModule.Color.get_DarkGray();
}
}
// 自动调整列宽以适应内容
for (let col = sheet.FirstColumn; col <= sheet.LastColumn; col++) {
sheet.AutoFitColumn(col);
}
// 设置边框颜色
sheet.AllocatedRange.Borders.Color = xlsModule.Color.get_White();
// 将修改后的工作簿保存到新的流
const outputFileName = 'ModifyExcelInStream.xlsx';
const outStream = new xlsModule.Stream(outputFileName);
workbook.SaveToStream(outStream, xlsModule.FileFormat.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>在流中修改并保存 Excel</h1>
<button onClick={modifyAndSaveInStream}>
生成
</button>
</div>
);
}
export default App;
使用 Spire.XLS for JavaScript 在流中修改并保存 Excel 文件

常见问题
为什么保存到流的文件无法在 Excel 中正常打开?
原因:使用 SaveToStream() 方法保存工作簿时,若未通过 FileFormat 参数指定正确的输出文件格式,生成的文件格式可能与扩展名不匹配,导致无法正常打开。
解决方案:保存到流时指定具体的文件格式枚举值,例如 xlsModule.FileFormat.Version2010:
const fileStream = new xlsModule.Stream(outputFileName);
workbook.SaveToStream(fileStream, xlsModule.FileFormat.Version2010);
如何确保从流加载的工作簿能够正确识别文件格式?
原因:LoadFromStream() 方法需要根据流中数据的实际格式来识别文件类型,若格式参数设置不正确,可能导致加载失败或数据解析错误。
解决方案:加载时使用 xlsModule.FileFormat.Auto,让库自动检测流中文件的格式:
const fileStream = new xlsModule.Stream('Sample.xlsx');
workbook.LoadFromStream(fileStream, xlsModule.FileFormat.Auto);
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。









