在 gspread 中,如何删除所有工作表并重新开始?
In gspread, how I do delete all worksheets and start over?
对于我的用例,我必须动态生成一些报告,所以我认为从头开始创建报告会更容易。每次用户请求报告时,我都想先清除整个电子表格,然后根据新的数据库查询生成工作表。我试图遍历每个工作表并删除每个工作表,但我无法删除最后一个。这是我的代码:
import gspread
gc = gspread.service_account()
sh = gc.open("My Google Sheet")
for s in sh.worksheets():
sh.del_worksheet(s)
这是我遇到的错误:
---------------------------------------------------------------------------
APIError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_17768/423772843.py in <module>
1 sh = gc.open(report_name)
2 for s in sh.worksheets():
----> 3 sh.del_worksheet(s)
~\anaconda3\envs\analytics\lib\site-packages\gspread\spreadsheet.py in del_worksheet(self, worksheet)
436 body = {"requests": [{"deleteSheet": {"sheetId": worksheet.id}}]}
437
--> 438 return self.batch_update(body)
439
440 def reorder_worksheets(self, worksheets_in_desired_order):
~\anaconda3\envs\analytics\lib\site-packages\gspread\spreadsheet.py in batch_update(self, body)
128 .. versionadded:: 3.0
129 """
--> 130 r = self.client.request(
131 "post", SPREADSHEET_BATCH_UPDATE_URL % self.id, json=body
132 )
~\anaconda3\envs\analytics\lib\site-packages\gspread\client.py in request(self, method, endpoint, params, data, json, files, headers)
78 return response
79 else:
---> 80 raise APIError(response)
81
82 def list_spreadsheet_files(self, title=None, folder_id=None):
APIError: {'code': 400, 'message': "Invalid requests[0].deleteSheet: You can't remove all the sheets in a document.", 'status': 'INVALID_ARGUMENT'}
您无法删除最后一个 sheet,但解决此问题的一种方法是添加一个新的空白 sheet,然后删除您想要的所有 sheet删除,建立你的报告,最后删除空白 sheet.
我认为您出现问题的原因是 Google Spreadsheet 的当前规范无法删除所有 sheet。评论和现有答案中已经提到了这一点。
关于你的脚本,当我看到gsperad的脚本时,似乎sh.del_worksheet(s)
是运行,使用一个SheetsAPI的配额。 Ref 这样,当循环使用sh.del_worksheet(s)
时,将连续使用Sheets API。当sheet个数很大时,我担心会出现错误。
因此,在这个回答中,我想提出一个示例脚本,通过 2 API 次调用来实现您的目标。
模式一:
在此模式中,第一个 sheet 被清除,除第一个 sheet 之外的其他 sheet 被删除。
worksheets = sh.worksheets()
reqs = [{"repeatCell": {"range": {"sheetId": s.id}, "fields": "*"}} if i == 0 else {"deleteSheet": {"sheetId": s.id}} for i, s in enumerate(worksheets)]
sh.batch_update({"requests": reqs})
模式二:
在此模式中,插入了一个新的 sheet 并删除了所有其他 sheet。
worksheets = sh.worksheets()
reqs = [{"addSheet": {"properties": {"index": 0}}}] + [{"deleteSheet": {"sheetId": s.id}} for s in worksheets]
sh.batch_update({"requests": reqs})
注:
- 在这些示例脚本中,
sh.worksheets()
使用一个 API 调用。而且,sh.batch_update({"requests": reqs})
使用了一个 API 呼叫。
参考:
对于我的用例,我必须动态生成一些报告,所以我认为从头开始创建报告会更容易。每次用户请求报告时,我都想先清除整个电子表格,然后根据新的数据库查询生成工作表。我试图遍历每个工作表并删除每个工作表,但我无法删除最后一个。这是我的代码:
import gspread
gc = gspread.service_account()
sh = gc.open("My Google Sheet")
for s in sh.worksheets():
sh.del_worksheet(s)
这是我遇到的错误:
---------------------------------------------------------------------------
APIError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_17768/423772843.py in <module>
1 sh = gc.open(report_name)
2 for s in sh.worksheets():
----> 3 sh.del_worksheet(s)
~\anaconda3\envs\analytics\lib\site-packages\gspread\spreadsheet.py in del_worksheet(self, worksheet)
436 body = {"requests": [{"deleteSheet": {"sheetId": worksheet.id}}]}
437
--> 438 return self.batch_update(body)
439
440 def reorder_worksheets(self, worksheets_in_desired_order):
~\anaconda3\envs\analytics\lib\site-packages\gspread\spreadsheet.py in batch_update(self, body)
128 .. versionadded:: 3.0
129 """
--> 130 r = self.client.request(
131 "post", SPREADSHEET_BATCH_UPDATE_URL % self.id, json=body
132 )
~\anaconda3\envs\analytics\lib\site-packages\gspread\client.py in request(self, method, endpoint, params, data, json, files, headers)
78 return response
79 else:
---> 80 raise APIError(response)
81
82 def list_spreadsheet_files(self, title=None, folder_id=None):
APIError: {'code': 400, 'message': "Invalid requests[0].deleteSheet: You can't remove all the sheets in a document.", 'status': 'INVALID_ARGUMENT'}
您无法删除最后一个 sheet,但解决此问题的一种方法是添加一个新的空白 sheet,然后删除您想要的所有 sheet删除,建立你的报告,最后删除空白 sheet.
我认为您出现问题的原因是 Google Spreadsheet 的当前规范无法删除所有 sheet。评论和现有答案中已经提到了这一点。
关于你的脚本,当我看到gsperad的脚本时,似乎sh.del_worksheet(s)
是运行,使用一个SheetsAPI的配额。 Ref 这样,当循环使用sh.del_worksheet(s)
时,将连续使用Sheets API。当sheet个数很大时,我担心会出现错误。
因此,在这个回答中,我想提出一个示例脚本,通过 2 API 次调用来实现您的目标。
模式一:
在此模式中,第一个 sheet 被清除,除第一个 sheet 之外的其他 sheet 被删除。
worksheets = sh.worksheets()
reqs = [{"repeatCell": {"range": {"sheetId": s.id}, "fields": "*"}} if i == 0 else {"deleteSheet": {"sheetId": s.id}} for i, s in enumerate(worksheets)]
sh.batch_update({"requests": reqs})
模式二:
在此模式中,插入了一个新的 sheet 并删除了所有其他 sheet。
worksheets = sh.worksheets()
reqs = [{"addSheet": {"properties": {"index": 0}}}] + [{"deleteSheet": {"sheetId": s.id}} for s in worksheets]
sh.batch_update({"requests": reqs})
注:
- 在这些示例脚本中,
sh.worksheets()
使用一个 API 调用。而且,sh.batch_update({"requests": reqs})
使用了一个 API 呼叫。