☰
gspread 实战指南:用 Python 高效读写 Google Sheets 电子表格
2026/9/28 2:44:24 网站建设 项目流程
  • 后端

【免费下载链接】gspread

Google Sheets Python API

项目地址:https://gitcode.com/gh_mirrors/gs/gspread
点击查看免费下载

导读

gspread 是面向 Google Sheets 的 Python API v4 客户端,为开发者提供"按标题、Key 或 URL 打开电子表格、读写并格式化单元格范围、共享与访问控制、批量更新"等完整能力。本文以仓库 README.md 为主线,结合 gspread/auth.py、gspread/client.py、gspread/worksheet.py、gspread/spreadsheet.py 等源码,系统讲解安装配置、三种认证方式、电子表格与工作表管理、数据读写、格式设置、数据校验,以及 v5.12 → v6.0 迁移的完整要点,帮助你从零开始把 Google Sheets 集成进 Python 应用。

项目概览与核心特性

gspread 提供了一个"简单接口"用于操作 Google Sheets(对应官方 Sheets API v4)。仓库根目录的 README.md 明确列出四大核心特性:

  • 打开电子表格:支持按标题(title)、Key(键)或URL三种方式打开;
  • 读写与格式化:读取、写入并格式化单元格范围;
  • 共享与访问控制:通过 Drive API 管理电子表格的共享权限;
  • 批量更新:一次请求更新多个范围,减少 API 往返。

从源码结构看,整个库分为几个层次:gspread/auth.py 负责认证入口,gspread/client.py 的Client是"gspread 的入口点",负责打开/创建/删除电子表格及权限管理,gspread/spreadsheet.py 的Spreadsheet代表一份电子表格文件,gspread/worksheet.py 的Worksheet代表其中的单个工作表,gspread/http_client.py 封装了底层 HTTP 请求与重试逻辑。

安装与环境要求

在 Python 3.8+ 环境下,只需一条命令即可安装:

pip install gspread

注意:gspread v6 起最低要求 Python 3.8,因为 Python 3.7 已进入生命周期结束(EOL)状态。

第一步:创建 Google API 凭据

使用 gspread 前,需要在 Google API Console 中创建凭据。根据你的使用场景选择三类凭据之一:

  1. 服务账号(Service Account):适合服务器端、自动化脚本等无人值守场景,推荐初学者使用;
  2. OAuth 客户端 ID(OAuth Client ID):适合需要代表真实用户操作的桌面应用;
  3. API Key:仅用于访问公开电子表格。

凭据创建完成后,对照调用 gspread/auth.py 中对应的工厂函数初始化客户端。

服务账号认证:service_account()

服务账号是自动化场景的首选。默认读取当前用户配置目录下的service_account.json:

import gspread # 默认路径:~/.config/gspread/service_account.json gc = gspread.service_account() # 或者显式指定凭据文件路径 gc = gspread.service_account(filename="google_credentials.json")

也可以不落地文件,直接把服务账号信息以字典形式传入service_account_from_dict()。从 gspread/auth.py 的源码可以看出,两者最终都调用google.oauth2.service_account.Credentials生成凭据并构造Client。

OAuth 认证:oauth()

适合桌面端交互式场景。默认使用"本地服务器流程",会启动本地 Web 服务器并在浏览器中打开授权页面:

gc = gspread.oauth()

首次授权成功后,gspread 会把授权后的用户凭据写入authorized_user.json,后续调用直接复用,不再重复弹出授权流程(对应 gspread/auth.py 中load_credentials→ 未命中才走flow的逻辑)。如果不想用浏览器,也可以改用控制台流程:

gc = gspread.oauth(flow=gspread.auth.console_flow)

API Key 认证:api_key()

API Key 只能打开公开电子表格,无法访问私有文件(gspread/auth.py 中对此有明确 warning),且需要google-auth>=2.15.0:

gc = gspread.api_key("YOUR_API_KEY")

凭据文件默认存放位置

由 gspread/auth.py 的get_config_dir()决定:

平台配置目录
Windows%APPDATA%\gspread
Linux / macOS 等~/.config/gspread

默认文件名:credentials.json(OAuth 客户端凭据)、authorized_user.json(已授权用户凭据)、service_account.json(服务账号凭据)。

