Finding the file_id of a spreadsheet using gspread - python

I'm trying to clear up some space in my Google service account. I've been using it to handle spreadsheets and I want to delete some spreadsheets that I have created earlier. To delete a spreadsheet, there if function as gc.del_spreadsheet(file_id) in gspread. However, I could not find a way to retrieve the files ids of the spreadsheets that I want to delete.
I could not find a way to open the google drive of the service account like a google drive of a personal account. Therefore, I used the following code to list all the spreadsheets in the account as of now. The code outputs the spreadsheet title but not the file id which is required to delete the spreadsheet.
def upload_to_google_sheets():
scope = ['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name("client.json", scope)
gc = gspread.authorize(credentials)
print('authorized')
titles_list = []
for spreadsheet in gc.openall():
titles_list.append(spreadsheet.title)
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(titles_list)
upload_to_google_sheets()
The final objective is to delete spreadsheets using gspread del_spreadsheet function which requires "file_id".

You want to retrieve Spreadsheet title and Spreadsheet ID using gspread.
If my understanding is correct, how about this modification?
From:
titles_list.append(spreadsheet.title)
To:
titles_list.append({'title': spreadsheet.title, 'id': spreadsheet.id})
The object spreadsheet of for spreadsheet in gc.openall(): includes the Spreadsheet ID.
In order to retrieve Spreadsheet ID, in your script, please use spreadsheet.id.
By this modification, you can retrieve the following result.
[ { 'id': '### Spreadsheet ID1 ###',
'title': '### Spreadsheet name1 ###'},
{ 'id': '### Spreadsheet ID2 ###',
'title': '### Spreadsheet name2 ###'},
,
,
,
]
Reference:
gspread
If I misunderstood your question and this was not the result you want, I apologize.

Related

How to create multiple sheets in a spreadsheet by gspread and python?

I am new to Python and wanna practice using gspread and python to deal with spreadsheets. Now I already knew how to connect google spreadsheet with gspread, but still cannot figure out how to create multiple sheets at once.
My expectation:
Create multiple sheets naming by Employees' names at once
So every employee can use their own sheet
Thanks in advance!
employee_name = ['Jonny','Emma', ...]
You can do this, for example:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
# Set up the credentials and client
scopes = ['https://spreadsheets.google.com/feeds']
credentials = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scopes)
client = gspread.authorize(credentials)
# Open the spreadsheet
spreadsheet = client.open("My Spreadsheet")
# Get the list of employee names
employee_names = ['Jonny', 'Emma', ...]
# Iterate over the list of names and create a sheet for each of the employee
for name in employee_names:
spreadsheet.add_worksheet(title=name, rows=100, cols=20)
This is going to open the sheet, get the list of employees and loop over the list and in that way, you create a new sheet for each employee with the name of the actual employee as the sheet title. Hope it helps
References:
https://docs.gspread.org/en/v5.7.0/
From your following reply,
Actually, I think 2nd is just the consequence of the 1st request, so sorry for making misunderstanding! my thought is that I can use: worksheet = sh.add_worksheet(title="A worksheet", rows=100, cols=20) to create a worksheet, but i don't know how to create multiple worksheets.
I understood that you wanted to add multiple sheets in a Google Spreadsheet using gspread for python. In this case, how about the following sample script?
Sample script:
client = # Please use your client.
employee_names = ["Jonny", "Emma",,,] # Please set the sheet names.
spreadsheetId = "###" # Please set your spreadsheet ID.
requests = [
{
"addSheet": {
"properties": {
"title": e,
"gridProperties": {"rowCount": 100, "columnCount": 20},
}
}
}
for e in employee_names
]
spreadsheet = client.open_by_key(spreadsheetId)
spreadsheet.batch_update({"requests": requests})
In this sample script, the multiple sheets can be inserted by one API call by creating a request body. If sh.add_worksheet() is used, multiple API calls are required to be used. So, I proposed the above script.
Although I used "gridProperties": {"rowCount": 100, "columnCount": 20} from your showing script, in this case, even when "gridProperties": {"rowCount": 100, "columnCount": 20} is not used, the sheets are inserted as the default rows (1000) and columns (26).
References:
Method: spreadsheets.batchUpdate
AddSheetRequest

Copy paste Google sheet without formulae and just data

I want to copy a sheet from a Google sheet to another Google sheet where I want to keep the data and formatting intact but not the formula.
Just want to copy the cell values to another sheet i.e. raw data.
I am using the google sheets api -
spreadsheets().sheets().copyTo(spreadsheetId=spreadsheet_id, sheetId=sheet_id, body={'destination_spreadsheet_id': target_spreadsheet})
but this is copying the formula and throws error
I believe your goal is as follows.
You want to copy a sheet in a source Spreadsheet to a destination Spreadsheet.
You want to remove the formulas while the cell formats and the cell values are kept.
You want to achieve this using googleapis for python.
In this case, how about the following patterns?
Pattern 1:
In this pattern, your showing script is modified.
service = build("sheets", "v4", credentials=creds) # Please use your client.
srcSpreadsheetId = "###" # Please set source Spreadsheet ID.
srcSheetId = "###" # Please set source sheet ID.
dstSpreadsheetId = "###" # Please set destination Spreadsheet ID.
res = service.spreadsheets().sheets().copyTospreadsheetId=srcSpreadsheetId, sheetId=srcSheetId, body={"destination_spreadsheet_id": dstSpreadsheetId}).execute()
)
service.spreadsheets().batchUpdate(spreadsheetId=dstSpreadsheetId, body={"requests": [{"copyPaste": {"source": {"sheetId": res["sheetId"]},"destination": {"sheetId": res["sheetId"]},"pasteType": "PASTE_VALUES"}}]}).execute()
When this script is run, a sheet in a source Spreadsheet is copied to a destination Spreadsheet. In this case, the formulas are also copied. And, only the values are copied using batchUpdate method. By this, the cell formats and the values are copied without the formulas.
Pattern 2:
In this pattern, the copy process is changed from the above pattern. Because, when the above script is used, if the formulas using the other sheets and Spreadsheet are included in the source sheet, the copied sheet has no values. Unfortunately, from your question, I couldn't confirm this. So, I would like to propose this pattern 2.
service = build("sheets", "v4", credentials=creds) # Please use your client.
srcSpreadsheetId = "###" # Please set source Spreadsheet ID.
srcSheetId = "###" # Please set source sheet ID.
dstSpreadsheetId = "###" # Please set destination Spreadsheet ID.
# 1. Duplicate the source sheet in the source Spreadsheet as a temporal sheet.
newSheetId = "123456789"
service.spreadsheets().batchUpdate(spreadsheetId=srcSpreadsheetId,body={"requests": [{"duplicateSheet": {"sourceSheetId": srcSheetId,"newSheetId": newSheetId}}]}).execute()
time.sleep(3)
# 2. Remove formulas.
service.spreadsheets().batchUpdate(spreadsheetId=srcSpreadsheetId,body={"requests": [{"copyPaste": {"source": {"sheetId": newSheetId},"destination": {"sheetId": newSheetId},"pasteType": "PASTE_VALUES"}}]}).execute()
# 3. Copy the source sheet from the source Spreadsheet to the destination Spreadsheet.
service.spreadsheets().sheets().copyTo(spreadsheetId=srcSpreadsheetId,sheetId=newSheetId,body={"destination_spreadsheet_id": dstSpreadsheetId}).execute()
# 4. Delete temporal sheet from source Spreadsheet.
service.spreadsheets().batchUpdate(spreadsheetId=srcSpreadsheetId,body={"requests": [{"deleteSheet": {"sheetId": newSheetId}}]},
).execute()
When this script is run, the following flow is run.
Duplicate the source sheet in the source Spreadsheet as a temporal sheet.
Remove formulas.
Copy the source sheet from the source Spreadsheet to the destination Spreadsheet.
Delete temporal sheet from source Spreadsheet.
If the copied sheet has no value from the formulas, please increase 3 of time.sleep(3).
References:
Method: spreadsheets.sheets.copyTo
Method: spreadsheets.batchUpdate
You could use SpreadsheetApp:
const destination = SpreadsheetApp.openById("id1")
const source = SpreadsheetApp.openById("id2")
source.getSheetByName("sheet-name").copyTo(destination)

How to write data in a specific tab of a spreadsheet with the Google Sheets API in Python?

I'm writing data in a Google Sheet using this function :
def Export_Data_To_Sheets(df):
response_date = service.spreadsheets.values().update(
spreadsheetId=SAMPLE_SPREADSHEET_ID_input,
valueInputOption='RAW',
range=SAMPLE_RANGE_NAME,
body=dict(
majorDimension='ROWS',
values=df.T.reset_index().T.values.tolist()[1:])
).execute()
print('Sheet successfully Updated')
It works well, but I have two tabs in my Google Sheet and I would like to choose in which one I want to write data. I don't know how can I do this.
In this point in the code:
range=SAMPLE_RANGE_NAME
You can replace this value with a sheet and cell reference, something like:
range="Sheet1!A1:D5"
Reference
Writing a Single Range

Using gspread to extract sheet ID

