在浏览器端生成报表时,一张订单明细表往往要打印好几页。如果沿用默认的打印设置,第二页之后就会丢失表头和关键列,阅读时无从判断每一列的含义,页码也难以与整份报表的编排衔接。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接完成页面设置,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文主要介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
设置打印标题行与打印标题列
打印标题对应 Excel「页面设置」对话框里的「顶端标题行」与「左端标题列」两项。设置之后,指定的行或列会在每一页打印输出的相同位置重复出现,表格翻到第二页时依然能看到表头。Spire.XLS for JavaScript 通过 PageSetup 的 PrintTitleRows 与 PrintTitleColumns 属性完成设置,取值是行列区间的引用字符串。具体代码示例如下:
function App() {
const setPrintTitles = 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 = 'OrderDetails.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 pageSetup = sheet.PageSetup;
// 把第 1、2 行设为打印标题行,每一页的顶端都重复输出
pageSetup.PrintTitleRows = '$1:$2';
// 把 A、B 两列设为打印标题列,每一页的左端都重复输出
pageSetup.PrintTitleColumns = '$A:$B';
// 保存工作簿
const outputFileName = 'SetPrintTitles.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// 释放 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={setPrintTitles}>设置打印标题行与打印标题列</button>
</div>
);
}
export default App;
原文件打印效果
运行后,打印标题行与打印标题列的效果:

设置打印顺序
当工作表同时超出一页宽和一页高时,Excel 需要在两种分页推进方向中做出选择:默认的「先行后列」先自上而下打满一页高,再换到右侧的下一组列;「先列后行」则先沿列方向打满一页宽,再向下推进。Spire.XLS for JavaScript 用 PageSetup 的 Order 属性在两者之间切换。具体代码示例如下:
function App() {
const setPrintOrder = 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 = 'OrderDetails.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 pageSetup = sheet.PageSetup;
// 把打印顺序设为「先列后行」:先自上而下打满一列,再向右换到下一列
pageSetup.Order = xlsModule.OrderType.OverThenDown;
// 保存工作簿
const outputFileName = 'SetPrintOrder.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// 释放 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={setPrintOrder}>设置打印顺序</button>
</div>
);
}
export default App;
运行后,打印顺序设为「先列后行」的效果:

常见问题
只设置打印标题行、不设置打印标题列,可以吗
原因:PrintTitleRows 与 PrintTitleColumns 是两个互不影响的属性,前者控制每页顶端重复的行,后者控制每页左端重复的列。只设置其中一个时,另一个保持未设置,不会因为缺了一项而被拒绝,也不会被补上默认值。
解决:按需要设置其中一个即可,例如只重复表头行:pageSetup.PrintTitleRows = '$1:$2'。
设置打印标题后,工作表里的数据会变吗
原因:打印标题属于页面设置,只决定打印时哪些行列重复输出,不改动单元格的内容,也不增删行列。
解决:数据不会受影响。实测设置前与设置后的结果文件同为 62 行 × 18 列,逐格文本完全一致,差别只在页面设置里多了一条打印标题定义;屏幕上看到的工作表与原来相同。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







