作者:互联网 时间: 2026-08-08 14:30:01
Microsoft Excel 技能在 AI 代理与 Microsoft Graph API 之间提供了无缝桥梁,允许全面操作存储在 OneDrive 或 SharePoint 中的 Excel 文件。通过利用 Openclaw Skills,开发人员可以绕过复杂的 OAuth 实现,直接通过托管网关与工作簿、工作表和单元格区域进行交互。这种集成对于构建需要处理电子表格数据、生成报告或通过安全统一的界面同步企业数据集信息的代理至关重要。
下载入口:https://github.com/openclaw/skills/tree/main/skills/byungkyu/microsoft-excel
从源直接安装技能的最快方式。
npx clawhub@latest install microsoft-excel
将技能文件夹复制到以下位置之一
全局模式~/.openclaw/skills/
工作区
<project>/skills/
优先级:工作区 > 本地 > 内置
将此提示词复制到 OpenClaw 即可自动安装。
请帮我使用 Clawhub 安装 microsoft-excel。如果尚未安装 Clawhub,请先安装(npm i -g clawhub)。
通过获取您的 Maton API 密钥并配置环境变量来设置技能:
export MATON_API_KEY="YOUR_API_KEY"
接下来,通过控制门户 https://ctrl.maton.ai 创建与 Microsoft Excel 的活动连接。您可以使用以下命令验证连接状态,以确保您的 Openclaw Skills 环境配置正确:
# 列出活动连接以验证设置
curl -H "Authorization: Bearer $MATON_API_KEY" "https://ctrl.maton.ai/connections?app=microsoft-excel&status=ACTIVE"
该技能基于 Microsoft Graph 资源层级组织数据交互。Openclaw Skills 用户可以导航和操作以下数据结构:
| 层级 | 描述 | 关键属性 |
|---|---|---|
| 驱动器 | OneDrive 或 SharePoint 中的根容器 | drive_id, root_path |
| 工作簿 | 主要的 .xlsx 文件资源 | file_id, filename |
| 工作表 | 工作簿中的单个表格页 | id, name, visibility |
| 区域 | 指定的单元格块 | address, values, formulas, text |
| 表格 | 带有标题的结构化数据对象 | id, name, rows, columns |
| 图表 | 视觉数据表示 | type, sourceData, seriesBy |
注意:所有区域操作均使用标准 A1 引用样式(例如 A1:C10)。仅支持 .xlsx 文件格式。
name: microsoft-excel
description: |
Microsoft Excel API integration with managed OAuth. Read and write Excel workbooks, worksheets, ranges, tables, and charts stored in OneDrive.
Use this skill when users want to read or modify Excel spreadsheets, manage worksheet data, work with tables, or access cell values.
For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
compatibility: Requires network access and valid Maton API key
metadata:
author: maton
version: "1.0"
clawdbot:
emoji: ??
requires:
env:
- MATON_API_KEY
Access the Microsoft Excel API (via Microsoft Graph) with managed OAuth authentication. Read and write workbooks, worksheets, ranges, tables, and charts stored in OneDrive or SharePoint.
# List worksheets in a workbook
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://gateway.maton.ai/microsoft-excel/{native-api-path}
Replace {native-api-path} with the actual Microsoft Graph API endpoint path. The gateway proxies requests to graph.microsoft.com and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your Microsoft Excel OAuth connections at https://ctrl.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=microsoft-excel&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'microsoft-excel'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "4751ac89-3970-47e1-872c-eacdf4291732",
"status": "ACTIVE",
"creation_time": "2026-02-07T00:43:18.565932Z",
"last_updated_time": "2026-02-07T00:43:29.729782Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "microsoft-excel",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple Microsoft Excel connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/microsoft-excel/v1.0/me/drive')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '4751ac89-3970-47e1-872c-eacdf4291732')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
You can access workbooks using either ID-based or path-based patterns:
By File ID:
/microsoft-excel/v1.0/me/drive/items/{file-id}/workbook/...
By File Path:
/microsoft-excel/v1.0/me/drive/root:/{path-to-file}:/workbook/...
GET /microsoft-excel/v1.0/me/drive
GET /microsoft-excel/v1.0/me/drive/root/children
GET /microsoft-excel/v1.0/me/drive/root/search(q='.xlsx')
PUT /microsoft-excel/v1.0/me/drive/root:/{filename}.xlsx:/content
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
{binary xlsx content}
Sessions improve performance for multiple operations. Recommended for batch operations.
POST /microsoft-excel/v1.0/me/drive/root:/{path}:/workbook/createSession
Content-Type: application/json
{
"persistChanges": true
}
Response:
{
"persistChanges": true,
"id": "cluster=PUS7&session=..."
}
Use the session ID in subsequent requests:
workbook-session-id: {session-id}
POST /microsoft-excel/v1.0/me/drive/root:/{path}:/workbook/closeSession
workbook-session-id: {session-id}
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets
Response:
{
"value": [
{
"id": "{00000000-0001-0000-0000-000000000000}",
"name": "Sheet1",
"position": 0,
"visibility": "Visible"
}
]
}
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets
Content-Type: application/json
{
"name": "NewSheet"
}
PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')
Content-Type: application/json
{
"name": "RenamedSheet",
"position": 2
}
DELETE /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('{worksheet-id}')
Returns 204 No Content on success.
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')
Response:
{
"address": "Sheet1!A1:B2",
"values": [
["Hello", "World"],
[1, 2]
],
"formulas": [
["Hello", "World"],
[1, 2]
],
"text": [
["Hello", "World"],
["1", "2"]
],
"numberFormat": [
["General", "General"],
["General", "General"]
],
"rowCount": 2,
"columnCount": 2
}
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/usedRange
PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')
Content-Type: application/json
{
"values": [
["Updated", "Values"],
[100, 200]
]
}
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')/clear
Content-Type: application/json
{
"applyTo": "All"
}
Options: All, Formats, Contents
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/tables
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/tables/add
Content-Type: application/json
{
"address": "A1:C4",
"hasHeaders": true
}
Response:
{
"id": "{6D182180-5F5F-448B-9E9C-377A5251CFC5}",
"name": "Table1",
"showHeaders": true,
"showTotals": false,
"style": "TableStyleMedium2"
}
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')
PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')
Content-Type: application/json
{
"name": "PeopleTable",
"showTotals": true
}
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows
Response:
{
"value": [
{
"index": 0,
"values": [["Alice", 30, "NYC"]]
},
{
"index": 1,
"values": [["Bob", 25, "LA"]]
}
]
}
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows
Content-Type: application/json
{
"values": [["Carol", 35, "Chicago"]]
}
DELETE /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows/itemAt(index=0)
Returns 204 No Content on success.
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/columns
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/columns
Content-Type: application/json
{
"values": [["Email"], ["[email protected]"], ["[email protected]"]]
}
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/names
GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/charts
POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/charts/add
Content-Type: application/json
{
"type": "ColumnClustered",
"sourceData": "A1:C4",
"seriesBy": "Auto"
}
// Get range values
const response = await fetch(
"https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/data.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B10')",
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
console.log(data.values);
import os
import requests
# Update range values
response = requests.patch(
"https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/data.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')",
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
json={'values': [['Name', 'Age'], ['Alice', 30]]}
)
print(response.json())
.xlsx files are supported (not legacy .xls){ and } must be URL-encoded (%7B and %7D)null in value arrays to skip updating specific cells"" (empty string)A1:C10, Sheet1!A1:B5)curl -g when URLs contain parentheses to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Missing Microsoft Excel connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 404 | Item not found or session expired |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Microsoft Graph API |
| Code | Description |
|---|---|
ItemNotFound |
File or resource doesn't exist |
ItemAlreadyExists |
Worksheet or table with that name already exists |
InvalidArgument |
Invalid parameter or missing required field |
SessionNotFound |
Session expired or doesn't exist |
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
microsoft-excel. For example:https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheetshttps://gateway.maton.ai/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets