ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

WPS插件开发实战:用DeepSeek API打造智能摘要与润色助手

WPS插件开发实战:用DeepSeek API打造智能摘要与润色助手 简介WPS DeepSeek API办公插件开发全流程记录共33页面向希望将DeepSeek智能能力融入WPS的开发者完整梳理了从需求调研、开发环境配置、插件架构设计到DeepSeek API接入、文本生成/翻译/格式调整/信息检索等功能模块开发再到WPS菜单工具栏集成、测试优化与部署发布的实战路径。整个资源为单份PDF文件大小2.16MB文档目录划分为引言、WPS与DeepSeek API简介、开发环境搭建、需求分析、架构设计、API集成、功能模块开发、深度集成实现、测试与优化、部署与发布、总结展望等部分结构完整清晰所有文字、图表显示正常。文档不仅说明了HTTP请求构造、响应解析、错误重试等API集成关键点还覆盖了功能测试、性能测试、兼容性测试、安全测试及插件打包发布等工程环节能帮助读者避开常见坑位、理解智能办公插件的端到端落地流程。目前该资源已有106人学习适合具备基础编程能力、从事办公插件或AI应用开发的研发人员参考。1. 把 DeepSeek API 接进 WPS 做智能插件这件事的本质是什么在 WPS 文字里选中一段三页纸的合同点一下功能区里的“智能摘要”十几秒后文档尾部出现结构化要点再选中一段陈旧的项目报告点“一键润色”文字通顺了段落样式却一点没动。做这种功能传统宏和正则已经不够用真正干活的是 DeepSeek APIWPS 侧要解决的是什么时候读文档、怎么把内容安全送进请求、响应回来后在哪个位置写回。这篇实录按完整开发链条拆解加载项工程怎么起、选区读取与 prompt 组装、DeepSeek chat 接口调用与格式回填、上线前必须处理的 Key 保管和超时兜底。适合两类人——给企业做办公自动化的工程师以及想把 WPS 变成个人 AI 工作台的开发者。2. WPS 插件开发基线在三条自动化路线里选对加载项方案2.1 VBA、JS 宏和 Web 加载项三条路的边界在哪里做 WPS 自动化先要回答一个问题用哪套运行时干活。老员工会打开开发者工具用 VBA稍新一点用 WPS 的 JS 宏JavaScript for WPS做产品化插件的人走 Web 加载项路线对标 Office Add-ins。三者不冲突但边界必须划清楚。VBA 的优势是兼容存量。企业的 .docm、表格模板多半是 VBA 写的能在 WPS 里直接跑。但 VBA 与 WPS 进程模型耦合很深调外部 HTTPS 接口要借助 WinHttp 对象解析 JSON 几乎靠字符串处理开发和维护成本都高。另一个常见痛点是 64 位 WPS 的 VBA 兼容性用户换到 64 位版本后32 位外部控件和 Declare 语句容易出问题网上大量“wps vba”“wps 64位 vba”的求助就是来自这个场景。JS 宏比 VBA 更接近现代 Web 工程。它运行在 WPS 内置 JS 引擎里可以直接用 XMLHttpRequest 或 fetch 发网络请求天然适合接 DeepSeek API。缺点是它本质是“宏”分发路径窄做不了复杂 UI任务窗格、配置界面都需要另想办法。Web 加载项是本文主推的路线。它本质上是一个注册到 WPS 的 HTML/JS 应用main.js 里可以完整操作文档对象同时渲染任务窗格或对话框。DeepSeek 接入、结果缓存、失败重试、用户配置界面全部按前端工程处理。三者对照如下维度VBA 宏JS 宏Web 加载项开发语言VBAJavaScriptHTML/CSS/JavaScriptHTTPS 调用WinHttp 可做但繁琐XMLHttpRequest 原生支持完整前端网络能力UI 能力简陋 UserForm弱主要靠对话框完整 HTML 页面分发方式.docm/模板加载项/模板加载项清单适合企业分发对接 DeepSeek 推荐度低中高真实项目的判定条件很简单如果你只处理自己手中的固定格式文档JS 宏够用如果功能要交给多个同事使用还有配置、日志、更新需求直接选 Web 加载项。本文代码全部基于 Web 加载项加原生 XMLHttpRequest这是唯一能同时满足网络请求和文档回填兼容性的组合。2.2 用 wpsjs 创建一个最小可运行的加载项工程WPS 官方维护的 wpsjs 工具链用于生成加载项骨架。以当前版本为例全局安装后执行生成命令就能得到工程目录npm install -g wpsjs wpsjs create DeepSeekHelper cd DeepSeekHelper工程里最重要的三个文件是 main.js、index.html 和 manifest.xmlDeepSeekHelper/ ├── main.js # 加载项主逻辑注册命令、读写文档 ├── index.html # 任务窗格界面用户输入与结果展示 ├── manifest.xml # 声明加载项的入口、权限、功能区 └── package.json # 构建与依赖main.js 是核心。WPS 加载插件时会把自身 JavaScript API 注入全局wps对象业务代码从wps.WpsApplication()获取应用引用再访问Document、Selection等对象。写一个最基本的选区读取函数// main.js —— 读取当前 WPS 文字里的选区 function getActiveSelectionInfo() { var wpsApp wps.WpsApplication(); var doc wpsApp.ActiveDocument; var sel doc.Selection; return { text: sel.Text, start: sel.Start, end: sel.End }; }代码逻辑很直白Selection对象指向文档当前高亮区域sel.Text拿纯文本sel.Start和sel.End是字符偏移量。不建议用剪贴板取选区因为剪贴板可能存着用户的其他数据读取操作会污染现场。如果没选中任何文字sel.Text仍是空字符串读取之后判断长度即可。2.3 功能区按钮到回调函数一次点击背后的注册链插件得有个用户入口。WPS 通过 manifest.xml 里的功能区声明把按钮加到工具栏每个按钮的 onAction 属性引用 main.js 里的一个全局函数。最小可用的功能区声明大致如下customUI xmlnshttp://schemas.microsoft.com/office/2009/07/customui ribbon tabs tab idcustomTab labelDeepSeek 助手 group iddeepseekGroup label智能办公 button idbtnSummarize label智能摘要 onActiononSummarize sizelarge / button idbtnPolish label一键润色 onActiononPolish sizelarge / /group /tab /tabs /ribbon /customUI对应的 main.js 里必须定义同名函数function onSummarize(control) { // control 是触发按钮的上下文对象 // 在这里实现完整流程读选区、调 API、写回文档 }踩坑预警onAction 指定的函数必须挂载在全局作用域。如果把函数包在模块闭包或 IIFE 里又没暴露出去点击按钮就会提示找不到命令。处理方式是显式写globalThis.onSummarize handleSummarize;或直接定义成普通顶层 function。另外WPS 加载项的调试信息进的是 WPS 开发者工具或日志不是浏览器 DevTools。点了按钮没反应先查 onAction 名称拼写再查 main.js 加载时有没有报错中断这两处占据了大多数空白点击故障。3. 把文档选区送进 DeepSeek API请求构造、参数和响应解析3.1 读取内容的完整封装选区、整篇文档与表格区域生产环境里读取内容不会只有选区一种情况。整理一个函数集合分别应付三种场景// 读取当前选中文本WPS 文字 function readSelection() { var wpsApp wps.WpsApplication(); var doc wpsApp.ActiveDocument; var sel doc.Selection; return sel.Text || ; } // 读取整篇正文压缩连续空白 function readDocument(trimSpaces) { var wpsApp wps.WpsApplication(); var doc wpsApp.ActiveDocument; var text doc.Content.Text; return trimSpaces ? text.replace(/\s/g, ) : text; }表格场景要单说。插件在 WPS 表格里工作时ActiveDocument的语义要换成ActiveSheet惯用做法是用range.Value2取二维数组再序列化成文本// 读取当前选定区域转成 Markdown 表格风格文本 function readTableSelection(maxRows) { var wpsApp wps.WpsApplication(); var sheet wpsApp.ActiveSheet; var range sheet.Range(sheet.Selection.Address); var values range.Value2; var rows values.slice(0, maxRows || 200); return rows.map(function (row, i) { return | row.join( | ) |; }).join(\n); }Value2返回嵌套数组第一层是行第二层是列。把行用竖线连成表格文本是为了让大模型认清行列关系。maxRows参数防止用户手滑选中十万行打爆 token 预算。真实项目里建议对行数和字符数双重截断超 8000 字符就提示用户缩小选区。3.2 构造 DeepSeek chat/completions 请求参数与模型怎么选DeepSeek API 对外兼容 OpenAI 接口格式请求体是 messages 数组。这意味着代码可以平滑切换 DeepSeek 与其他 OpenAI 兼容后端。常用模型有两个deepseek-chat适合摘要、润色、问答这类日常操作deepseek-reasoner带思维链适合需要逐步推理的复杂任务。办公场景默认选deepseek-chat响应更快、成本更低。下面封装了请求函数。为了兼容 WPS 加载项环境使用 XMLHttpRequest 而不是 fetch——WPS 不同版本对 fetch 的实现存在差异XHR 最稳妥// deepseekClient.js —— 所有 API 调用集中在这里 var DEEPSEEK_API_URL https://api.deepseek.com/chat/completions; function deepseekChat(apiKey, systemMessage, userMessage, onSuccess, onError) { var xhr new XMLHttpRequest(); xhr.open(POST, DEEPSEEK_API_URL, true); xhr.setRequestHeader(Content-Type, application/json); xhr.setRequestHeader(Authorization, Bearer apiKey); xhr.timeout 60000; xhr.onreadystatechange function () { if (xhr.readyState ! 4) return; if (xhr.status 200) { try { var data JSON.parse(xhr.responseText); // deepseek-chat 结果在 choices[0].message.content onSuccess(null, data.choices[0].message.content); } catch (e) { onError(e, null); } } else { onError(new Error(HTTP xhr.status : xhr.responseText), null); } }; xhr.ontimeout function () { onError(new Error(请求超时请稍后重试), null); }; xhr.send(JSON.stringify({ model: deepseek-chat, messages: [ { role: system, content: systemMessage }, { role: user, content: userMessage } ], temperature: 0.3, max_tokens: 2048 })); }参数调优参考表参数推荐值场景说明modeldeepseek-chat摘要润色用 chat多步推理换 reasonertemperature0.3摘要保持低值 0.1~0.3创意写作调到 0.7max_tokens2048长文摘要可升 4096控制响应长度timeout60000reasoner 思考可能超过 30 秒注意API Key 不能写死在 main.js 里。插件打包发人时Key 要放独立配置文件或在设置面板让用户自行填写第 5 章展开讲。3.3 响应回填的两种模式替换选区与插入文档末尾API 返回后业务最常见的两种操作是替换选区、插入新位置。先看替换选区function replaceSelectionWithText(newText) { var wpsApp wps.WpsApplication(); var doc wpsApp.ActiveDocument; var sel doc.Selection; if (sel.Text.length 0) { // 新文本会继承选区起点处的段落格式 sel.Text newText; } }直接给sel.Text赋值结果是原选区全部字符被替换新文本的字体、字号、颜色与选区起点处的段落样式一致。如果你希望 AI 返回内容保留加粗、斜体等字符级格式只靠sel.Text做不到因为纯文本赋值不携带格式信息。可靠做法是让 AI 返回干净文本再由前端按段落意图显式设置样式。插入新文档适用于“生成摘要”这类不能覆盖原文的场景function insertSummaryIntoNewDoc(title, content) { var wpsApp wps.WpsApplication(); var newDoc wpsApp.Documents.Add(); var range newDoc.Content; range.Text title \n content; range.Font.Size 12; range.ParagraphFormat.LineSpacing 1.5; }在原文末尾追加内容用doc.Range(end, end)动态取末尾位置function appendToDocEnd(doc, text) { var endPos doc.Content.End; var range doc.Range(endPos, endPos); range.Text \n text; }范围边界问题是 WPS JS 里很典型的 bug 源头。不少人用doc.Content.InsertAfter(text)部分版本运行正常但遇到带格式 Range 时插入内容会落错位置。用doc.Range(endPos, endPos)拿空 Range 再放文本是更可控的方式。顺带排一个高频报错wps.Application.Documents.Open在部分加载项版本里返回 undefined多数不是 API 缺失而是路径参数用了相对路径。先把当前工作目录打出来改用绝对路径即可。4. 深度集成实战智能摘要、一键润色和表格 AI 公式4.1 智能摘要选区读取、Prompt 压缩与结果落盘把前面的函数串起来一个完整“智能摘要”功能就成型了。核心逻辑用户选中正文点击功能区按钮main.js 读选区、拼 prompt、调 DeepSeek、把摘要追加到当前文档末尾。function onSummarize() { var text readSelection(); if (text.trim().length 50) { alert(请选中至少 50 个字符的内容再试); return; } // 截断超长文本保护 token 预算 var maxInput 8000; var trimmed text.length maxInput ? text.slice(0, maxInput) : text; var prompt 请为下面这段文字生成结构化摘要输出不超过 300 字 用第一点、第二点的要点形式\n\n trimmed; deepseekChat(apiKey, 你是一名严谨的办公文档助理, prompt, function (err, result) { if (err) { alert(摘要失败 err.message); return; } var wpsApp wps.WpsApplication(); appendToDocEnd(wpsApp.ActiveDocument, 【智能摘要】\n result); }, function (err) { alert(摘要请求失败 err.message); } ); }两个设计决策值得注意。第一截断不能偷偷进行超过 8000 字符时应在提示里说明“只处理了前 8000 字符”否则用户会以为全文参与了摘要。第二落盘到文档末尾而不是替换选区因为摘要语义上就不该覆盖原文。4.2 一键润色替换选区的格式继承与防覆盖校验润色与摘要的代码相似差异在 prompt 和写回方式。润色的用户期望是原文原地变通顺写回用sel.Text result。难的是处理异步时序function onPolish() { var selInfo getActiveSelectionInfo(); if (!selInfo.text || selInfo.text.trim().length 0) { alert(请先选中需要润色的文本); return; } var prompt 请把下面这段文字润色成书面化、条理清晰的版本。 只输出润色后的正文不要加解释、不要加引号\n\n selInfo.text.slice(0, 6000); deepseekChat(apiKey, 你是一名资深中文编辑追求语言简洁准确, prompt, function (err, result) { if (err) { alert(润色失败 err.message); return; } var wpsApp wps.WpsApplication(); var doc wpsApp.ActiveDocument; var sel doc.Selection; // 关键校验API 返回前用户可能切走了选区 if (sel.Start selInfo.start sel.End selInfo.end) { sel.Text result; } else { // 兜底不覆盖新区选提示用户手动粘贴 alert(原选区已改变请重新选中文本再执行润色); } }, function (err) { alert(润色请求失败 err.message); } ); }这里最重要的不是 API 调用而是sel.Start selInfo.start sel.End selInfo.end这个时序校验。API 请求是异步的用户等待的几秒内完全可能移动光标或另选内容。不做校验直接sel.Text result会把用户新选的内容也覆盖。这类 bug 演示时很难复现一上生产就频繁出现。4.3 表格里的 AI自定义函数与批量按钮两种用法场景再推进用户在 WPS 表格里维护一列客户反馈想逐行让 AI 给出情感结论。常见做法是注册自定义函数单元格里写AI_JUDGE(A2)// WPS 表格的 JS 宏环境注册自定义函数 function AI_JUDGE(cellText) { if (!cellText) return ; // 公式求值是同步的这里只能用同步请求 var result deepseekChatSync(cellText, 只返回三个字正面/中性/负面); return result; }克制地说这条路看起来漂亮但坑最多。WPS JS 宏的用户自定义函数没有统一的异步约定在公式里发异步请求单元格会先返回空值响应回来后再没法更新那个格子。常规解法有两条一是提供“批量处理”按钮选中一列后循环调异步 API逐行写回二是只用同步请求跑短文本场景严格限制行数和文本长度。推荐走批量按钮数据流完全可控function onBatchAnalyze() { var wpsApp wps.WpsApplication(); var sheet wpsApp.ActiveSheet; var rows sheet.UsedRange.Value2; // 假设 A 列是文本B 列写结果 for (var i 1; i rows.length; i) { (function (rowIndex) { deepseekChat(apiKey, 情感分析器, 请对以下文本做情感三分类只输出正面中性负面\n rows[rowIndex][0], function (err, result) { if (!err) { sheet.Cells(rowIndex 1, 2).Value2 result; } else { sheet.Cells(rowIndex 1, 2).Value2 错误; } }, function (err) { sheet.Cells(rowIndex 1, 2).Value2 错误; } ); })(i); } }循环里用 IIFE 闭包固定行号是异步循环的基本素养。不包闭包i在回调执行时早已递增到最后结果会全部写到末尾行。5. 上线前要处理的四个硬问题Key 安全、超时、分发与后台进程5.1 API Key 不能留在加载项前端代码里DeepSeek API Key 与账号费用直接绑定泄露就产生实际损失。千万别把 Key 硬编码在 main.js 里打包分发。稳妥模式是加载项同目录放config.json首次运行让用户填 Key敏感环境走本地反向代理加载项只请求本机 localhost由代理持有真实 Key别人按 F12 也抓不到。5.2 超时、取消与后台进程的清理deepseek-reasoner复杂推理可能耗 30 秒以上请求要设 60 秒超时界面上同步显示“处理中”。用户中途关掉任务窗格或 WPS 主界面时在unload事件里中止所有在途 XHR否则页面白屏后回调还在执行访问wps对象直接抛异常还会留下“WPS 界面关闭后后台还有一堆子程序运行”的现象。window.addEventListener(unload, function () { if (pendingXhr) pendingXhr.abort(); clearInterval(progressTimer); });5.3 分发依赖注册表WPS 安装目录不能剪切粘贴WPS 的安装信息写在注册表里。很多用户以为把整个 WPS 目录剪切到新盘符就行结果文件关联失效、插件从功能区消失原因就是注册表里的路径还是旧的。Office、WPS 这类依赖注册的软件正确迁移是先卸载再重装到目标路径最后重新注册加载项。加载项工程自身也一样凡是引用图标、config.json 的地方基于加载项所在目录动态解析不要写死绝对路径。5.4 64 位 WPS 的 VBA 兼容检查与功能区缓存64 位 WPS 的 VBA 引擎对 32 位外部控件和 Declare 语句有限制JS 宏倒不受影响。迁移存量 VBA 插件时建议在 32 位和 64 位环境各自跑一遍“打开文档、读选区、写回结果”的冒烟用例。另外改了 manifest.xml 后功能区按钮不更新可以先完全退出 WPS清掉%APPDATA%\kingsoft\office\data下的缓存状态再重启加载项开发阶段每次改声明都走这个流程能省下大量定位时间。本文还有配套的精品资源点击获取
返回列表