找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 36|回复: 4

[转载代码] 办公WPS中自定义功能区按钮,对接JSA

[复制链接]
发表于 5 小时前 | 显示全部楼层 |阅读模式
本帖最后由 cutebe 于 2026-6-13 16:47 编辑

文件名:自定义功能区.xlsm
目录结构:内部文件一:_rels\.rels;内部文件二:customUI\customUI.xml        //重要文件两个

查看方法
方法一:改扩展名为.zip,用解压软件打开;
方法二:用Ribbon XML Editor v9.4汉化版打开,直接显示。

内部文件说明
第一点:内部文件名:.rels
类型为功能扩展:Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility"
界面文件路径为:Target="customUI/customUI.xml"        //第二点有说明
  1. <?xml version="1.0" standalone="yes"?>
  2. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  3.         <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  4.         <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
  5.         <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
  6.         <Relationship Id="customUI2007RelID" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
  7. </Relationships>
复制代码


第二点:内部文件名:customUI.xml
界面文件:功能区自定义一个标签,下含三个按钮。其中第一个按钮与函数关联
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  3.         <ribbon startFromScratch="false">
  4.                 <tabs>
  5.                         <tab id="tba" label="自定义功能区标签" >
  6.                                 <group id="g1" label="组">
  7.                                         <button id="b1" label="按钮一" onAction="检测ffi" />
  8.                                         <button id="b2" label="按钮二" />
  9.                                         <button id="b3" label="按钮三" />
  10.                                 </group>
  11.                         </tab>
  12.                 </tabs>
  13.         </ribbon>
  14. </customUI>
复制代码


//代码JSA:WPS宏编辑器        //开发工具》查询代码
  1. function 检测ffi(){测试外部函数接口ffi支持与否();}

  2. function 测试外部函数接口ffi支持与否(){        //测试ffi支持与否
  3.         //支持ffi开始:WPS 12.1.0.23542 版本及以上
  4.         console.log(ffi);        //若提示“引用错误:ffi is not defined”,则表示不支持!
  5.         //不支持原因:一、版本低;二、精简版删除了ffi或未开启。
  6. }
复制代码

 楼主| 发表于 5 小时前 | 显示全部楼层

基础中设置加载按钮,方便 添加/修改 界面功能

//基础.xlam:.rels
  1. <?xml version="1.0" standalone="yes"?>
  2. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  3.         <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
  4.         <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
  5.         <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  6.         <Relationship Id="rId5" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
  7.         <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/>
  8. </Relationships>
复制代码


//基础.xlam:customUI.xml
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  3.         <ribbon startFromScratch="false">
  4.                 <tabs>
  5.                         <tab idMso="TabHome"><!--开始标签-->
  6.                                 <group id="gBase" label="系统自带" insertBeforeMso="ShowClipboard"><!--组在剪贴板前面-->
  7.                                         <button id="btLoad" label="加载" onAction="加载常用便捷" size="large" imageMso="FillUp" />
  8.                                 </group>
  9.                         </tab>
  10.                 </tabs>
  11.         </ribbon>
  12. </customUI>
复制代码


//基础.xlam:JSA
  1. function 加载常用便捷(){        //大按钮在 开始 标签末尾
  2.         let 常用便捷加载项=Application.AddIns.Add("D:\\Program Files (x86)\\功能区\\功能区JSA\\常用便捷.xlam");        //添加到列表
  3.         常用便捷加载项.Installed=true;        //打勾
  4. }
  5. function 卸去常用便捷(){
  6.         let 常用便捷加载项=Application.AddIns.Item("常用便捷");
  7.         常用便捷加载项.Installed=false;        //不打勾
  8. }
复制代码


//常用便捷..xlam:.rels
  1. <?xml version="1.0" standalone="yes"?>
  2. <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  3.         <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
  4.         <Relationship Id="rId3" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
  5.         <Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
  6.         <Relationship Id="rId5" Type="http://schemas.microsoft.com/office/2006/relationships/ui/extensibility" Target="customUI/customUI.xml"/>
  7.         <Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties" Target="docProps/custom.xml"/>
  8. </Relationships>
