python gspread library only writes to worksheet labeled 'sheet1' - python

My sheet is named 'doc_name', and it has two worksheets, 'sheet1' and 'sheet2'. but, i can only write data to the worksheet labeled 'sheet1'?
is this a limitation or am i doing something wrong?
this works,
wks = gc.open("doc_name").sheet1
but this fails,
wks = gc.open("doc_name").sheet2
giving this error,
AttributeError: 'Spreadsheet' object has no attribute 'sheet2'
i also notice that this fails,
wks = gc.open("doc_name").Sheet1
...where i use a capital 'S'.. and it will only write if i specify lowercase .sheet1
how do i write to a worksheet without having to code... wks = gc.open("doc_name").sheet1?

This is because gspread only implemented sheet1 to let you retrieve the first sheet in your spreadsheet as a shortcut.
From the source code you can see the implementation of sheet1 is using get_worksheet(0)
#property
def sheet1(self):
"""Shortcut property for getting the first worksheet."""
return self.get_worksheet(0)
So if you want to retrieve other sheets, you need to use other methods like:
1.specify index as a integer indicating the position of the sheet to open starting from 0:
wks = gc.open("doc_name").get_worksheet(index)
or
2.specify title of the sheet to open as a string:
wks = gc.open("doc_name").worksheet(title)
That is to say, in you case, to get sheet2 you can probably use
wks = gc.open("doc_name").get_worksheet(1)

client = gspread.authorize(creds)
sheet = client.open('name').worksheet('name/title')

Related

Update specific tab on google sheet - Python

