简介:本资源是面向JavaScript开发者与WPS办公自动化需求者的WPSJS插件开发实战项目包,聚焦Web技术扩展WPS文档处理能力,解决插件环境搭建、调试发布、前后端通信及按钮/保存/事件等核心功能落地难题。压缩包共65个文件,含18个JS主逻辑与接口调用脚本、6个TS类型定义文件、7个HTML前端界面模板、5个JSON配置(如package.json、ribbon.xml)、3个MD说明文档(含中英文README),以及SVG图标、CSS样式、字体与许可证等配套资源,整体仅765KB,轻量易部署。已有476人学习下载,适合中初级前端开发者快速入门WPS生态扩展开发。资源直接提供可运行的项目骨架、wpsjs工具链完整命令实践(create/debug/build/publish)、官方API集成示例及插件安装全流程指引,结构清晰对应开发阶段——plugin目录承载核心逻辑,server与wpsweb体现跨端通信设计,LICENSE与README保障合规复用。
1. WPSJS插件开发指南:为什么写个「插入当前日期」按钮要配三套环境、改五次 manifest.json、最后卡在签名验证上?
这不是一份泛泛而谈的“WPS宏入门”,而是某高校实验室在落地一个跨部门文档协同工具时,被 WPSJS 插件体系真实按在地上摩擦了 37 天后,把血泪经验拧成的一份可复现、可调试、可上线的实战笔记。它解决的是:你写完一段 JavaScript,怎么让它真正在 WPS 文字/表格/演示里跑起来?不是靠宏录制器点几下,也不是靠 Office Add-in 那套 Web API 套壳——是原生支持.wpsjs包、能调APIs.Application、能监听onDocumentChange、能弹出Dialog.show()的那一套。适合刚从 Excel VBA 或 Web 前端转过来、手握fetch()却在WPS.Dom文档里找不到.querySelector()的开发者;也适合团队里那个被临时抓壮丁、被告知“WPS 也能做插件,和 Office 差不多”的工程师。它不讲“WPSJS 是什么”,只回答:第一步该下哪个 SDK、第二步npm run build后生成的.wpsjs文件为什么双击打不开、第三步调试时控制台连console.log都不输出——到底在哪看日志?
2. 搭建可调试的本地开发环境:从零配置到WPS.run成功执行
WPSJS 插件不是网页,也不是 Node.js 脚本,它运行在 WPS 自研的 JS 引擎(基于 Chromium Embedded Framework + 定制 JSBridge)中。这意味着:没有node_modules全局共享,没有localhost:3000热更新,甚至没有标准window对象。一切必须围绕 WPS 提供的wps-js-sdk和其构建链路展开。
2.1 下载并初始化官方 SDK:别碰 npm registry 上的“wps-js-sdk”
WPS 官方未将 SDK 发布至公共 npm 仓库。所谓“npm install wps-js-sdk”是常见翻车起点——那是个同名但早已废弃的社区包,与当前 WPS 2023+ 版本完全不兼容。正确路径是:访问 WPS 开放平台官网(open.wps.cn),登录后进入「插件开发」→「SDK 下载」页,下载最新版wps-js-sdk-vX.X.X.zip(截至 2024 年中,稳定版为 v2.4.0)。
解压后你会得到:
/sdk/:核心类型定义(.d.ts)、API 文档 HTML、示例代码/tools/:wpsjs-cli可执行文件(Windows 为.exe,macOS 为二进制)/templates/:basic、dialog、ribbon三类模板项目
提示:
wpsjs-cli是构建和签名的唯一可信入口。它不依赖 Node.js 全局环境,自身已打包所需 runtime。不要试图用npx或yarn create替代。
2.2 用 CLI 创建最小可运行项目:绕过所有 Webpack 配置陷阱
执行以下命令(以 Windows 为例,路径需替换为你的实际解压路径):
# 进入 SDK tools 目录 cd D:\wps-js-sdk-v2.4.0\tools # 创建基础插件项目(会生成 ./my-plugin/) wpsjs-cli create my-plugin --template basic # 进入项目目录 cd ..\my-plugin此时my-plugin/结构为:
my-plugin/ ├── manifest.json # 插件元信息,必改! ├── index.html # 插件主界面(仅 ribbon/dialog 类型需要) ├── index.js # 主逻辑入口,WPS 启动时自动加载 ├── assets/ # 图标等静态资源 └── package.json # 仅用于 CLI 识别,无实际构建作用关键不是写代码,而是让index.js被 WPS 正确加载。WPSJS 不执行<script src="index.js">,而是直接eval()index.js内容,并注入全局WPS对象。因此index.js必须是 IIFE 或顶层同步逻辑:
// my-plugin/index.js (function () { // 1. 确保 WPS 对象存在(开发时可能未就绪) if (typeof WPS === 'undefined') { console.warn('WPS global object not available yet'); return; } // 2. 注册插件启动回调(必须!否则不会触发) WPS.onReady(function () { console.log('✅ WPSJS plugin loaded and ready'); // 3. 调用最基础 API 验证环境 try { const app = WPS.Application; console.log('App name:', app.Name); // 输出 "WPS文字" / "WPS表格" console.log('App version:', app.Version); } catch (e) { console.error('❌ Failed to access WPS.Application:', e); } }); })();2.3 构建与安装:.wpsjs包不是 ZIP,签名是硬门槛
WPSJS 插件包是经过特定签名的 ZIP 文件,扩展名为.wpsjs。未签名的包,WPS 会直接拒绝加载,且不报任何错误提示——这是新手最大黑洞。构建命令必须使用 CLI:
# 在 my-plugin/ 目录下执行(注意:不是 npm run build!) ..\..\tools\wpsjs-cli build成功后生成dist/my-plugin.wpsjs。此时不能双击安装——WPS 要求插件必须通过「开发模式」手动加载:
- 打开 WPS 文字(确保是 2023 或更新版本)
- 「文件」→「选项」→「插件」→「开发模式」→ 打开开关
- 点击「安装插件」→ 选择
dist/my-plugin.wpsjs - 重启 WPS(必须!)
参数说明:
wpsjs-cli build默认读取manifest.json中的name、version、description生成包。它会自动压缩index.js、index.html(如有)、assets/下所有文件,并用 SDK 内置密钥签名。不要手动修改dist/下的.wpsjs文件内容,签名会立即失效。
3. manifest.json 核心字段详解:为什么改了图标却显示默认齿轮?
manifest.json是 WPSJS 插件的身份证,字段缺失或格式错误会导致插件静默失败。它不是 Chrome Extension 的 manifest,不支持content_scripts、permissions等字段。以下是生产环境必须精确配置的 5 个字段:
| 字段 | 类型 | 必填 | 说明 | 常见错误 |
|---|---|---|---|---|
name | string | ✅ | 插件显示名称(中文 OK),长度 ≤ 32 字符 | 使用空格或特殊符号如&、<导致解析失败 |
version | string | ✅ | 语义化版本号(如"1.0.0"),必须为 x.y.z 格式 | 写成"1.0"或"v1.0.0"会被拒绝 |
description | string | ⚠️ | 描述(≤ 128 字符),不填则显示空白 | 包含换行符\n或未转义引号" |
icons | object | ✅ | 图标尺寸映射,必须同时提供16x16和32x32 | 只提供48x48,WPS 任务栏图标显示为默认齿轮 |
applications | object | ✅ | 指定支持的 WPS 应用及最低版本 | 错误写成"wps": "2022"(应为"wps": "12.0.0.0") |
一个经实测可用的manifest.json示例:
{ "name": "文档时间戳助手", "version": "1.2.0", "description": "一键插入带格式的当前日期和时间", "icons": { "16x16": "assets/icon16.png", "32x32": "assets/icon32.png" }, "applications": { "wps": "12.0.0.0" } }注意:
applications.wps的版本号对应 WPS 内部 Build 号,非市场宣传版本。查询方法:打开 WPS →「帮助」→「关于 WPS 文字」→ 查看「版本号」字段(如12.0.0.12345),取前四位即可。低于该版本的 WPS 将完全不显示此插件。
4. 调试与日志:当console.log不输出时,去哪找你的undefined?
WPSJS 的调试体验远不如浏览器 DevTools。console.log默认不输出到任何可见窗口,debugger断点无效,alert()被禁用。真正的调试路径只有两条:日志文件 + WPS 内置调试器。
4.1 日志文件:定位WPS.Application未定义的根本原因
WPSJS 将所有console.*输出重定向至本地日志文件。路径因系统而异:
- Windows:
%APPDATA%\Kingsoft\WPS Office\logs\wpsjs\plugin-name\ - macOS:
~/Library/Application Support/Kingsoft/WPS Office/logs/wpsjs/plugin-name/
每个插件有独立子目录,内含console.log(主日志)和error.log(异常堆栈)。例如,你的插件name为"文档时间戳助手",日志路径为:
Windows: C:\Users\YourName\AppData\Roaming\Kingsoft\WPS Office\logs\wpsjs\文档时间戳助手\ macOS: /Users/YourName/Library/Application Support/Kingsoft/WPS Office/logs/wpsjs/文档时间戳助手/日志文件是纯文本,按行记录,格式为:
[2024-06-15 14:22:31.123] INFO: ✅ WPSJS plugin loaded and ready [2024-06-15 14:22:31.456] ERROR: TypeError: Cannot read property 'Name' of undefined玄学经验:如果
console.log完全没出现在日志里,90% 是manifest.json格式错误(如多了一个逗号)或index.js语法错误(如const声明在严格模式外),导致整个脚本未被eval()执行。此时需检查error.log开头是否有SyntaxError。
4.2 启用 WPS 内置调试器:看到真实的WPS.Dom对象结构
WPS 提供了类似 Chrome DevTools 的调试面板,但需手动开启:
- 确保 WPS 处于「开发模式」(见 2.3 节)
- 按快捷键
Ctrl + Shift + I(Windows)或Cmd + Option + I(macOS) - 弹出窗口即为 WPSJS 调试器,包含
Console、Sources、Elements三页
Console页:可输入WPS.Application.Name实时执行,验证 API 可用性Sources页:自动加载index.js源码(无需 sourcemap),可设断点(仅对WPS.onReady回调内代码有效)Elements页:显示 WPS 文档 DOM 结构(WPS.Dom.document),可右键Inspect查看节点
血泪经验:调试器
Console页的this指向 WPSJS 全局上下文,而非浏览器window。在这里执行document.getElementById会报错,必须用WPS.Dom.document.getElementById—— 这是WPS.Dom与浏览器 DOM 的根本隔离点。
5. 避坑指南:那些让你怀疑人生、重装三次 WPS 的典型问题
WPSJS 插件开发的坑不在代码逻辑,而在环境、配置、版本的隐式耦合。以下是某开发者在模拟项目 X 中踩过的 5 个高频、隐蔽、且官方文档几乎不提的坑,按「现象 → 原因 → 解决」结构整理:
5.1 现象:插件安装后,在「插件中心」列表里显示为「未启用」,点击启用无反应
原因:manifest.json中applications.wps版本号高于当前 WPS 版本。例如你写了"wps": "13.0.0.0",但实际 WPS 是12.0.0.12345。WPS 不提示版本不匹配,而是静默禁用。
解决:打开 WPS →「帮助」→「关于」,复制完整版本号(如12.0.0.12345),取前四位填入manifest.json,重新build并安装。
5.2 现象:WPS.Application.ActiveDocument返回null,但文档明明已打开
原因:WPSJS 插件加载时机早于文档初始化完成。WPS.onReady只保证 WPS 引擎就绪,不保证文档已加载。
解决:监听WPS.Application.OnDocumentChange事件,而非在onReady内直接访问ActiveDocument:
WPS.onReady(function () { console.log('WPS engine ready'); // ✅ 正确:等待文档事件 WPS.Application.OnDocumentChange = function () { const doc = WPS.Application.ActiveDocument; if (doc) { console.log('Document loaded:', doc.Name); // 此处执行文档操作 } }; });5.3 现象:index.js中import语法报错SyntaxError: Unexpected token 'export'
原因:WPSJS 引擎(基于较老 V8)不支持 ES6 Module。wpsjs-cli build仅做文件打包,不做 AST 转译。
解决:彻底放弃import/export,改用 IIFE + 全局变量模拟模块:
// utils/dateHelper.js(不要 import!) window.DateHelper = { formatNow: function() { return new Date().toLocaleString(); } }; // index.js 中直接使用 WPS.onReady(function () { console.log('Now:', window.DateHelper.formatNow()); });5.4 现象:图标icon32.png显示为模糊马赛克,或完全不显示
原因:WPS 对图标文件有严格要求:必须为 PNG 格式、无透明通道(Alpha=255)、尺寸严格为32x32像素(非32x32pxCSS 尺寸)。常见设计稿导出时保留了透明背景。
解决:用 Photoshop 或在线工具(如 png-pixel.com)将图标背景填充为纯白(#FFFFFF),另存为icon32.png,再build。
5.5 现象:插件在 WPS 文字中正常,但在 WPS 表格中WPS.Application报undefined
原因:manifest.json中applications字段未声明et(WPS 表格代号)。WPSJS 按应用隔离运行环境,未声明的应用无法加载插件。
解决:补全applications,支持多应用:
"applications": { "wps": "12.0.0.0", "et": "12.0.0.0", "dps": "12.0.0.0" }其中wps=文字,et=表格,dps=演示。重新构建安装。
6. 进阶技巧:用WPS.Dialog实现无感交互,以及如何让插件「活」过 WPS 升级
WPSJS 插件的生命周期绑定 WPS 进程,但用户需求常要求「状态持久化」和「轻量交互」。WPS.Dialog是突破 UI 限制的关键 API,而插件升级策略则决定长期维护成本。
6.1 用WPS.Dialog替代alert/prompt:实现真正可用的用户反馈
WPS 禁用浏览器原生弹窗,但提供了WPS.Dialog对象,支持自定义 HTML 内容、按钮、回调。它不阻塞主线程,且样式与 WPS 原生一致:
// 在 index.js 中定义对话框 function showTimestampDialog() { const html = ` <div style="padding:16px;"> <h3>插入时间戳</h3> <p>请选择格式:</p> <select id="formatSelect" style="width:100%;margin:8px 0;"> <option value="full">2024年06月15日 14:30:22</option> <option value="date">2024-06-15</option> <option value="time">14:30:22</option> </select> <div style="margin-top:12px;text-align:right;"> <button onclick="WPS.Dialog.close(true)" style="margin-right:8px;">确定</button> <button onclick="WPS.Dialog.close(false)">取消</button> </div> </div> `; WPS.Dialog.show({ title: "时间戳助手", width: 320, height: 180, html: html, onClosed: function (result) { if (result === true) { const format = document.getElementById('formatSelect').value; insertTimestamp(format); } } }); } // 插入时间戳到当前光标位置 function insertTimestamp(format) { const doc = WPS.Application.ActiveDocument; if (!doc) return; let text = ''; const now = new Date(); switch (format) { case 'full': text = now.toLocaleString('zh-CN'); break; case 'date': text = now.toLocaleDateString('zh-CN'); break; case 'time': text = now.toLocaleTimeString('zh-CN'); break; } // 获取当前 Selection(光标位置) const sel = WPS.Application.Selection; if (sel) { sel.Text = text; // 直接替换选区或插入光标处 } }关键点:
WPS.Dialog.show()的html参数是字符串,不是 URL;onClosed回调中result由WPS.Dialog.close(value)的value决定;对话框内 JS 可直接访问WPS全局对象,无需额外注入。
6.2 插件升级策略:如何避免每次 WPS 更新都重签重装?
WPSJS 插件升级不是覆盖安装,而是「卸载旧版 → 安装新版」。但用户数据(如用户偏好设置)易丢失。解决方案是利用WPS.StorageAPI(WPS 提供的本地存储):
// 保存用户设置 function saveSettings(settings) { try { WPS.Storage.setItem('timestamp_format', settings.format); WPS.Storage.setItem('auto_insert', settings.autoInsert ? '1' : '0'); } catch (e) { console.error('Failed to save settings:', e); } } // 读取用户设置(在 WPS.onReady 后调用) function loadSettings() { const format = WPS.Storage.getItem('timestamp_format') || 'full'; const autoInsert = WPS.Storage.getItem('auto_insert') === '1'; return { format, autoInsert }; } // 使用示例 WPS.onReady(function () { const settings = loadSettings(); console.log('Loaded settings:', settings); });WPS.Storage是持久化、应用级(非插件级)存储,即使插件卸载,数据仍保留在 WPS 用户配置中。这是让插件具备「用户心智」的核心——下次安装,用户看到的还是他上次选的格式。
6.3 最后一条习惯:永远在manifest.json里加build时间戳
WPS 缓存插件包极深,有时build新包后仍加载旧逻辑。终极排查法是在manifest.json加一个动态字段:
{ "name": "文档时间戳助手", "version": "1.2.0", "build_time": "2024-06-15T14:30:00Z", ... }然后在index.js开头打印:
console.log('Plugin build time:', WPS.manifest.build_time);这样每次build后,日志第一行就能确认是否加载了最新包。这招看似笨拙,却是我在某跨平台系统中连续三天查不出缓存问题后的后悔药。
希望帮到你。
本文还有配套的精品资源,点击获取