合同、报价单、试用版资料一旦以 PDF 发出去,内容就基本交到了对方手里,什么时候失效全凭对方自觉。想让文档到指定日期后自动提示失效,桌面软件只能一份份打开再手工设一遍,很难接进批量处理的 Web 流程;换到服务端做,文件又得先上传,离开用户的设备。
本文介绍用 Spire.PDF for JavaScript 为 PDF 文档设置过期日期。它基于 WebAssembly 在浏览器端直接加载、修改与保存 PDF 文档,全过程在本地完成,通过虚拟文件系统(VFS)读写文件,无需后端配合。
有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。下面的示例假定 Spire.PDF 已安装、WebAssembly 模块已初始化。
设置 PDF 文档的过期日期
Spire.PDF for JavaScript 提供 PdfJavaScriptAction 类,用于把一段 JavaScript 脚本包装成 PDF 动作。把它赋给 PdfDocument.AfterOpenAction 后,阅读器每次打开文档都会执行这段脚本——脚本比对当前时间与设定的日期,过了期就弹窗提示并关闭文档。
步骤 1:载入待处理的 PDF
先取到 Spire.PDF 的 WASM 模块并确认就绪,再把待设置的 PDF 读进虚拟文件系统(VFS),交给 PdfDocument 加载。
// 获取 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 对象并加载文档
const doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
步骤 2:编写过期校验脚本
过期日期就写在脚本里:new Date() 取打开当刻的系统时间,与设定的到期时刻比对,晚于它就走提示、关闭这两个动作。提示文字和到期时刻都是这一段里的字符串,换日期、换文案都改在这里。
// 过期校验脚本:当前时间晚于设定日期就提示并关闭文档
const script =
"var rightNow = new Date();" +
"var endDate = new Date('January 1, 2026 23:59:59');" +
"if (rightNow.getTime() > endDate.getTime()) {" +
"app.alert('本文档已过期,请联系我们获取新版本。', 1);" +
"this.closeDoc();" +
"}";
步骤 3:挂到文档的打开后动作
脚本本身不会自己运行,要包成 PdfJavaScriptAction 交给 PdfDocument.AfterOpenAction。这是文档级动作,阅读器打开文档时自动执行;保存后动作随文档一起落盘。
// 把脚本包成 JavaScript 动作,挂到文档的打开后动作
doc.AfterOpenAction = new pdfModule.PdfJavaScriptAction(script);
// 保存文档
const outputFileName = '设置过期日期.pdf';
doc.SaveToFile(outputFileName);
doc.Close();
步骤 4:读出结果并触发下载
保存好的文件还在 VFS 里,从里面读出字节、包成 Blob,再用一个临时链接交给浏览器下载。
// 从 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);
完整代码
把上面四步放回一个 App 组件,就是可直接运行的完整示例。
function App() {
const setExpiryDate = 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 对象并加载文档
const doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 过期校验脚本:当前时间晚于设定日期就提示并关闭文档
const script =
"var rightNow = new Date();" +
"var endDate = new Date('January 1, 2026 23:59:59');" +
"if (rightNow.getTime() > endDate.getTime()) {" +
"app.alert('本文档已过期,请联系我们获取新版本。', 1);" +
"this.closeDoc();" +
"}";
// 把脚本包成 JavaScript 动作,挂到文档的打开后动作
doc.AfterOpenAction = new pdfModule.PdfJavaScriptAction(script);
// 保存文档
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={setExpiryDate}>
开始设置
</button>
</div>
);
}
export default App;
给合同模板设置好过期日期后,用支持 JavaScript 的阅读器打开,过了期的文档会弹出提示并随即关闭:

常见问题
为什么设置后打开文档没有弹出提示
原因:过期校验靠阅读器执行文档里的 JavaScript 动作。浏览器内置的 PDF 查看器、系统自带的预览工具大多不执行内嵌脚本,只有支持 JavaScript 的阅读器(如 Adobe Acrobat、Acrobat Reader)才会在打开文档时运行它。
解决:换用支持 JavaScript 的阅读器打开生成的 PDF。脚本已经写进文档,换一个阅读器就能看到效果,不必重新生成。
文档过期后,内容就完全看不到了吗
原因:脚本做的是弹提示、关掉当前阅读会话,它不改动文档内容,也没有加密。文件本身还是普通 PDF,换成不执行脚本的工具照样能打开、能提取文字。
解决:要真正拦住访问,得给文档加密并设置打开密码或操作权限;过期脚本起到的是提醒与劝阻的作用,不等同于访问控制。
想换一个过期日期或改提示文字,怎么改
原因:日期和提示都是脚本里的字符串字面量——new Date('…') 里的日期、app.alert('…') 里的文字。它们随脚本一起写进文档的打开动作,事后改文档属性不会影响它。
解决:改脚本里的这两个字符串,再生成一次文档:
const script =
"var rightNow = new Date();" +
"var endDate = new Date('December 31, 2026 23:59:59');" + // 换成新的过期时刻
"if (rightNow.getTime() > endDate.getTime()) {" +
"app.alert('试用已到期,请购买正式版。', 1);" + // 换成新的提示文字
"this.closeDoc();" +
"}";
想让文档在「打开后 30 天」过期,该怎么设
原因:脚本在每次打开文档时执行,new Date() 取到的是打开那一刻的系统时间。如果日期也拿打开当刻去推算,比如 new Date() 再加 30 天,那每次打开算出来的到期时刻都在往后移,文档永远不会真正过期。
解决:把过期日期写成固定值,在生成时就把 30 天后那一刻算好填进去,脚本只管拿当前时间和它比:
// 生成时算好固定时刻,写进脚本;不要留到打开时再算
"var endDate = new Date('October 15, 2026 23:59:59');" +
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。