I have the following code to append a dataframe in to a google sheet that runs everyday.
I had to create 03 more tabs in to this sheet and now, every time I upload the dataframe it goes to another tab and not the one that I need.
I`m using the following code to update the gsheet:
gc = gspread.authorize(credentials)
sh = gc.open_by_key("1O1NKT4LRf7F17kRjupUD7peonCwT04BG-l7pbo5-BLU").sheet1
values = df.values.tolist()
sh.append_rows(values)
I tried a few things such as
sh = gc.open_by_key("1O1NKT4LRf7F17kRjupUD7peonCwT04BG-l7pbo5-BLU").tabname
But it didnt work. Is there a way to do that?
thank you
Using sheet1 will give you the first worksheet in your spreadsheet, if your target sheet is not the first worksheet then you might need to use other methods to access that particular worksheet.
Best option is to get the worksheet by title (if you select worksheet using indexes, you need to update your code if ever you re-arranged your tabs. Hence the best option is to select worksheet by its title)
Here are all the options that you can use to select a worksheet using gspread:
Select worksheet by index. Worksheet indexes start from zero:
sh = gc.open_by_key("1O1NKT4LRf7F17kRjupUD7peonCwT04BG-xxxxxx")
worksheet = sh.get_worksheet(0)
Or by title:
worksheet = sh.worksheet("January")
Or the most common case: Sheet1:
worksheet = sh.sheet1
To get a list of all worksheets: (check each worksheet in the list based on their title)
worksheet_list = sh.worksheets()

does this library assume the Google Spreadsheet will have one sheet only?

I am trying to use this library to pull data from a Googlespreadsheet with two sheets in it, I can get data only from the first sheet but not the second sheet. sheet = client.open("sheetname").sheet1, if I change sheet1 to sheet2 I get the following error sheet = client.open("filename").sheet2 AttributeError: 'Spreadsheet' object has no attribute 'sheet2' how do I fix this? any help is appreciated!
.sheet1 is used as a shortcut.
In order to get the second sheet try that:
sheet = client.open("filename").get_worksheet(1)
1 means second sheet (starting from 0).
References:
Official documentation
In this case, you can use get_worksheet, worksheet and worksheets.
Sample script:
sh = client.open("###Spreadsheet name###") # or client.open_by_key(spreadsheetId)
worksheet = sh.get_worksheet(1) # Use the index of the sheet. 0 is the 1st sheet.
worksheet = sh.worksheet('Sheet2') # Use the sheet name of the sheet.
worksheet = sh.worksheets()[1] # In this case, all sheets are included in the array.
Note:
In the current stage, it seems that sh.sheet1 is only the 1st sheet.
Reference:
Selecting a Worksheet

GSPREAD: How do I fetch the last added worksheet from a spreadsheet having many worksheets?

Using gspread, I know how to access a sheet by name, id or index, like:
import gspread
gc = gspread.authorize(credentials)
worksheet = sh.worksheet("January")
or
worksheet = sh.sheet1
But I was wondering if it is possible to open a last added or last updated sheet?
It's not possible to get the last modification of each spreadsheet sheet because this modification is fetched through Google Drive.
It's possible to obtain the last modification of the entire worksheet using the lastUpdateTime:
import gspread
sa = gspread.service_account('authentication')
sa.open("worksheet name").lastUpdateTime

Obtain name of worksheet using openpyxl

I am using openpyxl to access all of the tabs in a spreadsheet using the following:
rawReturnwb = openpyxl.load_workbook(ValidationsDir)
for sheet in rawReturnwb.worksheets:
do something...
This works fine. I then would like to access the worksheet name to use else where in my code. However when I try access the worksheet name (printing sheet to the console) I get:
<Worksheet "SheetName">
the type of sheet is
<class 'openpyxl.worksheet.worksheet.Worksheet'>
Is there a way that I can just get the worksheet name returned (so my output would be "SheetName" only. Or would I have to convert to string and strip the parts of the string I don't need?
As suggested in comment of the question, sheet.title is working.
For example, this is some code to get the Worksheet name from a given cell:
from openpyxl.cell import Cell
def get_cell_name(cell:Cell) -> str:
"""Get the name of the Worksheet of a given cell"""
return cell.parent.title
And in the case of the OP, the code could be something like:
rawReturnwb = openpyxl.load_workbook(ValidationsDir)
for sheet in rawReturnwb.worksheets:
# ...
if sheet.title == "Sheet1":
continue
# ...
FYI, the names of the variables are weird:
They should be lowercase in Python (according to PEP-8)
ValdiationsDir is weird, for the path of an Excel File
rawReturnwb could be renamed to book for example

Create internal links within excelsheet with openpyxl

I created a excelfile with around 50 worksheets. All information is in the summary in the first worksheet, but for detailed information people can check the source in the worksheet.
I thought it would be nice to have an internal link to the worksheet (people want to know why the sales were down in July 2016 worksheet etc).
But while I seem to be able to create hyperlinks to websites, I just want to make it work in this excel file.
Is this possible at all?
This question is more about Excel than Python or programming, but you have to use #, for example:
ws = wb['Sheet1']
cell = ws.cell('A1')
cell.value = '=HYPERLINK("#Sheet2!A2")'
You can also give the cell a human-friendly display text:
cell.value = '=HYPERLINK("#Sheet2!A2", "click here")'
Will create a link in cell A1 in Sheet1 to cell A2 in Sheet2.
The 2 cells may or may not be on the same sheet.
The # tells Excel that this is an hyperlink to a local location, much like # is used as an anchor in HTML.
Here is a function which can be used directly to create hyperlink to a sheet in same excel:
def create_hyperlink(ws, at_cell, sheet_name, cell_ref='A1', display_name=None):
if display_name is None:
display_name = sheet_name
to_location = "'{0}'!{1}".format(sheet_name, cell_ref)
ws[at_cell].hyperlink = Hyperlink(display=display_name, ref=at_cell, location=to_location)
ws[at_cell].value = display_name
ws[at_cell].font = Font(u='single', color=colors.BLUE)
ws: worksheet where the links will be created
at_cell: cell location where links will be created. e.g. 'A1'
sheet_name: sheet_name of which the link will be created. e.g. 'Sheet1'
Actually, you can add local hyperlinks but have to control the location. The specification says this of the location attribute:
Location within target. If target is a workbook (or this workbook)
this shall refer to a sheet and cell or a defined name. Can also be an
HTML anchor if target is HTML file.
I think this works by setting target to None and ref to the cell reference.

Categories