一组数据按顺序逐项累积、中间既有增加也有减少时,只看起点与终点无法知道中间每一步各贡献了多少。瀑布图把每个增减项画成一根悬浮的柱子,从上一项的累计值出发,向上或向下延伸到新的累计值,相邻柱子首尾相接,整串图形既能看到逐项的增减幅度,也能读出每一步之后的累计结果。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端创建并保存瀑布图,输入输出文件通过虚拟文件系统(VFS)管理,无需后端服务支持。
本文介绍三个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
创建瀑布图
制作一张可用的瀑布图,需要先准备一列分类与一列数值,再把图表类型指定为瀑布图,确定数据区域、图表位置与标题。图表创建完成后保存为 Excel 工作簿,即可在表格软件中打开、继续编辑或分发。
创建瀑布图的写法与结果:
| 写法 | 得到的结果 |
|---|---|
window.spire.FetchFileToVFS |
把字体文件与输入文件载入虚拟文件系统 |
workbook.LoadFromFile({ fileName }) |
载入 Excel 工作簿 |
workbook.Worksheets.get(0) |
取得工作簿中的第一张工作表 |
sheet.Charts.Add() |
在工作表中添加一个图表对象 |
chart.ChartType = xlsModule.ExcelChartType.WaterFall |
把图表类型指定为瀑布图 |
chart.DataRange |
把指定单元格区域设为图表的数据源 |
chart.ChartTitle |
设置图表标题 |
chart.TopRow / chart.BottomRow / chart.LeftColumn / chart.RightColumn |
设定图表在工作表中的位置与大小 |
workbook.SaveToFile({ fileName }) |
把带瀑布图的工作簿写入虚拟文件系统 |
具体操作步骤如下:
- 用
window.spire.FetchFileToVFS把字体文件与 Excel 测试文件载入 VFS。 - 用
new Workbook()新建工作簿,再用workbook.LoadFromFile载入测试文件。 - 调用
workbook.Worksheets.get(0)取得第一张工作表。 - 用
sheet.Charts.Add()添加图表,再把chart.ChartType设为xlsModule.ExcelChartType.WaterFall。 - 把
chart.DataRange设为包含分类与数值的区域(示例为sheet.Range.get('A1:B8')),第一列为分类、第二列为数值,正数累计向上、负数累计向下。 - 设置
chart.ChartTitle,并通过chart.TopRow、chart.BottomRow、chart.LeftColumn、chart.RightColumn把图表放到数据区域右侧的第 4 至 12 列,确定其位置与大小,避免遮挡原有数据。 - 调用
workbook.SaveToFile写出CreateWaterfall.xlsx,再用workbook.Dispose释放资源并从 VFS 读取工作簿触发下载。
以下为完整的代码示例,演示如何在 React 中创建瀑布图并保存到 Excel 工作簿:
function App() {
// 创建瀑布图并保存为 Excel 工作簿
const createWaterfall = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体与测试数据文件载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'WaterfallData.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 chart = sheet.Charts.Add();
chart.ChartType = xlsModule.ExcelChartType.WaterFall;
// 设置数据区域:第一列为收支项目,第二列为金额
chart.DataRange = sheet.Range.get('A1:B8');
// 设置图表的位置与大小
chart.TopRow = 1;
chart.BottomRow = 19;
chart.LeftColumn = 4;
chart.RightColumn = 12;
// 设置图表标题
chart.ChartTitle = '月度现金收支';
// 将带瀑布图的工作簿保存到 VFS
const outputFileName = 'CreateWaterfall.xlsx';
workbook.SaveToFile({ fileName: outputFileName });
// 释放 workbook 对象以释放资源
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>在 React 中创建瀑布图</h1>
<button id="create-waterfall" onClick={createWaterfall}>创建瀑布图</button>
</div>
);
}
export default App;
创建瀑布图后的 Excel 工作簿:

将指定数据点标记为汇总
瀑布图默认把每一行都当作增减项,柱子从前一行的累计值继续浮动。序列首尾的汇总值并非增减项,而应直接从零起算,与中间的增减项区分开来。把对应的数据点标记为汇总后,这两根柱子会以完整柱形呈现,读者一眼就能认出起点与终点。
将指定数据点标记为汇总的写法与结果:
| 写法 | 得到的结果 |
|---|---|
chart.Series.get(0) |
取得图表中的第一个数据系列 |
chart.Series.get(0).DataPoints |
取得该系列的数据点集合,每一行数据对应一个数据点 |
DataPoints.get(i).SetAsTotal = true |
把索引 i 对应的数据点标记为汇总,柱形从零起算 |
workbook.SaveToFile({ fileName }) |
把带汇总标记的工作簿写入虚拟文件系统 |
具体操作步骤如下:
- 用
window.spire.FetchFileToVFS把字体文件与测试文件载入 VFS,再用workbook.LoadFromFile载入工作簿并取得第一张工作表。 - 用
sheet.Charts.Add()添加图表,把chart.ChartType设为xlsModule.ExcelChartType.WaterFall,再设置chart.DataRange、标题与位置。 - 通过
chart.Series.get(0).DataPoints取得数据点集合,集合中的索引从 0 开始,与数据行依次对应。 - 把
DataPoints.get(0).SetAsTotal与DataPoints.get(6).SetAsTotal都设为true,第一行与最后一行的数据点随之成为汇总列。 - 用
workbook.SaveToFile写出MarkTotals.xlsx,再用workbook.Dispose释放资源并触发下载。
以下为完整的代码示例,演示如何把期初与期末数据点标记为汇总:
function App() {
// 将期初与期末数据点标记为汇总
const markTotals = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体与测试数据文件载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'WaterfallData.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 chart = sheet.Charts.Add();
chart.ChartType = xlsModule.ExcelChartType.WaterFall;
chart.DataRange = sheet.Range.get('A1:B8');
chart.TopRow = 1;
chart.BottomRow = 19;
chart.LeftColumn = 4;
chart.RightColumn = 12;
chart.ChartTitle = '月度现金收支';
// 把第一个与最后一个数据点标记为汇总,让两根柱子从零起算
const points = chart.Series.get(0).DataPoints;
points.get(0).SetAsTotal = true;
points.get(6).SetAsTotal = true;
// 将带汇总数据点的瀑布图工作簿保存到 VFS
const outputFileName = 'MarkTotals.xlsx';
workbook.SaveToFile({ fileName: outputFileName });
// 释放 workbook 对象以释放资源
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>在 React 中创建瀑布图</h1>
<button id="mark-totals" onClick={markTotals}>标记汇总数据点</button>
</div>
);
}
export default App;
将数据点标记为汇总后的 Excel 工作簿:

