Excel 本身没有内置的水印功能,但在合同、报表、内部资料等业务场景中,我们经常需要为文档加上"机密"、"样本"等水印标识,防止信息被随意复制和传播。Spire.XLS for JavaScript 基于 WebAssembly 在浏览器端直接处理 Excel 文档,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。借助页眉图片功能,即可为工作表轻松添加和移除水印。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.XLS for JavaScript。以下示例默认已安装 Spire.XLS 并完成 WebAssembly 模块初始化。
添加水印到 Excel 工作表
Excel 本身没有内置的水印功能,合同、报表和内部资料却常常需要标明来源或使用范围。水印以浅色文字铺在页面中央,既不遮挡正文,又能提示读者这份文件的用途。实现时先把水印绘制成与页面同尺寸的图片,再把它放进页眉,水印便会随每一页一起显示。
添加水印到 Excel 工作表的写法与结果:
| 写法 | 得到的结果 |
|---|---|
sheet.PageSetup.PageWidth / PageHeight |
取得页面尺寸,用于绘制同尺寸的水印图片 |
watermarkCanvas.toBlob(...) 与 FS.writeFile(...) |
生成水印图片并写入 VFS |
new xlsModule.Stream(imgFileName) |
从 VFS 读取水印图片流 |
sheet.PageSetup.LeftHeaderImage = watermark |
把水印图片设为左侧页眉图片 |
sheet.PageSetup.LeftHeader = "&G" |
在页眉中显示该图片 |
sheet.ViewMode = xlsModule.ViewMode.Layout |
切换到页面布局视图,便于预览 |
workbook.SaveToFile(...) |
把带水印的工作簿保存到 VFS |
具体操作步骤如下:
- 将字体文件与输入文件载入 VFS。
- 创建
Workbook对象,用LoadFromFile()载入 Excel 文档,并通过Workbook.Worksheets.get(0)取得第一张工作表。 - 使用 Canvas 绘制一张与页面大小一致的水印图片:白色背景,居中显示旋转 -45° 的 LightCoral 文字。
- 将水印图片保存到虚拟文件系统(VFS),并使用
Stream对象加载。 - 将水印图片设置为左侧页眉图片(
LeftHeaderImage),并将页眉文本设置为图片占位符&G。 - 将工作表切换到页面布局视图(
ViewMode.Layout),方便预览水印效果。 - 通过
Workbook.SaveToFile()方法保存文档,并用Workbook.Dispose()释放资源。
下面是一个完整的代码示例,展示了在 React 中为工作表添加水印:
function App() {
const addWatermark = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将字体和 Excel 文件载入 VFS
await window.spire.FetchFileToVFS('simsun.ttc', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'Watermark.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 watermarkText = '内部使用';
const textColor = 'lightcoral';
const backColor = 'white';
// 根据页面大小绘制水印图片(白底、居中旋转 -45° 的文字)
const drawWatermarkImage = (text, color, bg, width, height) => {
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// 绘制背景
ctx.fillStyle = bg;
ctx.fillRect(0, 0, width, height);
// 设置文字样式并在页面中心绘制旋转 -45° 的文本
ctx.fillStyle = color;
ctx.font = 'bold 48px SimSun';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.save();
ctx.translate(width / 2, height / 2);
ctx.rotate(-Math.PI / 4);
ctx.fillText(text, 0, 0);
ctx.restore();
return canvas;
};
// 绘制水印图片并写入虚拟文件系统(VFS)
const watermarkCanvas = drawWatermarkImage(watermarkText, textColor, backColor, sheet.PageSetup.PageWidth, sheet.PageSetup.PageHeight);
const watermarkBlob = await new Promise((resolve) => watermarkCanvas.toBlob(resolve, 'image/png'));
const watermarkBytes = new Uint8Array(await watermarkBlob.arrayBuffer());
const imgFileName = 'Watermark.png';
window.dotnetRuntime.Module.FS.writeFile(imgFileName, watermarkBytes);
// 加载水印图片
const watermark = new xlsModule.Stream(imgFileName);
// 将水印图片设置为左侧页眉图片,并通过 &G 占位符显示
sheet.PageSetup.LeftHeaderImage = watermark;
sheet.PageSetup.LeftHeader = "&G";
// 切换到页面布局视图,方便预览水印效果
sheet.ViewMode = xlsModule.ViewMode.Layout;
// 保存文档
const outputFileName = 'AddWatermark_output.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>Add Watermark to Excel</h1>
<button onClick={addWatermark}>
Start
</button>
</div>
);
}
export default App;
添加水印后的工作表:

移除 Excel 工作表上的水印
水印既由页眉承载,移除时也就只需处理页眉中的引用。清空对应的页眉文本后,图片不再显示,工作表正文保持原样。
移除 Excel 工作表上的水印的写法与结果:
| 写法 | 得到的结果 |
|---|---|
workbook.LoadFromFile(...) |
载入带有水印的工作簿 |
workbook.Worksheets.get(0) |
取得要处理的第一张工作表 |
sheet.PageSetup.LeftHeader = "" |
清空左侧页眉文本与图片占位符 |
workbook.SaveToFile(...) |
把移除水印后的工作簿保存到 VFS |
具体操作步骤如下:
- 将带有水印的 Excel 文件载入 VFS。
- 创建
Workbook对象,用LoadFromFile()载入文档,并通过Workbook.Worksheets.get(0)取得第一张工作表。 - 将
PageSetup.LeftHeader设置为空字符串,移除页眉中的水印图片占位符。 - 通过
Workbook.SaveToFile()方法保存文档,并用Workbook.Dispose()释放资源。
下面是一个完整的代码示例,展示了在 React 中移除工作表上的水印:
function App() {
const removeWatermark = async () => {
// 获取 Spire.XLS WASM 模块
const xlsModule = window.wasmModule?.spirexls;
// 检查模块是否就绪
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// 将带有水印的 Excel 文件载入 VFS
const inputFileName = 'AddWatermark.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);
// 清除左侧页眉文本,移除水印
sheet.PageSetup.LeftHeader = "";
// 保存文档
const outputFileName = 'RemoveWatermark_output.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>Remove Watermark from Excel</h1>
<button onClick={removeWatermark}>
Start
</button>
</div>
);
}
export default App;
移除水印后的工作表:

常见问题
水印在普通视图中看不到
原因:通过页眉图片实现的水印只显示在页面布局视图和打印预览中,在 Excel 普通视图中不可见。
解决:将工作表视图切换到页面布局模式即可预览水印效果,例如在代码中设置 sheet.ViewMode = xlsModule.ViewMode.Layout。
水印位置与预期不一致
原因:页眉图片水印会显示在页眉区域,可通过左、中、右三个页眉位置控制显示方位。位置不符合预期通常是因为设置的页眉区域与需求不一致。
解决:根据需求选择 LeftHeaderImage、CenterHeaderImage 或 RightHeaderImage 属性设置水印图片,并配合 LeftHeader、CenterHeader 或 RightHeader 属性设置对应的图片占位符 &G。
移除水印后文件中仍有残留内容
原因:水印基于页眉图片实现,如果仅清除了部分页眉区域,其他区域(如左侧或右侧页眉)可能仍保留水印图片。
解决:确保清除所有设置了水印的页眉区域文本,包括 LeftHeader、CenterHeader 和 RightHeader。
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