复制代码


//常用便捷.xlam:customUI.xml
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  3.         <ribbon startFromScratch="false">
  4.                 <tabs>
  5.                         <tab idMso="TabHome"><!--开始标签-->
  6.                                 <group idQ="gBase" label="系统自带"><!--之前有的自定义组用idQ-->
  7.                                         <button idMso="ViewCode" label="代码查看" insertBeforeQ="btLoad" size="large" /><!--在加载前面-->
  8.                                 </group>
  9.                         </tab>
  10.                         <tab id="tab1" label="常用便捷">
  11.                                 <group id="sys" label="系统组">
  12.                                         <button idMso="ViewCode" label="查看代码" size="large" />
  13.                                         <button idMso="AlignCenter" label="水平居中" />
  14.                                         <button idMso="MergeCenter" label="合并居中" />
  15.                                         <button idMso="AlignMiddleExcel" label="垂直居中" />
  16.                                 </group>
  17.                                 <group id="g2" label="定制组">
  18.                                         <button id="b21" label="六位编码居中" onAction="六位编码居中" />
  19.                                         <button id="b22" label="新增黄底红字" onAction="新增黄底红字" />
  20.                                         <button id="b22" label="单元格不换行" onAction="单元格不换行" />
  21.                                 </group>
  22.                                 <group id="g3" label="检验组">
  23.                                         <button id="b31" label="外部函数接口" onAction="测试外部函数接口ffi" />
  24.                                         <button id="b32" label="检验条码" onAction="检验条码" />
  25.                                         <button id="b33" label="检验追溯码" onAction="检验追溯码" />
  26.                                         <button id="b34" label="卸去" onAction="卸去常用便捷" size="large" imageMso="FillDown" />
  27.                                 </group>
  28.                         </tab>
  29.                 </tabs>
  30.         </ribbon>
  31. </customUI>
复制代码


//常用便捷.xlam:JSA
  1. function 六位编码居中(){
  2.         var 选区=Selection;
  3.         选区.NumberFormat="000000";        //六位数字格式
  4.         选区.HorizontalAlignment=-4108;        //水平居中
  5.         选区.VerticalAlignment=-4108;        //垂直居中
  6. }
  7. function 新增黄底红字(){
  8.         选区=Selection;
  9.         选区.Value2="新增";
  10.         选区.Font.Color=0xFF;        //红色
  11.         选区.Interior.Color=0xFFFF;        //黄底
  12. }
  13. function 单元格不换行(){
  14.         选区=Selection;        //取消水平两端对齐(-4130)
  15.         if(选区.HorizontalAlignment==-4130){选区.HorizontalAlignment=1;}
  16.         选区.WrapText=0;        //取消自动换行
  17. }
  18. function 测试外部函数接口ffi(){        //测试ffi支持与否
  19.         //支持ffi开始:WPS 12.1.0.23542 版本及以上
  20.         console.log(ffi);        //若提示“引用错误:ffi is not defined”,则表示不支持!
  21.         //不支持原因:一、版本低;二、精简版删除了ffi或未开启。
  22. }
  23. function 检验条码(){
  24.         alert("条码13位,“69”开头");
  25. }
  26. function 检验追溯码(){
  27.         alert("追溯码20位,“8”开头,前七位为识别码");
  28. }
  29. function 卸去常用便捷(){        //方便修改功能区按钮
  30.         let 常用便捷加载项=Application.AddIns.Item("常用便捷");
  31.         常用便捷加载项.Installed=false;        //不打勾
  32. }
复制代码
 楼主| 发表于 1 小时前 | 显示全部楼层

未调用WinAPI代码

函数JS
  1. function 随机整数(起始数,终止数){
  2.         return Math.floor(Math.random()*(终止数-起始数+1))+起始数;
  3. }
复制代码
 楼主| 发表于 1 小时前 | 显示全部楼层

调用WinAPI的小功能代码

一个一个小功能
  1. function 设置剪贴板文本(文本内容){        //参数为字符串
  2.         let 执行宏调用=ExecuteExcel4Macro;        //调用系统应用接口。简化书写
  3.         if (执行宏调用(`CALL("User32","OpenClipboard","AJ",0)`)){        //打开剪贴板
  4.                 if(执行宏调用(`CALL("User32","EmptyClipboard","A")`)){        //清空剪切板
  5.                         const 内存句柄=字符串到内存(文本内容);        /*-----调用函数-----*/
  6.                         if(内存句柄){        //console.log("内存块大小:"+执行宏调用(`CALL("Kernel32","GlobalSize","JJ",${内存句柄})`));
  7.                                 let 剪贴板文本=执行宏调用(`CALL("User32","SetClipboardData","JJJ",1,${内存句柄})`);
  8.                                 执行宏调用(`CALL("Kernel32","GlobalFree","JJ",${内存句柄})`);        //释放内存
  9.                         }else{console.log("未能分配内存!");}        //数据放入剪切板,参数为1(CF_TEXT)则返回文本
  10.                 }else{console.log('未能清空剪贴板!');}
  11.                 执行宏调用(`CALL("User32","CloseClipboard","A")`);        //关闭剪贴板,以释放控制权。
  12.         }else{alert('无法打开剪贴板!');}
  13. }

  14. function 获取剪贴板文本(){        //返回字符串
  15.         const 执行宏调用=ExecuteExcel4Macro;
  16.         if(执行宏调用(`CALL("User32","OpenClipboard","JJ",0)`)){        //打开剪贴板
  17.                 const 内存句柄=执行宏调用(`CALL("User32","GetClipboardData","JJ",1)`);        //获取剪贴板文本,返回句柄。
  18.                 if(内存句柄){        //锁定全局内存对象,获取内存地址
  19.                         var 剪贴板文本=内存取字符串(内存句柄);        /*-----调用函数-----*/
  20.                 }else{console.log("未能获取剪贴板数据的内存句柄!");}
  21.                 执行宏调用(`CALL("User32","CloseClipboard","J")`);        //关闭剪贴板,让其它应用可以使用剪贴板
  22.                 return 剪贴板文本;        //返回字符串
  23.         }else{alert('无法打开剪贴板!');}
  24. }

  25. function 字符串到内存(字符串){        //返回内存句柄
  26.         const 执行宏调用=ExecuteExcel4Macro;
  27.         let 分段文本=[],分段字节=[],总字节=0,段长度=127;        //可申请256字节内存,结束符1字节,汉字最长127
  28.         for(let 起始=i=0;起始<字符串.length;起始+=段长度,i++){
  29.                 分段文本.push(字符串.slice(起始,起始+段长度));
  30.                 分段字节.push(分段文本[i].replace(/[^\x00-\xff]/g,'xx').length);        //一个汉字占两个字节
  31.                 总字节+=分段字节[i];
  32.         }        //分配内存        //分配GlobalAlloc对应销毁GlobalFree        //分配LocalAlloc对应销毁LocalFree
  33.         const 内存句柄=执行宏调用(`CALL("Kernel32","GlobalAlloc","JJJ",${0x42},${总字节+1})`);
  34.         if(内存句柄){        //内存分配成功,然后锁写解内存。        //锁定全局内存对象,会返回其内存地址
  35.                 const 内存地址=执行宏调用(`CALL("Kernel32","GlobalLock","JJ",${内存句柄})`);
  36.                 for(let 偏移字节=i=0;i<分段文本.length;i++){        //字符串(JS变量)分批复制到刚申请的内存中。分批是因为有限长
  37.                         执行宏调用(`CALL("Kernel32","lstrcpynW","JJFJ",${内存地址+偏移字节},"${分段文本[i].replace(/\"/g,'\"\"')}",${分段字节[i]})`);
  38.                         偏移字节+=分段字节[i];        //返回地址J。        //字符串中含双引号出错,因此替换成单引号
  39.                 }
  40.                 执行宏调用(`CALL("Kernel32","GlobalUnlock","JJ",${内存句柄})`);        //解锁全局内存对象,以释放资源
  41.                 return 内存句柄;
  42.         }else{console.log("未能分配内存!");}
  43. }

  44. function 内存取字符串(内存句柄){        //返回字符串
  45.         const 执行宏调用=ExecuteExcel4Macro,段长度=127;
  46.         const 内存地址=执行宏调用(`CALL("Kernel32","GlobalLock","JJ",${内存句柄})`);        //锁定,获取内存地址
  47.         if(内存地址){
  48.                 const 总字节=执行宏调用(`CALL("Kernel32","lstrlenA","JJ",${内存地址})`);        //内存文本字节数
  49.                 let 偏移字节=0,文本字符串=分段文本='';
  50.                 while(偏移字节<总字节){        //返回字符串F。        //返回超255字节时,也需要分段操作
  51.                         分段文本=执行宏调用(`CALL("Kernel32","lstrcpynW","FFJJ","",${内存地址+偏移字节},${段长度})`);
  52.                         //偏移字节+=执行宏调用(`CALL("Kernel32","lstrlenA","JC","${分段文本.replace(/["\n]/g,'x')}")`);
  53.                         偏移字节+=分段文本.replace(/[^\x00-\xff]/g,'xx').length;        //计算字符串字节数
  54.                         //偏移字节+=执行宏调用(`LENB("${分段文本.replace(/"/g,'x')}")`);
  55.                         文本字符串+=分段文本;
  56.                 }        //解锁全局内存对象,以释放资源
  57.                 执行宏调用(`CALL("Kernel32","GlobalUnlock","JJ",${内存句柄})`);
  58.                 return 文本字符串;
  59.         }else{console.log("未找到内存地址!");}
  60. }
复制代码
 楼主| 发表于 1 小时前 | 显示全部楼层

调用WinAPI基础小单元

单个WinAPI函数对应一个JS函数
  1. function 打开剪贴板(){
  2.         const 执行宏调用=ExecuteExcel4Macro;
  3.         let 打开结果=执行宏调用(`CALL("User32","OpenClipboard","AJ",0)`);
  4.         return 打开结果;        //if(打开结果){console.log("成功打开剪贴板!");}else{console.log("剪贴板打开失败。");}
  5. }
  6. function 清空剪贴板(){
  7.         const 执行宏调用=ExecuteExcel4Macro;
  8.         let 清空结果=执行宏调用(`CALL("User32","EmptyClipboard","A")`);
  9.         return 清空结果;        //if(清空结果){console.log("成功清空剪贴板!");}else{console.log("剪贴板清空失败。");}
  10. }
  11. function 设置剪贴板(数据格式,数据句柄){
  12.         const 执行宏调用=ExecuteExcel4Macro;        //数据格式:位图2 文本1 统一文本0xD=13
  13.         let 数据内存句柄=执行宏调用(`CALL("User32","SetClipboardData","JJJ",${数据格式},${数据句柄})`);
  14.         return 数据内存句柄;        //if(数据内存句柄){console.log("成功设置剪贴板!");}else{console.log("剪贴板设置失败。");}
  15. }
  16. function 关闭剪贴板(){
  17.         const 执行宏调用=ExecuteExcel4Macro;
  18.         let 关闭结果=执行宏调用(`CALL("User32","CloseClipboard","A")`);
  19.         return 关闭结果;        //if(关闭结果){console.log("成功关闭剪贴板!");}else{console.log("剪贴板关闭失败。");}
  20. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-6-13 17:20

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表