一批文档要看起来像同一套,最省事的做法是给每页铺上统一的品牌底色或信纸底纹。过去要么回到源文件逐份改版式,要么手工往每页叠一张图——前者要求手上还有可编辑的原始文档,后者稍不注意就压到正文。
在浏览器里直接改 PDF 就能绕开这两点:Spire.PDF for JavaScript 基于 WebAssembly 加载、修改与保存 PDF 文档,底色和底图都写进已有页面的 BackgroundColor、BackgroundImage 属性,绘制层级在正文下方;文件读写通过虚拟文件系统(VFS)完成,无需后端配合。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。以下示例默认已安装 Spire.PDF 并完成 WebAssembly 模块初始化。
为 PDF 所有页面设置背景颜色
整份文档要统一底色,逐页给 BackgroundColor 赋一个 Color 就行,该属性默认只按 0.25 的不透明度叠加,需要实色时把 BackgroudOpacity 设为 1。
function App() {
const setBackgroundColor = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将待处理的 PDF 文件载入 VFS
const inputFileName = '模板.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfDocument 对象并加载 PDF 文档
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 自定义底色:ARGB 四通道,这里取浅蓝
const backgroundColor = pdfModule.Color.FromArgb(255, 226, 240, 253);
// 逐页设置背景颜色
for (let i = 0; i < doc.Pages.Count; i++) {
const page = doc.Pages.get_Item(i);
page.BackgroundColor = backgroundColor;
// 默认叠加不透明度为 0.25,置为 1 得到实色
page.BackgroudOpacity = 1;
}
const outputFileName = '设置背景颜色.pdf';
doc.SaveToFile(outputFileName);
doc.Close();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
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>设置 PDF 背景颜色</h1>
<button onClick={setBackgroundColor}>
开始设置
</button>
</div>
);
}
export default App;
设置浅蓝色背景后的两页文稿,底色前后保持一致:

为 PDF 所有页面设置背景图片
整页铺一张底图则交给 BackgroundImage:它接收一个在虚拟文件系统里打开的图片流,并自动拉伸铺满页面内容区,浓淡同样由 BackgroudOpacity 控制。
function App() {
const setBackgroundImage = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将待处理的 PDF 文件与背景图载入 VFS
const inputFileName = '模板.pdf';
const imageFileName = 'Background.png';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
await window.spire.FetchFileToVFS(imageFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfDocument 对象并加载 PDF 文档
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 从 VFS 打开背景图文件流,各页共用同一个流
const imageStream = new window.spire.Stream(imageFileName);
// 逐页铺上底图,图片会拉伸铺满页面内容区
for (let i = 0; i < doc.Pages.Count; i++) {
const page = doc.Pages.get_Item(i);
page.BackgroundImage = imageStream;
page.BackgroudOpacity = 1;
}
const outputFileName = '设置背景图片.pdf';
doc.SaveToFile(outputFileName);
doc.Close();
// 从 VFS 读取生成的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
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>设置 PDF 背景图片</h1>
<button onClick={setBackgroundImage}>
开始设置
</button>
</div>
);
}
export default App;
同一张底图铺满每一页,正文文字依旧清晰:

常见问题
设置完背景色,颜色比预期的淡很多
原因:BackgroudOpacity 属性(拼写里少一个 n)默认是 0.25,背景会按 25% 的不透明度叠到页面上,深色也会被冲成浅色。
解决:需要实色就把 BackgroudOpacity 设为 1;想保留一点淡化效果,也可以取 0.3 到 0.8 之间的值。
page.BackgroundColor = backgroundColor;
// 置为 1 得到实色,调小则是淡化叠加
page.BackgroudOpacity = 1;
背景没有铺满整页,页面四周还是白的
原因:背景只绘制在页面的内容区(ClientSize)内。载入的 PDF 一般没有页边距,背景就是整页;而用 Pages.Add() 新建的页面默认带 40 磅页边距,这一圈不会被着色。
解决:新建页时把页边距设为 0,背景即可覆盖整页:
// 第二个参数传零页边距对象,页面内容区与整页等大
const page = doc.Pages.Add(pdfModule.PdfPageSize.A4(), new pdfModule.PdfMargins());
只想给其中某一页加背景
原因:BackgroundColor 与 BackgroundImage 都是页面级属性,只对赋值的那个页面生效,不会自动应用到整份文档。
解决:按页号单独取页设置即可,不必遍历:
// 只处理第 1 页,其余页面保持原样
const page = doc.Pages.get_Item(0);
page.BackgroundColor = pdfModule.Color.FromArgb(255, 226, 240, 253);
page.BackgroudOpacity = 1;
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。









