diff --git a/.drone.yml b/.drone.yml
new file mode 100644
index 0000000..d6f700d
--- /dev/null
+++ b/.drone.yml
@@ -0,0 +1,74 @@
+---
+kind: pipeline
+type: docker
+name: default
+
+platform:
+ arch: amd64
+
+
+steps:
+ - name: build
+ image: node:slim
+ commands:
+ - npm config set registry http://mirrors.cloud.tencent.com/npm/
+ - npm config get registry
+ - npm install -g wpsjs
+ - wpsjs publish -s https://wps.woni.link/jsplugindir/
+
+ - name: upload plugin
+ image: appleboy/drone-scp
+ pull: never
+ settings:
+ host:
+ from_secret: ssh_host
+ username:
+ from_secret: ssh_user
+ port: 22
+ password:
+ from_secret: ssh_key
+ tags: 0.1
+ target: /data/www-data/xbotwps
+ source: ./wps-addon-build/*
+
+ - name: upload pushlish.html
+ image: appleboy/drone-scp
+ pull: never
+ settings:
+ host:
+ from_secret: ssh_host
+ username:
+ from_secret: ssh_user
+ port: 22
+ password:
+ from_secret: ssh_key
+ tags: 0.1
+ target: /data/www-data/xbotwps
+ source: ./wps-addon-publish/publish.html
+
+ - name: adjust dirctory
+ image: appleboy/drone-ssh
+ pull: never
+ settings:
+ host:
+ from_secret: ssh_host
+ username:
+ from_secret: ssh_user
+ port: 22
+ password:
+ from_secret: ssh_key
+ script:
+ - cd /data/www-data/xbotwps/wps-addon-build
+ - rm -rf /data/www-data/xbotwps/jsplugindir
+ - mkdir /data/www-data/xbotwps/jsplugindir
+ - mv ./* ../jsplugindir
+ - cd /data/www-data/xbotwps/wps-addon-publish
+ - mv ./* ../jsplugindir
+ - rm -rf /data/www-data/xbotwps/wps-addon-build
+ - rm -rf /data/www-data/xbotwps/wps-addon-publish
+
+trigger:
+ branch:
+ include:
+ - main
+ - /^release-.*$/
diff --git a/README.md b/README.md
index ecffe9e..92dc0eb 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,4 @@
-# XBot 文字插件
-
-
+# WPS 插件自动化实现
## 配置相关
@@ -11,8 +9,34 @@
## 发版相关
+## 自动安装插件
+
+安装目录
+windows: %Appdata%\kingsoft\wps\jsaddons
+
+linux: .local/share/Kingsoft/wps/jsaddons
+
+authwebsite.xml
+```xml
+
+
+
+
+```
+
+publish.xml
+```xml
+
+
+
+
+```
+
+
## 资料相关
- https://open.wps.cn/previous/docs/client/wpsload
- https://gitee.com/wpsoa/wpsoa
+- https://blog.csdn.net/huaermeier/article/details/132502705
+- https://club.excelhome.net/thread-1671577-1-1.html
diff --git a/images/1.svg b/images/1.svg
deleted file mode 100644
index e114763..0000000
--- a/images/1.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/images/2.svg b/images/2.svg
deleted file mode 100644
index a0214d4..0000000
--- a/images/2.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/images/3.svg b/images/3.svg
deleted file mode 100644
index f779740..0000000
--- a/images/3.svg
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
diff --git a/js/ribbon.js b/js/ribbon.js
deleted file mode 100644
index 3f51c0d..0000000
--- a/js/ribbon.js
+++ /dev/null
@@ -1,80 +0,0 @@
-
-//这个函数在整个wps加载项中是第一个执行的
-function OnAddinLoad(ribbonUI) {
- if (typeof (window.Application.ribbonUI) != "object") {
- window.Application.ribbonUI = ribbonUI
- }
-
- if (typeof (window.Application.Enum) != "object") { // 如果没有内置枚举值
- window.Application.Enum = WPS_Enum
- }
-
- window.Application.PluginStorage.setItem("EnableFlag", false) //往PluginStorage中设置一个标记,用于控制两个按钮的置灰
- window.Application.PluginStorage.setItem("ApiEventFlag", false) //往PluginStorage中设置一个标记,用于控制ApiEvent的按钮label
- return true
-}
-
-var WebNotifycount = 0;
-
-function OnAction(control) {
- const eleId = control.Id
- switch (eleId) {
- case "btnShowMsg":
- {
- const doc = window.Application.ActiveDocument
- if (!doc) {
- alert("当前没有打开任何文档")
- return
- }
- alert(doc.Name)
- }
- break;
- default:
- break
- }
- return true
-}
-
-function GetImage(control) {
- const eleId = control.Id
- switch (eleId) {
- case "btnShowMsg":
- return "images/1.svg"
- default:
- ;
- }
- return "images/newFromTemp.svg"
-}
-
-function OnGetEnabled(control) {
- const eleId = control.Id
- switch (eleId) {
- case "btnShowMsg":
- return true
- break
- default:
- break
- }
- return true
-}
-
-function OnGetVisible(control) {
- return true
-}
-
-function OnGetLabel(control) {
- const eleId = control.Id
- switch (eleId) {
- case "btnIsEnbable":
- {
- let bFlag = window.Application.PluginStorage.getItem("EnableFlag")
- return bFlag ? "按钮Disable" : "按钮Enable"
- break
- }
- }
- return ""
-}
-
-function OnNewDocumentApiEvent(doc) {
- alert("新建文件事件响应,取文件名: " + doc.Name)
-}
diff --git a/python/invoke_js.py b/py-wps/invoke_wps.py
similarity index 96%
rename from python/invoke_js.py
rename to py-wps/invoke_wps.py
index 55cc180..6bd1d71 100644
--- a/python/invoke_js.py
+++ b/py-wps/invoke_wps.py
@@ -75,7 +75,7 @@ if __name__ == "__main__":
start_http_server()
# print(get_version())
- path = r"c:\Users\32075\OneDrive\文档\Code\RPA_Script\wps-js-extension\XbotWps\python\wps.js"
+ path = r"C:\Users\32075\OneDrive\文档\Code\RPA_Script\wps-js-extension\XbotWps\py-wps\wps.js"
with open(path, "r", encoding="utf8") as f:
code = f.read()
diff --git a/python/wps.js b/py-wps/wps.js
similarity index 100%
rename from python/wps.js
rename to py-wps/wps.js
diff --git a/python/README.md b/python/README.md
deleted file mode 100644
index 8f6787e..0000000
--- a/python/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# XbotWPS
-
-## 介绍
-
-
-## 功能
-
-```
-启动Word
-Word导出PDF
-读取Word文本
-写入文本至Word中
-定位Word光标
-移动Word光标
-替换Word文本
-读取Word表格
-插入Word表格, 插入图片, 插入超链接, 保存Word, 关闭Word
-```
diff --git a/scripts/install.py b/scripts/install.py
new file mode 100644
index 0000000..a88d489
--- /dev/null
+++ b/scripts/install.py
@@ -0,0 +1,213 @@
+import os
+import platform
+import xml.dom.minidom as minidom
+import sys
+import shutil
+import zipfile
+
+
+def get_install_directory():
+ """Get the correct installation directory based on the platform."""
+ system = platform.system()
+ if system == "Windows":
+ return os.path.join(os.environ.get("APPDATA"), "kingsoft", "wps", "jsaddons")
+ elif system == "Linux":
+ return os.path.join(
+ os.path.expanduser("~"), ".local", "share", "Kingsoft", "wps", "jsaddons"
+ )
+ else:
+ print(f"Unsupported platform: {system}")
+ sys.exit(1)
+
+
+def create_authwebsite_xml(directory, node_name="xbotwps"):
+ """Create the authwebsite.xml file if it doesn't exist or update it if it exists."""
+ file_path = os.path.join(directory, "authwebsite.xml")
+
+ # Create the basic XML structure if the file doesn't exist
+ if not os.path.exists(file_path):
+ # Create base XML structure
+ content = '\n\n\n'
+ with open(file_path, "w", encoding="utf-8") as f:
+ f.write(content)
+ print(f"Created basic authwebsite.xml structure at {file_path}")
+
+ try:
+ # Parse the XML file
+ dom = minidom.parse()
+
+ # Get the websites element
+ websites_elements = dom.getElementsByTagName("websites")
+ if not websites_elements:
+ # If no websites element exists, create it
+ websites = dom.createElement("websites")
+ dom.appendChild(websites)
+ else:
+ websites = websites_elements[0]
+
+ # Check if a website node with the specified name already exists
+ existing_nodes = []
+ for website in websites.getElementsByTagName("website"):
+ if website.getAttribute("name") == node_name:
+ existing_nodes.append(website)
+
+ # Remove existing nodes with the same name
+ for node in existing_nodes:
+ websites.removeChild(node)
+
+ # Create and append the new website node
+ new_website = dom.createElement("website")
+ new_website.setAttribute("origin", "null")
+ new_website.setAttribute("status", "enable")
+ new_website.setAttribute("name", node_name)
+ websites.appendChild(new_website)
+
+ # Save the updated XML file
+ with open(file_path, "w", encoding="utf-8") as f:
+ f.write(dom.toprettyxml(indent=" "))
+
+ print(f"Updated authwebsite.xml at {file_path}")
+
+ except Exception as e:
+ print(f"Error working with authwebsite.xml: {e}")
+ # Create a completely new file with the correct structure and node
+ content = (
+ '\n'
+ "\n"
+ f' \n'
+ "\n"
+ )
+ with open(file_path, "w", encoding="utf-8") as f:
+ f.write(content)
+ print(f"Created new authwebsite.xml at {file_path}")
+
+
+def create_publish_xml(
+ directory, node_name="xbotwps", addon_path=None, verson="1.0.0", addon_type="wps"
+):
+ """Create the publish.xml file if it doesn't exist or update it if it exists."""
+ file_path = os.path.join(directory, "publish.xml")
+ if addon_path is None:
+ raise ValueError("addon_path must be provided")
+
+ # Create the basic XML structure if the file doesn't exist
+ if not os.path.exists(file_path):
+ # Create base XML structure
+ content = '\n\n\n'
+ with open(file_path, "w", encoding="utf-8") as f:
+ f.write(content)
+ print(f"Created basic publish.xml structure at {file_path}")
+
+ try:
+ # Parse the XML file
+ dom = minidom.parse(file_path)
+
+ # Get the jsplugins element
+ jsplugins_elements = dom.getElementsByTagName("jsplugins")
+ if not jsplugins_elements:
+ # If no jsplugins element exists, create it
+ jsplugins = dom.createElement("jsplugins")
+ dom.appendChild(jsplugins)
+ else:
+ jsplugins = jsplugins_elements[0]
+
+ # Check if a jsplugin node with the specified name already exists
+ existing_nodes = []
+ for jsplugin in jsplugins.getElementsByTagName("jsplugin"):
+ if jsplugin.getAttribute("name") == node_name:
+ existing_nodes.append(jsplugin)
+
+ # Remove existing nodes with the same name
+ for node in existing_nodes:
+ jsplugins.removeChild(node)
+
+ # Create and append the new jsplugin node
+ new_jsplugin = dom.createElement("jsplugin")
+ new_jsplugin.setAttribute("enable", "enable_dev")
+ new_jsplugin.setAttribute("url", addon_path)
+ new_jsplugin.setAttribute("install", "null")
+ new_jsplugin.setAttribute("version", verson)
+ new_jsplugin.setAttribute("type", addon_type)
+ new_jsplugin.setAttribute("customDomain", "")
+ new_jsplugin.setAttribute("name", node_name)
+ jsplugins.appendChild(new_jsplugin)
+
+ # Save the updated XML file
+ with open(file_path, "w", encoding="utf-8") as f:
+ f.write(dom.toprettyxml(indent=" "))
+
+ print(f"Updated publish.xml at {file_path}")
+
+ except Exception as e:
+ print(f"Error working with publish.xml: {e}")
+ # Create a completely new file with the correct structure and node
+ content = (
+ '\n'
+ "\n"
+ f' \n'
+ "\n"
+ )
+ with open(file_path, "w", encoding="utf-8") as f:
+ f.write(content)
+ print(f"Created new publish.xml at {file_path}")
+
+
+def extract_addon(addon_path, install_dir):
+ """Extract the addon archive to the installation directory."""
+ addon_name = "xbotwps"
+ extract_dir = os.path.join(install_dir, addon_name)
+
+ # Clean the existing directory if it exists
+ if os.path.exists(extract_dir):
+ print(f"Removing existing addon directory: {extract_dir}")
+ shutil.rmtree(extract_dir)
+
+ # Create the extraction directory
+ os.makedirs(extract_dir)
+
+ # Determine the archive type and extract accordingly
+ file_ext = os.path.splitext(addon_path)[1].lower()
+
+ try:
+ print(f"Extracting ZIP archive to {extract_dir}")
+ with zipfile.ZipFile(addon_path, "r") as zip_ref:
+ zip_ref.extractall(install_dir)
+ print("Extraction completed successfully")
+
+ return True
+ except Exception as e:
+ print(f"Error extracting archive: {e}")
+ return False
+
+
+def main():
+ # 1. 将插件文件解压到插件安装目录下
+ # 2. 从插件目录下读取package.json文件,获取插件名称, 版本号, 插件类型
+ # 3. 创建authwebsite.xml文件,添加插件名称节点
+ # 4. 创建publish.xml文件,添加插件名称节点
+
+ addon_path = r"C:\\Users\\32075\\OneDrive\\文档\\Code\\RPA_Script\\wps-js-extension\\XbotWps\\wps-addon-build\\xbotwps.zip"
+ node_name = "xbotwps"
+ install_dir = get_install_directory()
+ print(f"Installation directory: {install_dir}")
+
+ # Create the installation directory if it doesn't exist
+ if not os.path.exists(install_dir):
+ os.makedirs(install_dir)
+ print(f"Created installation directory: {install_dir}")
+
+ # Create the required XML files
+ create_authwebsite_xml(install_dir, node_name)
+ create_publish_xml(install_dir, node_name, addon_path)
+
+ # Extract the addon to the installation directory
+ if extract_addon(addon_path, install_dir):
+ print("Addon extracted successfully.")
+ else:
+ print("Failed to extract addon.")
+
+ print("Installation completed successfully.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/xbot-et/README.md b/xbot-et/README.md
new file mode 100644
index 0000000..bf03dc2
--- /dev/null
+++ b/xbot-et/README.md
@@ -0,0 +1 @@
+# WPS 表格自动化
diff --git a/xbot-et/images/about.svg b/xbot-et/images/about.svg
new file mode 100644
index 0000000..82718c1
--- /dev/null
+++ b/xbot-et/images/about.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/newFromTemp.svg b/xbot-et/images/newFromTemp.svg
similarity index 100%
rename from images/newFromTemp.svg
rename to xbot-et/images/newFromTemp.svg
diff --git a/index.html b/xbot-et/index.html
similarity index 100%
rename from index.html
rename to xbot-et/index.html
diff --git a/xbot-et/js/ribbon.js b/xbot-et/js/ribbon.js
new file mode 100644
index 0000000..d01a5f0
--- /dev/null
+++ b/xbot-et/js/ribbon.js
@@ -0,0 +1,39 @@
+
+//这个函数在整个wps加载项中是第一个执行的
+function OnAddinLoad(ribbonUI) {
+ if (typeof (window.Application.ribbonUI) != "object") {
+ window.Application.ribbonUI = ribbonUI
+ }
+
+ if (typeof (window.Application.Enum) != "object") { // 如果没有内置枚举值
+ window.Application.Enum = WPS_Enum
+ }
+ return true
+}
+
+
+function OnAction(control) {
+ const eleId = control.Id
+ switch (eleId) {
+ case "btnShowAbout":
+ {
+ alert("关于我们\n\n作者:Jianxin\n\n版本:1.0.0\n\n说明:自动化插件\n\n感谢使用!")
+ }
+ break;
+ default:
+ break
+ }
+ return true
+}
+
+
+function GetImage(control) {
+ const eleId = control.Id
+ switch (eleId) {
+ case "btnShowAbout":
+ return "images/about.svg"
+ default:
+ ;
+ }
+ return "images/newFromTemp.svg"
+}
diff --git a/js/util.js b/xbot-et/js/util.js
similarity index 100%
rename from js/util.js
rename to xbot-et/js/util.js
diff --git a/js/xbot.js b/xbot-et/js/xbot.js
similarity index 99%
rename from js/xbot.js
rename to xbot-et/js/xbot.js
index 2c64cb1..8dce0eb 100644
--- a/js/xbot.js
+++ b/xbot-et/js/xbot.js
@@ -1,5 +1,7 @@
let wpsInstance = null;
+
+
function InvokeFromXbot(param) {
// 1. 解析参数, 如果不是字符串, 则转换为字符串, 并用json解析, 解析失败直接retrun
if (typeof param !== 'string') {
diff --git a/main.js b/xbot-et/main.js
similarity index 100%
rename from main.js
rename to xbot-et/main.js
diff --git a/xbot-et/package.json b/xbot-et/package.json
new file mode 100644
index 0000000..b91c951
--- /dev/null
+++ b/xbot-et/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "xbotet",
+ "addonType": "et",
+ "version": "1.0.0",
+ "description": "借助插件实现WPS的自动化操作",
+ "devDependencies": {
+ "wps-jsapi-declare": "latest"
+ }
+}
diff --git a/xbot-et/ribbon.xml b/xbot-et/ribbon.xml
new file mode 100644
index 0000000..c6366a5
--- /dev/null
+++ b/xbot-et/ribbon.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xbot-wps/README b/xbot-wps/README
new file mode 100644
index 0000000..468622e
--- /dev/null
+++ b/xbot-wps/README
@@ -0,0 +1 @@
+# WPS 文档自动化
diff --git a/xbot-wps/images/about.svg b/xbot-wps/images/about.svg
new file mode 100644
index 0000000..82718c1
--- /dev/null
+++ b/xbot-wps/images/about.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/xbot-wps/images/newFromTemp.svg b/xbot-wps/images/newFromTemp.svg
new file mode 100644
index 0000000..f6c70b3
--- /dev/null
+++ b/xbot-wps/images/newFromTemp.svg
@@ -0,0 +1,22 @@
+
+
\ No newline at end of file
diff --git a/xbot-wps/index.html b/xbot-wps/index.html
new file mode 100644
index 0000000..2efb298
--- /dev/null
+++ b/xbot-wps/index.html
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/xbot-wps/js/ribbon.js b/xbot-wps/js/ribbon.js
new file mode 100644
index 0000000..d01a5f0
--- /dev/null
+++ b/xbot-wps/js/ribbon.js
@@ -0,0 +1,39 @@
+
+//这个函数在整个wps加载项中是第一个执行的
+function OnAddinLoad(ribbonUI) {
+ if (typeof (window.Application.ribbonUI) != "object") {
+ window.Application.ribbonUI = ribbonUI
+ }
+
+ if (typeof (window.Application.Enum) != "object") { // 如果没有内置枚举值
+ window.Application.Enum = WPS_Enum
+ }
+ return true
+}
+
+
+function OnAction(control) {
+ const eleId = control.Id
+ switch (eleId) {
+ case "btnShowAbout":
+ {
+ alert("关于我们\n\n作者:Jianxin\n\n版本:1.0.0\n\n说明:自动化插件\n\n感谢使用!")
+ }
+ break;
+ default:
+ break
+ }
+ return true
+}
+
+
+function GetImage(control) {
+ const eleId = control.Id
+ switch (eleId) {
+ case "btnShowAbout":
+ return "images/about.svg"
+ default:
+ ;
+ }
+ return "images/newFromTemp.svg"
+}
diff --git a/xbot-wps/js/util.js b/xbot-wps/js/util.js
new file mode 100644
index 0000000..8c991a1
--- /dev/null
+++ b/xbot-wps/js/util.js
@@ -0,0 +1,19 @@
+//在后续的wps版本中,wps的所有枚举值都会通过wps.Enum对象来自动支持,现阶段先人工定义
+var WPS_Enum = {
+ msoCTPDockPositionLeft: 0,
+ msoCTPDockPositionRight: 2
+}
+
+function GetUrlPath() {
+ let e = document.location.toString()
+ return -1 != (e = decodeURI(e)).indexOf("/") && (e = e.substring(0, e.lastIndexOf("/"))), e
+}
+/**
+ * 通过wps提供的接口执行一段脚本
+ * @param {*} param 需要执行的脚本
+ */
+function shellExecuteByOAAssist(param) {
+ if (wps != null) {
+ wps.OAAssist.ShellExecute(param)
+ }
+}
\ No newline at end of file
diff --git a/xbot-wps/js/xbot.js b/xbot-wps/js/xbot.js
new file mode 100644
index 0000000..8dce0eb
--- /dev/null
+++ b/xbot-wps/js/xbot.js
@@ -0,0 +1,65 @@
+let wpsInstance = null;
+
+
+
+function InvokeFromXbot(param) {
+ // 1. 解析参数, 如果不是字符串, 则转换为字符串, 并用json解析, 解析失败直接retrun
+ if (typeof param !== 'string') {
+ param = JSON.stringify(param);
+ }
+ try {
+ param = JSON.parse(param);
+ } catch (e) {
+ return { msg: '参数解析失败', code: -1 };
+ }
+
+ // 2. 判断是否有method字段, 如果没有直接return
+ if (!param.method) {
+ return { msg: '参数错误', code: -2 };
+ }
+
+ // 3. 获取 method 字段对应的方法和 args 参数
+ let method = param.method;
+
+ let args = null;
+
+ try {
+ args = JSON.parse(param.args);
+ } catch (e) {
+ args = {};
+ }
+
+
+ console.log("method:", method);
+ console.log("args:", args);
+ // confsole.log("args", typeof args);
+
+ // 4. 判断 method 是否为 inject, 如果是则执行注入方法, 其他走默认方法执行调用函数
+ if (method === 'inject') {
+ let code = args.code;
+ console.log("start eval code");
+ console.log(code);
+ console.log(new Function(code)());
+ wpsInstance = new Function(code)(); // 执行并获取返回值
+ console.log("success eval code");
+ return { message: "inject ok", code: 0 }
+ }
+
+ // 5. 判断是否有 wpsInstance, 如果没有直接return
+ if (!wpsInstance) {
+ return {msg: '未注入', code: -3};
+ }
+
+ // 6. 判断 wpsInstance 是否有 method 方法, 如果没有直接return
+ if (!wpsInstance[method]) {
+ return {msg: '方法不存在', code: -4};
+ }
+
+ // 7. 执行 wpsInstance 的 method 方法, 并返回结果
+ try {
+ const result = wpsInstance[method](args ?? null);
+ return {msg: '执行成功', code: 0, data: result};
+ } catch (e) {
+ return {msg: '执行失败', code: -5};
+ }
+}
diff --git a/xbot-wps/main.js b/xbot-wps/main.js
new file mode 100644
index 0000000..fc183d6
--- /dev/null
+++ b/xbot-wps/main.js
@@ -0,0 +1,4 @@
+//这个文件由index.html包含
+document.write("");
+document.write("");
+document.write("");
diff --git a/package.json b/xbot-wps/package.json
similarity index 58%
rename from package.json
rename to xbot-wps/package.json
index 20e775b..f066cfd 100644
--- a/package.json
+++ b/xbot-wps/package.json
@@ -2,7 +2,7 @@
"name": "xbotwps",
"addonType": "wps",
"version": "1.0.0",
- "description": "wps加载项示例, 执行npm install后,提供代码联想功能",
+ "description": "借助插件实现WPS的自动化操作",
"devDependencies": {
"wps-jsapi-declare": "latest"
}
diff --git a/ribbon.xml b/xbot-wps/ribbon.xml
similarity index 66%
rename from ribbon.xml
rename to xbot-wps/ribbon.xml
index 05ee89f..c7e5264 100644
--- a/ribbon.xml
+++ b/xbot-wps/ribbon.xml
@@ -3,7 +3,8 @@
-
+