简体   繁体   English

在 gspread 中,如何删除所有工作表并重新开始?

[英]In gspread, how I do delete all worksheets and start over?

For my use case, I have to generate some reports dynamically, so I thought it would be easier to just create the report from scratch.对于我的用例,我必须动态生成一些报告,所以我认为从头开始创建报告会更容易。 Every time the user requests the report, I would like to first clear the entire spreadsheet and then generate the worksheets from fresh database queries.每次用户请求报告时,我都想先清除整个电子表格,然后根据新的数据库查询生成工作表。 I tried to loop through every worksheet and delete each one, but I couldn't delete the last one.我试图遍历每个工作表并删除每个工作表,但我无法删除最后一个。 Here is my code:这是我的代码:

import gspread
gc = gspread.service_account()
sh = gc.open("My Google Sheet")
for s in sh.worksheets():
    sh.del_worksheet(s)

Here is the error I'm getting:这是我得到的错误:

---------------------------------------------------------------------------
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'}

You can't delete the last sheet, but one way to work around this is to add a new blank sheet, and then delete all the sheets you want to delete, build your report, and at the end delete the blank sheet.您无法删除最后一张工作表,但解决此问题的一种方法是添加新的空白工作表,然后删除所有要删除的工作表,构建报表,最后删除空白工作表。

I think that the reason for your issue is due to that all sheets cannot be removed by the current specification at Google Spreadsheet.我认为您遇到问题的原因是 Google Spreadsheet 的当前规范无法删除所有工作表。 This has already been mentioned in the comments and the existing answer.评论和现有答案中已经提到了这一点。

About your script, when I saw the script of gsperad, it seems that sh.del_worksheet(s) is run by using one quota of Sheets API. Ref By this, when sh.del_worksheet(s) is used in a loop, Sheets API is continuously used.关于你的脚本,当我看到 gsperad 的脚本时,似乎sh.del_worksheet(s)是使用一个配额的 Sheets API 运行的。 参考这个,当sh.del_worksheet(s)在循环中使用时,Sheets API被连续使用。 When the number of sheets is large, I'm worried that an error might occur.当张数很大时,我担心会发生错误。

So, in this answer, I would like to propose a sample script for achieving your goal with 2 API calls.因此,在这个答案中,我想提出一个示例脚本,用于通过 2 API 调用实现您的目标。

Pattern 1:模式 1:

In this pattern, 1st sheet is cleared and other sheets except for the 1st sheet are removed.在此模式中,第 1 张纸被清除,除第 1 张纸外的其他纸被移除。

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})

Pattern 2:模式 2:

In this pattern, a new sheet is inserted and all other sheets are removed.在此模式中,插入一张新纸并移除所有其他纸。

worksheets = sh.worksheets()
reqs = [{"addSheet": {"properties": {"index": 0}}}] + [{"deleteSheet": {"sheetId": s.id}} for s in worksheets]
sh.batch_update({"requests": reqs})

Note:笔记:

  • In these sample scripts, sh.worksheets() uses one API call.在这些示例脚本中, sh.worksheets()使用一个 API 调用。 And, sh.batch_update({"requests": reqs}) uses one API call.并且, sh.batch_update({"requests": reqs})使用一个 API 调用。

Reference:参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM