问题
I am trying to create a google spreadsheet from a template and then edit its values (cells). Manually, I just visit the original spreadsheet and click Make a copy from the File menu. I have not found a way to do that using Python3 and gspread. So, I am trying to find a workaround instead.
So, I am using a Python script in order to create new google sheets as shown in the snippet (I only used it as a viewer for this question here):
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from pprint import pprint
from googleapiclient import discovery
scope = ['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scope)
gc = gspread.authorize(credentials)
service = discovery.build('sheets', 'v4', credentials=credentials)
spreadsheet_body = {
"properties": {
"title": "xxGoogleAPIMasterTemplatexx"
}
}
request = service.spreadsheets().create(body=spreadsheet_body)
response = request.execute()
#Changing permissions for the user (from the credentials.json) and then the real user (me)
gc.insert_permission(response['spreadsheetId'], 'xxx@xxx-182311.iam.gserviceaccount.com', perm_type='user', role='owner')
gc.insert_permission(response['spreadsheetId'], 'xxx.xxx@gmail.com', perm_type='user', role='owner')
The new spreadsheet is called xxGoogleAPIMasterTemplatexx as I expected (script). Now, I am trying to copy a sheet from one spreadsheet (the original template) to the newly created spreadsheets.
My step now is to first test whether the copy_to_spreadsheet works
for specific IDs. I used the following script:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from pprint import pprint
from googleapiclient import discovery
scope = ['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scope)
gc = gspread.authorize(credentials)
# The ID of the spreadsheet containing the sheet to copy. Everybody has access!!!
spreadsheet_id = '1lw6FVG_gSDseDdseS54jOyXph74k_XfTvnyU2Wqd7yo'
#sheet = gc.open_by_key(response['spreadsheet_id']).Sheet1
# The ID of the sheet to copy. Everybody has access!!!
sheet_id = 0
copy_sheet_to_another_spreadsheet_request_body = {
{
"destinationSpreadsheetId": "1d8CeUxukBIOUpADE6eBlaksS2ptBjI0vIRpVm8ufEbs"
}
}
request = service.spreadsheets().sheets().copyTo(spreadsheetId=spreadsheet_id, sheetId=sheet_id, body=copy_sheet_to_another_spreadsheet_request_body)
response = request.execute()
and I got this error:
"destinationSpreadsheetId": "1d8CeUxukBIOUpADE6eBlaksS2ptBjI0vIRpVm8ufEbs"
TypeError: unhashable type: 'dict'
I am guessing the ID has to be hashable. After adding this line:
key = frozenset(dict_key.spreadsheet_id)
it still not work.
Please note that for the test purposes I changed the permissions of the files to global:
回答1:
How about a following modification?
I think that the error means that the structure of "destinationSpreadsheetId": "1d8CeUxukBIOUpADE6eBlaksS2ptBjI0vIRpVm8ufEbs"
is wrong. When it sees the right side of the document of spreadsheets.sheets.copyTo, the request body is {"destinationSpreadsheetId": ""}
. So please try a following modification.
From :
copy_sheet_to_another_spreadsheet_request_body = {
{
"destinationSpreadsheetId": "1d8CeUxukBIOUpADE6eBlaksS2ptBjI0vIRpVm8ufEbs"
}
}
To :
copy_sheet_to_another_spreadsheet_request_body = {
"destinationSpreadsheetId": "1d8CeUxukBIOUpADE6eBlaksS2ptBjI0vIRpVm8ufEbs"
}
If I misunderstand your question, I'm sorry.
Edit :
For the next error, I confirmed following patterns.
- When the user who uses this script is the owner of the spreadsheet that you want to copy, of course, the script works fine.
- When the user who uses this script is NOT the owner of the spreadsheet that you want to copy,
- If the spreadsheet is not shared, the error of
"The caller does not have permission"
occurred. This error may be the same to your situation. - If the spreadsheet is shared as
On - Anyone with the link
, the script works fine.
- If the spreadsheet is not shared, the error of
From above results, can you confirm the permission of the spreadsheet you want to copy again?
来源:https://stackoverflow.com/questions/46792942/copy-spreadsheet-sheet-to-a-another-one-with-google-api-using-python