Can't seem to find any answer to this, but are there any functions/methods which can get a worksheet ID?
Currently, my code looks like this:
scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
....code to authorize credentials goes here....
sheet = client.open(str(self.googleSheetFile)).worksheet(str(self.worksheet))
client.import_csv('abcdefg1234567abcdefg1234567', contents)
but I don't want to hardcode the abcdefg1234567abcdefg1234567. Is there anything I can do, like sheet.id()?
I believe your goal as follows.
In order to use import_csv, you want to retrieve the Spreadsheet ID from sheet = client.open(str(self.googleSheetFile)).worksheet(str(self.worksheet)).
You want to achieve this using gspread with python.
In this case, you can retrieve the Spreadsheet ID from client.open(str(self.googleSheetFile)). So please modify your script as follows.
From:
sheet = client.open(str(self.googleSheetFile)).worksheet(str(self.worksheet))
client.import_csv('abcdefg1234567abcdefg1234567', contents)
To:
spreadsheet = client.open(str(self.googleSheetFile))
sheet = spreadsheet.worksheet(str(self.worksheet))
client.import_csv(spreadsheet.id, contents)
Note:
When I saw the document of gspread, it says as follows. So please be careful this.
This method removes all other worksheets and then entirely replaces the contents of the first worksheet.
This modified script supposes that you have already been able to get and put values for Google Spreadsheet using Sheets API with gspread.
Reference:
import_csv(file_id, data)

GSpread how to duplicate sheet

After googling and searching on Stackoveflow, I think I can't find a guide on how to duplicate existing sheet(existing Template sheet) and saving it into another sheet.
as per docs, there is duplicate_sheet but I can't manage to do a working example, anyone that can guide me with this?
import gspread
from gspread.models import Cell, Spreadsheet
scope = [
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive",
]
json_key_absolute_path = "key.json"
credentials = ServiceAccountCredentials.from_json_keyfile_name(json_key_absolute_path, scope)
client = gspread.authorize(credentials)
spreadsheet_client = Spreadsheet(client)
spreadsheet_client.duplicate_sheet("18Qk5bzuA7JOBD8CTgwvKYRiMl_35it5AwcFG2Bi5npo", new_sheet_name="timcard2")
worksheet = client.open("timcard2")
worksheet.share("my_email#google.com", perm_type='user', role='writer')
You want to copy the source Spreadsheet as new Spreadsheet.
You want to achieve this using gspread with python.
You have already been able to get and put values for Google Spreadsheet using Sheets API.
If my understanding is correct, how about this answer?
Issue and solution:
It seems that duplicate_sheet method of gspread is used for copying a sheet in the source Spreadsheet to the same source Spreadsheet. Ref In order to copy the source Spreadsheet as new Spreadsheet, pleas use the method of copy() of Class Client.
Sample script:
Please modify your script as follows.
From:
client = gspread.authorize(credentials)
spreadsheet_client = Spreadsheet(client)
spreadsheet_client.duplicate_sheet("18Qk5bzuA7JOBD8CTgwvKYRiMl_35it5AwcFG2Bi5npo", new_sheet_name="timcard2")
worksheet = client.open("timcard2")
worksheet.share("my_email#google.com", perm_type='user', role='writer')
To:
client = gspread.authorize(credentials)
client.copy("18Qk5bzuA7JOBD8CTgwvKYRiMl_35it5AwcFG2Bi5npo", title="timcard2", copy_permissions=True)
worksheet = client.open("timcard2")
worksheet.share("my_email#google.com", perm_type='user', role='writer')
When you run the script, the Spreadsheet which has the spreadsheet ID of 18Qk5bzuA7JOBD8CTgwvKYRiMl_35it5AwcFG2Bi5npo is copied as the spreadsheet name of timcard2. And, the permission information of the source Spreadsheet is also copied.
Note:
In this case, when copy_permissions=True is used, the permission information is also copied. So although I'm not sure about your actual situation, it might not be required to use worksheet.share("my_email#google.com", perm_type='user', role='writer'). Please be careful this.
References:
duplicate_sheet
copy(file_id, title=None, copy_permissions=False)
Added:
You want to copy one of sheets in Google Spreadsheet.
I could understand like above. For this, the sample script is as follows.
Sample script:
client = gspread.authorize(credentials)
client.copy("18Qk5bzuA7JOBD8CTgwvKYRiMl_35it5AwcFG2Bi5npo", title="timcard2", copy_permissions=True)
ss = client.open("timcard2")
ss.share("my_email#google.com", perm_type='user', role='writer')
delete_sheets = ["Sheet2", "Sheet3", "Sheet4"] # Please set the sheet names you want to delete.
for s in delete_sheets:
ss.del_worksheet(ss.worksheet(s))
In this sample, the sheets of "Sheet2", "Sheet3", "Sheet4" are deleted from the copied Spreadsheet.
Reference:
del_worksheet(worksheet)

Categories