隐藏数据点之间的连接线
瀑布图默认在相邻柱子之间绘制连接线,把上一根柱子的结束位置与下一根柱子的起始位置连起来。当柱形较窄、标签较多,或结果需要导出到显示能力有限的查看器时,连接线与标签、网格线挤在一起会让图形显得繁乱。关闭连接线后,柱形之间的高低关系依然可读,版式随之简洁。
隐藏数据点之间的连接线的写法与结果:
| 写法 | 得到的结果 |
|---|---|
chart.Series.get(0).Format |
取得数据系列的格式对象 |
chart.Series.get(0).Format.ShowConnectorLines = false |
关闭相邻数据点之间的连接线 |
workbook.SaveToFile({ fileName }) |
把关闭连接线后的工作簿写入虚拟文件系统 |
具体操作步骤如下:
- 用
window.spire.FetchFileToVFS把字体文件与测试文件载入 VFS,再用workbook.LoadFromFile载入工作簿并取得第一张工作表。 - 用
sheet.Charts.Add()添加图表,把chart.ChartType设为xlsModule.ExcelChartType.WaterFall,再设置chart.DataRange、标题与位置。 - 通过
chart.Series.get(0).Format取得数据系列的格式对象,把其中的ShowConnectorLines设为false,相邻数据点之间的连接线随即消失。 - 用
workbook.SaveToFile写出HideConnectorLines.xlsx,再用workbook.Dispose释放资源并触发下载。
以下为完整的代码示例,演示如何隐藏瀑布图中数据点之间的连接线:
function App() {
// 隐藏数据点之间的连接线
const hideConnectorLines = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体与测试数据文件载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'WaterfallData.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 chart = sheet.Charts.Add();
chart.ChartType = xlsModule.ExcelChartType.WaterFall;
chart.DataRange = sheet.Range.get('A1:B8');
chart.TopRow = 1;
chart.BottomRow = 19;
chart.LeftColumn = 4;
chart.RightColumn = 12;
chart.ChartTitle = '月度现金收支';
// 关闭相邻数据点之间的连接线
chart.Series.get(0).Format.ShowConnectorLines = false;
// 将关闭连接线的瀑布图工作簿保存到 VFS
const outputFileName = 'HideConnectorLines.xlsx';
workbook.SaveToFile({ fileName: outputFileName });
// 释放 workbook 对象以释放资源
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>在 React 中创建瀑布图</h1>
<button id="hide-connector-lines" onClick={hideConnectorLines}>隐藏连接线</button>
</div>
);
}
export default App;
关闭连接线后的 Excel 工作簿:

常见问题
如何在瀑布图上显示数值
原因:瀑布图的柱形高度表达的是增减幅度,具体金额需要回到数据表查看,图形本身读不出每一行的数值。
解决:取得默认数据点的标签对象,把 HasValue 设为 true;需要时再把 Position 设为 xlsModule.DataLabelPositionType.Center,让标签落在柱形中央:
const labels = chart.Series.get(0).DataPoints.DefaultDataPoint.DataLabels;
labels.HasValue = true;
labels.Position = xlsModule.DataLabelPositionType.Center;
如何调整数值轴的最小值和最大值
原因:瀑布图的数值轴默认按数据自动缩放,柱子之间的差异可能被压缩,或轴两端留出过多空白。
解决:在保存工作簿之前设置 chart.PrimaryValueAxis.MinValue 与 MaxValue,把数值轴固定在一个明确的范围。示例将范围限制在 1000 到 2000:
chart.PrimaryValueAxis.MinValue = 1000;
chart.PrimaryValueAxis.MaxValue = 2000;
设置的范围需要覆盖所有柱子的累计值,范围过窄会把超出部分裁掉。
瀑布图与堆积柱形图应如何选择
原因:两者都能表现由多部分构成的总量,但呈现重点不同。堆积柱形图把各部分叠在同一根柱子里,强调总量的构成比例;瀑布图把各部分拆成首尾相接的独立柱子,强调每一步增减对累计结果的影响。
解决:需要展示各部分的构成与占比时选用堆积柱形图;需要追踪余额如何从起点经过若干增减项走到终点时,将 chart.ChartType 设为 xlsModule.ExcelChartType.WaterFall 创建瀑布图。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







