调用飞书API获取excel表格中数据

1.说明

关于云文档的api,今天处理kook机器人的时候,有位用户提出了这个和excel对接的需求。

但我翻了翻腾讯云文档和金山云文档,都没有看到正经的获取execl文档中数据的接口(其实是我愚笨实在是没看懂他文档里面在说什么),大多都是将云文档内嵌入到网站中的前端接口。

于是又看了看,找到了一个seatable平台是支持完整的api,甚至支持用sql来查询excel中的数据。但其免费版本的API日用量只有区区5000/天,实在是不够机器人用的。

又找到了飞书,这次总算是找到了我能看懂的用api来操作excel的文档了。

顺带一提,我的域名邮箱就是用的飞书的免费服务,还是很香的。

飞书官方文档:https://open.feishu.cn/document/server-docs/docs/sheets-v3/overview

然后又找到了一个CSDN上的教程:python 飞书API调用——电子表格操作

此教程讲述的还是不够清楚,感觉还是需要自己记录一下。万一以后用得上,也不用在到处找其他教程了。

2.创建api应用

要想能操作api,首先需要在你创建的企业中创建一个企业自建应用,名字随便填写

image-20230711152512721

为了操作excel表格,我们需要给予应用云文档的权限。

image-20230711152810849

在权限管理,往下滑找到云文档,全选所有权限,点击右侧批量开通

image-20230711152846721

注意,云文档的权限一共有21个,默认一页只是展示了10个,全选也只会添加10个权限,所以需要依次重复上述操作,把这里的21个权限都给选中给应用添加上。避免出现权限问题

image-20230711152916288

随后来到应用凭证,获取你的appid和appsecret,这两个调用鉴权api来获取token的时候需要

image-20230711153043103

随后来到版本管理,随便创建一个版本,点击申请发布,否则不能调用api

image-20230711153233310

因为我本来就是企业的管理员,所以就能在消息里面直接看到申请,点击审核,允许就行了

image-20230711153311014

3.调用api的基本示例

3.1 鉴权

https://open.feishu.cn/document/server-docs/authentication-management/access-token/tenant_access_token_internal

首先要获取到自己的token,如下代码,修改为你的appid和secret,就能获取到token

1
2
3
4
5
6
7
8
9
10
11
import requests

url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
# 应用凭证里的 app id 和 app secret
post_data = {
"app_id": "",
"app_secret": ""
}
r = requests.post(url, data=post_data)
tat = r.json()["tenant_access_token"]
print(tat)

这个接口完整的json返回值示例如下,其中"tenant_access_token"字段是后续需要使用的鉴权token,"expire"字段是这个token的过期时间(单位为秒),"code"字段非0代表获取失败。

1
2
3
4
5
6
{
"code":0,
"expire":6087,
"msg":"ok",
"tenant_access_token":"token内容"
}

获取到token后,需要构造一个请求headers来请求其他api,其中tat变量就是api返回值里面的"tenant_access_token"字段;

1
2
3
4
header = {
"Content-Type": "application/json",
"Authorization": "Bearer " + str(tat)
} # 请求头

3.2 写入

要想往excel表里面写入数据,首先得修改一下文档的权限为可编辑

image-20230711154024944

代码如下,来解释一下如何获取云文档的id,和sh的id(这两个不同)

大家应该都知道,一个excel表格里面是可以有多个独立的sheet的。比如下图中,我打开的云文档url里面就包含了云文档的id,和当前sheet1的id;

image-20230711154118974

这里页面的url分解出来就是下面这样,我们调用API需要用到的是云文档的完整ID和工作簿的ID。

1
https://企业地址.fetishu.cn/sheets/云文档的完整ID?sheet=工作簿的ID

代码注释中有更多说明,其中range字段参考官方文档里面的说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 飞书文档的储存地址结构:https://企业地址/sheets/shtcnjGdHzBm7Qa85UXQYk9OPxh?sheet=402cb1
# 一般来说sh开头为文档地址,sheet=后跟工作簿地址,这两块是代码需要引用的参数
# 总结来说就是 https://企业地址/sheets/云文档的完整ID?sheet=工作簿的ID
import json

sheets_base_url = "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets"
excel_id = "云文档的id"


def insert_info():
url = f"{sheets_base_url}/{excel_id}/values" #写入的sh开头的文档地址,其他不变
# range参数中!之前的工作簿ID,后面跟着行列号范围
post_data = {
"valueRange": {
"range": "486268!C3:N8",
"values": [["Hello", 1], ["World", 1]]
}
}
# 在486268这个工作簿内的单元格C3到N8写入内容为helloworld等内容
r2 = requests.put(url, data=json.dumps(post_data), headers=header) #请求写入
print(r2.json()) #输出来判断写入是否成功

调用之后,控制台输出success,表中成功新增数据

image-20230711154214211

3.3 查询

由于我的需求是查询某一列的数据,这对记账之类的表格很有用。比如下图中C列里面的数据就是数字的加减

image-20230711154300827

这时候我们就可以用如下的方式调用,获取到这个sheet中,C一整列的数据

1
2
3
4
5
6
7
8
sheets_base_url = "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets"
excel_id = "云文档的id"
# 在486268这个工作簿内的单元格C1开始的C列全部内容
url = f"{sheets_base_url}/{excel_id}/values/486268!C1:C"

ret = requests.get(url, headers=header)
print(ret.text)
print(ret.json())

返回结果示例如下,正好是表格中的数据!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"code": 0,
"data": {
"revision": 8,
"spreadsheetToken": "云文档ID",
"valueRange": {
"majorDimension": "ROWS",
"range": "486268!C1:C4",
"revision": 8,
"values": [[399], [-39], [-63], [65], [52], [0], [-63]]
}
},
"msg": "success"
}

The end

我需要的基本操作就是这些了。只要你学会了这两个操作,后续应该就能看懂飞书的api文档,来查询其他信息了。

有更多问题,欢迎在评论区交流讨论。