作用域(Scopes)

默认作用域为读写(定义于 gspread/auth.py):

DEFAULT_SCOPES = [ "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive", ]

如果只需要只读访问,可传入READONLY_SCOPES;但注意所有写入方法都将失效:

gc = gspread.oauth(scopes=gspread.auth.READONLY_SCOPES) sh = gc.open("A spreadsheet") sh.sheet1.update_acell("A1", "42") # 只读作用域下会报错

基本用法:打开电子表格并写入

完成认证后,即可体验 README 中最经典的"开箱即用"流程:

import gspread # 根据第一步选择的认证方式,调用 service_account() / oauth() / api_key() gc = gspread.service_account() # 一步到位:打开电子表格并取其第一个工作表(Sheet1) wks = gc.open("Where is the money Lebowski?").sheet1 # 以左上角地址为锚点,更新一个单元格范围 wks.update([[1, 2], [3, 4]], "A1") # 或更新单个单元格 wks.update_acell("B42", "it's down there somewhere, let me take another look.") # 格式化表头 wks.format("A1:B1", {"textFormat": {"bold": True}})

这段示例已覆盖三条核心链路:打开文件(Client.open→Spreadsheet)→ 定位工作表(.sheet1)→ 写入(Worksheet.update/update_acell)与格式化(Worksheet.format)。

打开电子表格的三种方式

按标题、按 Key、按 URL 分别对应 gspread/client.py 中的三个方法:

# 1) 按标题(与 Google Docs 中显示的名称一致) sh = gc.open("My poor gym results") # 2) 按 Key(即电子表格 ID,可从 URL 中提取) sht1 = gc.open_by_key("0BmgG6nO_6dprdS1MN3d3MkdPa142WFRrdnRRUWl1UFE") # 3) 懒得提取 Key?直接粘贴完整 URL sht2 = gc.open_by_url("https://docs.google.com/spreadsheet/ccc?key=0Bm...FE&hl")

实现细节:open_by_url()内部通过extract_id_from_url()从 URL 中解析出 Key 后再调用open_by_key();open()则调用 Drive API 的 files 列表接口按名称匹配(_list_spreadsheet_files支持按标题过滤和按folder_id目录过滤,见 gspread/client.py)。同名文件存在多个时,open()返回第一个;未找到时抛出SpreadsheetNotFound。

此外还可以一次打开所有电子表格:

gc.openall() # 打开全部 gc.openall(title="Filter title") # 按标题过滤

创建、共享与导出电子表格

创建

sh = gc.create("A new spreadsheet")

注意 README 中特别强调:新建的电子表格默认只对脚本账号可见。想用个人账号访问,必须执行共享操作:

sh.share("otto@example.com", perm_type="user", role="writer")

share()的参数语义:perm_type为"user"、"group"、"anyone"等授权对象类型,role为"reader"、"writer"、"owner"等角色。也可传入folder_id把新文件直接创建到指定 Drive 文件夹(gspread/client.py)。

导出

Client.export()与Spreadsheet.export()支持将电子表格导出为多种格式(对应 gspread/utils.py 的ExportFormat枚举):

枚举值输出格式
ExportFormat.PDFPDF(默认)
ExportFormat.EXCELExcel (.xlsx)
ExportFormat.CSVCSV
ExportFormat.OPEN_OFFICE_SHEETOpenDocument 表格
ExportFormat.TSVTSV
ExportFormat.ZIPPED_HTMLHTML 压缩包

工作表管理

选择工作表

四种常见选择方式(对应 gspread/spreadsheet.py):

# 按索引选择(索引从 0 开始) worksheet = sh.get_worksheet(0) # 按标题选择 worksheet = sh.worksheet("January") # 最常用:Sheet1 worksheet = sh.sheet1 # 获取全部工作表列表 worksheet_list = sh.worksheets()

worksheets()还支持exclude_hidden=True跳过隐藏工作表;get_worksheet_by_id()可按 URL 中gid参数对应的工作表 ID 定位。

创建与删除工作表

# 创建(注意 README 示例中 rows/cols 传的是字符串,源码类型标注为 int) worksheet = sh.add_worksheet(title="A worksheet", rows="100", cols="20") # 删除 sh.del_worksheet(worksheet)

add_worksheet()完整签名还支持index参数指定新工作表插入位置(gspread/spreadsheet.py)。删除也有按 ID 的变体del_worksheet_by_id()。

读取数据

读取单个单元格

# 用 A1 标签读取(get 返回 ValueRange,first() 取首个值) val = worksheet.get("B1").first() # 用行列坐标读取 val = worksheet.cell(1, 2).value

cell(row, col)底层调用get()并包装为 gspread/cell.py 的Cell对象,acell("B1")则是其 A1 记法变体(内部用a1_to_rowcol换算,见 gspread/worksheet.py)。Cell提供row、col、value、address、numeric_value等属性。

读取整行 / 整列

# 第一行的所有值 values_list = worksheet.row_values(1) # 第一列的所有值 values_list = worksheet.col_values(1)

读取整个工作表为"列表的列表"

from gspread.utils import GridRangeType list_of_lists = worksheet.get(return_type=GridRangeType.ListOfLists)

get()的返回类型由GridRangeType控制(gspread/utils.py):ValueRange(默认,带range与major_dimension元数据的列表子类)或ListOfLists(纯二维列表)。get_all_values()与get_values()是get()的旧式别名,默认pad_values=True且返回ListOfLists。

读取范围:三种"填充策略"

get("A1:B4")默认只返回有值的单元格,因此返回数组可能不是矩形:

>>> worksheet.get("A1:B4") [['A1', 'B1'], ['A2']]

加上pad_values=True后,空单元格以空字符串填充,返回包围数据的最小矩形:

>>> worksheet.get("A1:B4", pad_values=True) [['A1', 'B1'], ['A2', '']]

加上maintain_size=True后,返回数组与请求范围尺寸完全一致(即使整行为空也保留):

>>> worksheet.get("A1:B4", maintain_size=True) [['A1', 'B1'], ['A2', ''], ['', ''], ['', '']]

对应实现见 gspread/worksheet.py:pad_values走fill_gaps,maintain_size根据 A1 范围换算出行列数后用fill_gaps(values, rows=rows, cols=cols)补齐。

读取未格式化值或公式

通过value_render_option控制取值语义,三个选项定义于 gspread/utils.py 的ValueRenderOption:

from gspread.utils import ValueRenderOption # 默认(formatted):按 UI 显示的格式化值返回,如货币格式 >>> worksheet.get("A1:B2") [['$12.00']] # unformatted:返回未格式化的计算值 >>> worksheet.get("A1:B2", value_render_option=ValueRenderOption.unformatted) [[12]] # formula:返回公式原文,不计算结果 >>> worksheet.get("C2:D2", value_render_option=ValueRenderOption.formula) [['=1/1024']]

查找单元格

