插入图表时,Excel 会自动确定一套刻度:纵轴的下限、上限与单位,均由依据数据范围推算而来。这套默认值在多数情况下可以满足需要,但在两种情形下会显出不足。其一,数据集中在较窄的区间内、整体又远离零点时,自动刻度会把纵轴起点抬到数据下沿附近,幅度有限的波动因而被画成接近满高的涨落,柱体之间的高低差与数值的差距不成比例;其二,刻度标签沿用数据源的格式,带小数的数字会使纵轴排满小数位,既不易辨识,也占用宽度。坐标轴格式用于调整这两处:给定刻度范围与单位,可使纵轴不随数据浮动,柱高与数值成比例,各图表也落在同一尺度上;指定刻度线与标签位置,可控制读数的落点;改写数字格式,可将标签整理为便于比较的形式;再为两轴添加标题,读者方能明确横纵两轴各自的含义。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成上述操作,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
设置数值轴的刻度格式
自动刻度由 Excel 依据数据范围推算,其目标是让图表整体匀称,而非让读数便于比较。数据集中在较窄的区间内、整体又远离零点时,这种推算会把纵轴的下限抬到数据下沿附近:下限既不从 0 起,柱高便只体现彼此的差值,幅度有限的波动被画成接近满高的涨落,图形与数值之间不成比例。此外,刻度标签默认沿用源单元格的显示格式,数据带小数时,纵轴上会出现一串带小数位的刻度,既不易辨识,也占用宽度。手动接管数值轴的刻度可以同时解决这两点:刻度范围与刻度间隔由代码指定后,纵轴的起点与上限不再随数据浮动,柱高与数值成比例,同一批图表也可采用同一把尺子;标签的显示格式独立于源单元格后,读数更为整齐。具体操作步骤如下:
- 将字体与测试数据文件载入 VFS。
- 用
workbook.LoadFromFile加载工作簿,以workbook.Worksheets.get(0)取得工作表。 - 用
sheet.Charts.Add添加柱状图,将chart.DataRange指向销售额一列,再把月份一列赋给serie.CategoryLabels。 - 在
chart.PrimaryValueAxis上用MinValue与MaxValue指定刻度范围,用MajorUnit与MinorUnit给出主、次单位的步长。 - 用
MajorTickMark与MinorTickMark指定主、次刻度线的类型,用TickLabelPosition指定刻度标签的位置。 - 将
NumberFormat设为#,##0以指定标签的数字格式,并把IsSourceLinked设为false关闭与数据源的格式联动,最后保存工作簿。
以下为完整的代码示例,演示如何在 React 中设置数值轴的刻度格式:
function App() {
const formatValueAxis = 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 = 'ChartAxisData.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({ chartType: xlsModule.ExcelChartType.ColumnClustered });
chart.ChartTitle = "各月销售额";
chart.ChartTitleArea.IsBold = true;
chart.ChartTitleArea.Size = 12;
chart.DataRange = sheet.Range.get("B1:B9");
chart.SeriesDataFromRange = false;
chart.PlotArea.Visible = false;
// 设置图表在工作表中的位置
chart.TopRow = 10;
chart.BottomRow = 28;
chart.LeftColumn = 2;
chart.RightColumn = 10;
// 取到系列,把月份一列设为分类标签
const serie = chart.Series.get(0);
serie.CategoryLabels = sheet.Range.get("A2:A9");
// 给定数值轴的边界:下限 0,上限 5000
const valueAxis = chart.PrimaryValueAxis;
valueAxis.MinValue = 0;
valueAxis.MaxValue = 5000;
// 给定主刻度单位 1000,次刻度单位 500
valueAxis.MajorUnit = 1000;
valueAxis.MinorUnit = 500;
// 主刻度线画在轴线外侧,次刻度线画在内侧
valueAxis.MajorTickMark = xlsModule.TickMarkType.TickMarkOutside;
valueAxis.MinorTickMark = xlsModule.TickMarkType.TickMarkInside;
// 刻度标签紧贴轴线,横坐标轴在数值 0 处与数值轴交叉
valueAxis.TickLabelPosition = xlsModule.TickLabelPositionType.TickLabelPositionNextToAxis;
valueAxis.CrossesAt = 0;
// 刻度标签补千位分隔符、去掉小数位
valueAxis.NumberFormat = "#,##0";
// 关闭与数据源的格式联动,标签格式以 NumberFormat 为准
valueAxis.IsSourceLinked = false;
// 保存工作簿
const outputFileName = "AxisFormat.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>坐标轴刻度格式</h1>
<button onClick={formatValueAxis}>Start</button>
</div>
);
}
export default App;
运行后,设置数值轴刻度格式的效果:

为坐标轴添加标题
坐标轴上只有刻度与分类项,图表本身并不说明每条数据代表什么、数值以什么为单位;隔一段时间重新打开文件,往往需要先查看图表标题才能确认图表的主题。坐标轴标题补充的正是这一层语境:分类轴标题说明每个数据点代表的对象,数值轴标题说明这组数字的单位,二者与图表标题一同把图表补全为可以脱离上下文阅读的形式。此外,轴标题的字号可以单独调整,由此与图表标题区分开。具体操作步骤如下:
- 将字体与测试数据文件载入 VFS。
- 用
workbook.LoadFromFile加载工作簿,以workbook.Worksheets.get(0)取得工作表。 - 用
sheet.Charts.Add添加柱状图,将chart.DataRange指向销售额一列,再把月份一列赋给serie.CategoryLabels。 - 将标题文字分别赋给
chart.PrimaryCategoryAxis.Title与chart.PrimaryValueAxis.Title。 - 用两个轴对象的
Font.Size将标题字号统一设为 12,保存工作簿。
以下为完整的代码示例,演示如何在 React 中为坐标轴添加标题:
function App() {
const setAxisTitle = 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 = 'ChartAxisData.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({ chartType: xlsModule.ExcelChartType.ColumnClustered });
chart.ChartTitle = "各月销售额";
chart.ChartTitleArea.IsBold = true;
chart.ChartTitleArea.Size = 12;
chart.DataRange = sheet.Range.get("B1:B9");
chart.SeriesDataFromRange = false;
chart.PlotArea.Visible = false;
// 设置图表在工作表中的位置
chart.TopRow = 10;
chart.BottomRow = 28;
chart.LeftColumn = 2;
chart.RightColumn = 10;
// 取到系列,把月份一列设为分类标签
const serie = chart.Series.get(0);
serie.CategoryLabels = sheet.Range.get("A2:A9");
// 给定分类轴与数值轴的标题
chart.PrimaryCategoryAxis.Title = "月份";
chart.PrimaryValueAxis.Title = "销售额(元)";
// 两个轴标题的字号都设为 12
chart.PrimaryCategoryAxis.Font.Size = 12;
chart.PrimaryValueAxis.Font.Size = 12;
// 保存工作簿
const outputFileName = "AxisTitle.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>坐标轴标题</h1>
<button onClick={setAxisTitle}>Start</button>
</div>
);
}
export default App;
运行后,为坐标轴添加标题的效果:

常见问题
设置了 MinorUnit,却看不到次刻度线
原因:MinorUnit 仅决定次刻度的间隔,即主刻度之间被划分为几格;是否将这些格子绘制为短线,由另一属性决定。MinorTickMark 的默认值为 TickMarkNone,此时间隔已经生效,但不会绘制任何短线。
解决:同时设置 MinorTickMark,其取值来自 TickMarkType:
const valueAxis = chart.PrimaryValueAxis;
valueAxis.MinorUnit = 500;
valueAxis.MinorTickMark = xlsModule.TickMarkType.TickMarkInside;
设置了 CrossesAt,横坐标轴的位置却没有变化
原因:CrossesAt 决定横坐标轴与数值轴相交的位置,只有将其设为横坐标轴当前所在刻度以外的位置,才会看到移动发生。数值轴自 0 起步时,横坐标轴原本就位于轴线的底端,此时将 CrossesAt 设为 0,等同于维持原位。
解决:将 CrossesAt 设为数值轴范围内的其他刻度,例如 3000,横坐标轴将随之移升至该刻度处:
const valueAxis = chart.PrimaryValueAxis;
valueAxis.MinValue = 0;
valueAxis.MaxValue = 5000;
valueAxis.CrossesAt = 3000;
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。