find()返回第一个匹配的Cell,findall()返回全部匹配;两者均支持精确字符串与正则表达式两种查询([gspread/worksheet.py](https://link.gitcode.com/i/9f2efa9f7e1672081e32f69af4e1fcbc#L1089-L1090 附近的_finder实现,对应文件位置find/findall):

import re # 精确值查找 cell = worksheet.find("Dough") print("Found something at R%sC%s" % (cell.row, cell.col)) # 正则查找 amount_re = re.compile(r"(Big|Enormous) dough") cell = worksheet.find(amount_re) # 全部匹配:字符串 cell_list = worksheet.findall("Rug store") # 全部匹配:正则 criteria_re = re.compile(r"(Small|Room-tiering) rug") cell_list = worksheet.findall(criteria_re)

将工作表读为记录(字典列表)

get_all_records()把表头行作为键、后续行作为值,返回字典列表,且自动对数值型字符串做 numericise(gspread/worksheet.py):

records = worksheet.get_all_records(head=1)

常用参数:head(表头行号,默认 1)、expected_headers(校验/指定表头)、default_blank(空白单元格的默认值)、numericise_ignore(跳过数值化的列索引,或用["all"]全部跳过)、empty2zero(空单元格转 0)、value_render_option。v6 中旧方法get_records()已被移除,只保留全量get_all_records()(详见下文迁移指南)。

写入数据

更新单个单元格

worksheet.update_acell("B1", "Bingo!")

更新一个范围

worksheet.update([[1, 2], [3, 4]], "A1:B2")

update()的完整签名(gspread/worksheet.py)包含若干实用参数:

  • values:二维数组,必须是 2D 结构(v6 强制);
  • range_name:A1 记法或命名范围,可省略(默认从 A1 起);
  • raw:True(默认)按原文写入不做解析;设为False则等效value_input_option=USER_ENTERED,可写入会被 Sheet 解析的公式等;
  • value_input_option:ValueInputOption.raw/ValueInputOption.user_entered;
  • include_values_in_response/response_value_render_option/response_date_time_render_option:控制响应中回读的内容;
  • default_serializer:为datetime、Decimal等 JSON 无法直接序列化的值提供转换回调(如default_serializer=str)。

写入公式的示例:

worksheet.update([["=SUM(A1:A4)"]], "A5", raw=False)

更新范围可以大于 values 数组本身(多余部分保持原值):

worksheet.update([[42], [43]], "A2:B4")

批量更新多个范围

worksheet.batch_update([{ "range": "A1:B2", "values": [["A1", "B1"], ["A2", "B2"]], }, { "range": "J42:K43", "values": [[1, 2], [3, 4]], }])

batch_update()接收{'range': ..., 'values': [[...]]}字典列表,一次请求完成多处写入(gspread/worksheet.py),是降低 API 调用次数、规避速率限制的推荐做法。

用 Cell 对象批量更新

先取回Cell列表、修改value后一次性提交:

cell_list = worksheet.range("A1:C7") for cell in cell_list: cell.value = "O_o" worksheet.update_cells(cell_list)

update_cells()会把 Cell 列表换算成最小矩形范围并整体写入(cell_list_to_rect补齐空洞,见 gspread/worksheet.py)。

格式化单元格

# 单个范围加粗 worksheet.format("A1:B1", {"textFormat": {"bold": True}}) # 多个范围统一加粗 worksheet.format(["A1:D4", "A10:D10"], {"textFormat": {"bold": True}}) # 综合样式:背景色、对齐、前景色、字号、加粗 worksheet.format("A2:B2", { "backgroundColor": {"red": 0.0, "green": 0.0, "blue": 0.0}, "horizontalAlignment": "CENTER", "textFormat": { "foregroundColor": {"red": 1.0, "green": 1.0, "blue": 1.0}, "fontSize": 12, "bold": True, }, })

format()内部调用batch_format(),将每个范围包装为repeatCell请求并通过batch_update一次性下发(gspread/worksheet.py)。注意颜色字段使用 Sheets API 原生风格的红/绿/蓝 0~1 浮点字典;而**工作表标签颜色(tab color)**在 v6 中已改为十六进制字符串(见迁移指南)。

添加数据验证规则

add_validation()用ValidationConditionType(完整枚举见 gspread/utils.py)限定单元格输入:

import gspread from gspread.utils import ValidationConditionType # 限制单个单元格输入必须大于 10,并开启严格模式与提示信息 worksheet.add_validation( "A1", ValidationConditionType.number_greater, [10], strict=True, inputMessage="Value must be greater than 10", ) # 为 C2:C7 区域提供 Yes/No 下拉选项 worksheet.add_validation( "C2:C7", ValidationConditionType.one_of_list, ["Yes", "No"], showCustomUi=True, )

ValidationConditionType覆盖数值类(number_greater、number_between、number_eq等)、文本类(text_contains、text_starts_with、text_is_email、text_is_url等)、日期类(date_before、date_after、date_between等)以及one_of_list、one_of_range、custom_formula、boolean、blank/not_blank等丰富条件。相关测试见 tests/worksheet_test.py(如test_add_validation)。

v5.12 → v6.0 迁移指南

README 单独用一个章节总结升级 v6 的破坏性变更,这是升级老项目时最容易踩坑的部分。

1. Python 3.7 停止支持

v6 最低要求 Python 3.8,因为 3.7 已进入 EOL。升级前先确认运行环境。

2.Worksheet.update参数顺序交换

values与range_name的前两个参数位置互换了。v6 下两种写法等价:

- file.sheet1.update([["new", "values"]]) + file.sheet1.update([["new", "values"]]) # 单个参数写法不变 - file.sheet1.update("B2:C2", [["54", "55"]]) + file.sheet1.update([["54", "55"]], "B2:C2") # 或(推荐,v5/v6 通用) + file.sheet1.update(range_name="B2:C2", values=[["54", "55"]])

同时,values不再允许一维列表,必须传 2D 数组。源码中 gspread/worksheet.py 对旧顺序的调用会发出DeprecationWarning并自动交换,属于兼容过渡逻辑。

3. 颜色从字典改为十六进制字符串

v6 全面使用十六进制颜色表示。update_tab_color()等接口不再接受 RGB 字典:

- tab_color = {"red": 1, "green": 0.5, "blue": 1} + tab_color = "#FF7FFF" file.sheet1.update_tab_color(tab_color)

若手头是旧字典格式,可用兼容函数gspread.utils.convert_colors_to_hex_value()转成十六进制字符串(反向转换可用convert_hex_to_colors_dict(),两者均定义于 gspread/utils.py)。从 gspread/worksheet.py 的get_tab_color()也可看到,读取到的 tab 颜色现在以 hex 形式返回。

4.lastUpdateTime从属性改为方法

- age = spreadsheet.lastUpdateTime + age = spreadsheet.get_lastUpdateTime()

5.Worksheet.get_records被移除

v6 只能通过get_all_records()获取全部记录。想取部分记录,需自行获取表头与数据行后,用gspread.utils.to_records()组装:

+ from gspread import utils all_records = spreadsheet.get_all_records(head=1) - some_records = spreadsheet.get_all_records(head=1, first_index=6, last_index=9) - some_records = spreadsheet.get_records(head=1, first_index=6, last_index=9) + header = spreadsheet.get("1:1")[0] + cells = spreadsheet.get("6:9") + some_records = utils.to_records(header, cells)

6. 静默 v5 的弃用警告

v5 中大量标记弃用特性/函数/方法的警告,可通过环境变量关闭:

export GSPREAD_SILENCE_WARNINGS=1

7.gspread.Worksheet.__init__新增参数

v6 起手动构造Worksheet必须额外传入spreadsheet_id与http_client(源码 gspread/worksheet.py 对缺失参数会直接抛RuntimeError):

gc = gspread.service_account(filename="google_credentials.json") spreadsheet = gc.open_by_key("{{key}}") properties = spreadsheet.fetch_sheet_metadata()["sheets"][0]["properties"] - worksheet = gspread.Worksheet(spreadsheet, properties) + worksheet = gspread.Worksheet(spreadsheet, properties, spreadsheet.id, gc.http_client)

不过官方不推荐手动实例化Worksheet,建议始终通过spreadsheet.get_worksheet(0)、worksheet("title")等现成方法获取。

测试验证与源码结构

仓库在 tests/ 下提供了覆盖上述能力的录制品测试(VCR cassettes),例如 tests/worksheet_test.py 中的test_update_and_get、test_find、test_findall、test_get_values_merge_cells_with_named_range、test_add_validation,以及 tests/client_test.py 中的test_open_by_key_has_metadata、test_create、test_copy、test_list_spreadsheet_files等。阅读这些测试可以直观理解每个 API 的实际调用形态与预期行为,是进一步深入源码(gspread/client.py、gspread/worksheet.py、gspread/spreadsheet.py、gspread/http_client.py)的良好入口。

进一步阅读

  • 认证细节:仓库文档 docs/oauth2.rst 与 docs/auth.rst;
  • API 参考:docs/api/client.rst、docs/api/spreadsheet.rst、docs/api/worksheet.rst(对应 docs/api/models/ 目录);
  • 进阶用法:docs/advanced.rst、docs/user-guide.rst;
  • 工具函数与枚举:gspread/utils.py;
  • 异常体系:docs/api/exceptions.rst 与 gspread/exceptions.py。

遇到使用问题,建议先在仓库 tests/ 与 HISTORY.rst 中检索对应行为,再结合本文的源码路径定位实现细节。

  • 后端

【免费下载链接】gspread

Google Sheets Python API

项目地址:https://gitcode.com/gh_mirrors/gs/gspread
点击查看免费下载
上一篇:Cozy Cube Godot Addons:17款实用插件完整解析,助力3D游戏开发效率提升
下一篇:CANN应用开发使用约束

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询