Google Slides API update table background color - python-3.x

basically I have table (8 rows x 3 columns) within the Google slides presentation, that I want to change background color to via the API.
First item of my list of rgb color values:
cons_data_lst[0][1][-1]
>>> [0.5882353, 0.7764706, 0.4862745]
My function to produce a request body:
def update_table_cell_colors(color_list):
req = [{
'updateTableCellProperties':{
'objectId': 'obj_id',
'tableRange': {
'location': {
'rowIndex': 1,
'columnIndex': 2,
},
'rowSpan': 1,
'columnSpan': 1,
},
'tableCellProperties':{
'tableCellBackgrounFill':{
'solidFill':{
'color':{
'rgbColor':{
'red': color_list[0],
'green': color_list[1],
'blue': color_list[2],
}
}
}}
}}} ]
return req
When I send batch update to presentation I receive the following error:
HttpError: https://slides.googleapis.com/v1/presentations/1dzxYYPuqTM3VhwaR93Ep2jj_9Y2NCkSBsVBnmN6lcOs:batchUpdate?alt=json
returned "Invalid JSON payload received. Unknown name
"table_cell_backgroun_fill" at
'requests[0].update_table_cell_properties.table_cell_properties':
Cannot find field.". Details: "[{'#type':
'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations':
[{'field':
'requests[0].update_table_cell_properties.table_cell_properties',
'description': 'Invalid JSON payload received. Unknown name
"table_cell_backgroun_fill" at
\'requests[0].update_table_cell_properties.table_cell_properties\':
Cannot find field.'}]}]">
Given a list of different rgb color values, how can I create a request body to update all columns (1 to 2) row (there are 8) text background color ?
Thank you.

How about this answer?
A1:
In this section, it explains about the reason of the error.
Modification points:
From the error message of Unknown name "table_cell_backgroun_fill" at 'requests[0].update_table_cell_properties.table_cell_properties', it is found that the property name of tableCellBackgrounFill is a spelling mistake. Please modify to tableCellBackgroundFill.
At updateTableCellProperties, the property of fields is required to be used. In your case, how about adding "fields": "tableCellBackgroundFill"? You can also use 'fields': '*'.
When these modifications are reflected to your request body, it becomes as follows.
Modified request body:
req = [
{
'updateTableCellProperties': {
'objectId': 'obj_id',
'tableRange': {
'location': {
'rowIndex': 1,
'columnIndex': 2
},
'rowSpan': 1,
'columnSpan': 1
},
'tableCellProperties': {
'tableCellBackgroundFill': { # Modified
'solidFill': {
'color': {
'rgbColor': {
'red': color_list[0],
'green': color_list[1],
'blue': color_list[2],
}
}
}
}
},
'fields': 'tableCellBackgroundFill' # Added
}
}
]
Before you use this script, please check the variables of color_list and 'obj_id',
A2:
In this section, it explains about the question 2 of Given a list of different rgb color values, how can I create a request body to update all columns (1 to 2) row (there are 8) text background color ?.
In your question, you say I have table (8 rows x 3 columns) at the top of your question. But at Given a list of different rgb color values, how can I create a request body to update all columns (1 to 2) row (there are 8) text background color ?, you say columns (1 to 2). I'm confused about this. So I would like to suppose as follows.
Your table has 8 rows and 2 columns.
You want to change the background color of all columns and rows with one color.
The sample request body is as follows.
Sample request body:
req = [
{
"updateTableCellProperties":
{
"objectId": "obj_id",
"tableRange":
{
"location":
{
"rowIndex": 0,
"columnIndex": 0
},
"rowSpan": 8,
"columnSpan": 2
},
"tableCellProperties":
{
"tableCellBackgroundFill":
{
"solidFill":
{
"color":
{
"rgbColor":
{
"red": color_list[0],
"green": color_list[1],
"blue": color_list[2]
}
}
}
}
},
"fields": "tableCellBackgroundFill"
}
}
]
rowIndex and columnIndex are the start cell.
"rowIndex": 0 and "columnIndex": 0 means the cell "A1".
rowSpan and columnSpan are the number of rows and columns.
"rowSpan": 8 and "columnSpan": 2 means 8 rows and 2 columns. By this, the background colors of cells "A1:B8" are changed.
If your table is 8 rows and 3 columns, and you want to change all cells, please set them as follows.
"rowIndex": 0, "columnIndex": 0 and "rowSpan": 8, "columnSpan": 3
If you want to change the special background color every cell, it is required to create the array of request body for each cell. Please be careful this.
Note:
This answer supposes that you have already been able to put and get values for Google Slides using Slides API.
References:
UpdateTableCellPropertiesRequest
TableCellProperties
If I misunderstood your question and this didn't resolve your issue, I apologize.

Related

Create Google Sheets Bar Graph with instances of data

Suppose you have a Google Sheets page that has a table like so:
But Type 1
Bug Type 2
Bug_A
Bug_C
Bug_B
Bug_D
Bug_D
I am trying to create a bar graph that graphs the number of instances of a bug type. The data of each bug is not an integer, which means I cant map integer data like one normally would when creating bar graphs with Google Sheets API.
It seems that with the Google Sheets Python API, you can only use series' data sources with row and column indexes.
'series': [
{
'series': {
'sourceRange': {
'sources': [
{
'sheetId': 636584873,
'startRowIndex': 1,
'endRowIndex': 2,
'startColumnIndex': 0,
'endColumnIndex': len(table_values)
}
]
}
}
}
]

Google Sheets automatically changing date format while setting data in sheet using Google APIs

I am working on a project where I need to collect data from an API, store them in a matrix and set that data in a Google Sheet using the Google-Sheets-APIv4 with Node.js. Two key in that API are object.start_date and object.end_date which return date strings in the format for e.g "2021-09-22" ie. yyyy-mm-dd. I want to convert that date to dd/mm/yyyy format. The function I have implemented for the same is:
function changeDateFormat(dateString){
let a=dateString.split('-');
let t=a[0];
a[0]=a[2];
a[2]=t;
//console.log(a.join('/'));
return `${a.join('/')}`;
}
The code works fine and I have used it in the manner shown below:
let checkin=`${changeDateFormat(`${tenancy.start_date}`)}`;
console.log(checkin);
let checkout=`${changeDateFormat(`${tenancy.end_date}`)}`;
console.log(checkout);
tenancy in the code above is an object. The output that I get in the console is
which is the desired format, which shows that algorithm for changing date is working fine too.
Also, my code for adding the data in the sheet is
await googleSheets.spreadsheets.values.append({
auth,
spreadsheetId,
range:"MySheet!A2:AC",
valueInputOption:"USER_ENTERED",
resource: {values : newData}
/*newData is a 2-D array where each row has several data fields in the form newData[i]=[propertyName,id,......,check-in,checkout,.......]*/
});
However, when I add the data in the sheet, the date fields are entirely jumbled up where some have the desired dd/mm/yyyy format while others have the same yyyy-mm-dd format as shown in the image
I am not being able to solve the problem as I cannot find any error in the code either but the output is completely jumbled as it's working in some cells but not working in other cells. What might be a possible workaround for this problem? I will gladly provide any other information or data regarding the problem or my code if needed. Thanks!
I believe your goal and your situation as follows.
You want to set the number format of the cells to dd/mm/yyyy.
You want to achieve this using googleapis for Node.js.
You have already been able to get and put values for Google Spreadsheet using Sheets API.
Modification points:
For example, when the values of [["2021-01-02", "02/01/2021"]] are put to the Spreadsheet using the method of "spreadsheets.values.append" in Sheets API with valueInputOption of USER_ENTERED, each value is put as the date object. But it seems that the number format is different.
In order to use the same number format, in this answer, I would like to set the number format of dd/mm/yyyy to the cells using the method of "spreadsheets.batchUpdate".
When above points are reflected to your script, it becomes as follows.
Modified script:
Please set the value of sheetId.
await googleSheets.spreadsheets.values.append({
auth,
spreadsheetId,
range: "MySheet!A2:AC",
valueInputOption: "USER_ENTERED",
resource: { values: newData },
});
const sheetId = "###"; // <--- Please set the sheet ID of "MySheet".
const resource = {
auth,
spreadsheetId,
resource: {
requests: [
{
repeatCell: {
range: {
sheetId: sheetId,
startRowIndex: 1,
startColumnIndex: 12,
endColumnIndex: 15,
},
cell: {
userEnteredFormat: {
numberFormat: {
pattern: "dd/mm/yyyy",
type: "DATE",
},
horizontalAlignment: "RIGHT", // <--- Added
},
},
fields: "userEnteredFormat",
},
},
],
},
};
await googleSheets.spreadsheets.batchUpdate(resource);
When above modified script is run, the number format of the columns "M" to "O" is changed to dd/mm/yyyy. This is from your sample image.
If you want to modify the format and range, please modify above script.
And, at above script, the batchUpdate method reflects all rows of the columns "M" to "O". So I think that in this case, this batchUpdate method might be able to achieve your goal by only one time running.
References:
Method: spreadsheets.values.append
Method: spreadsheets.batchUpdate
RepeatCellRequest

Python Google Sheets API make values update and sheet properties update with a single batch update

I am wondering can a range of values that I want to update to a spreadsheet can be sent in a single batch update together with the spreadsheet properties update? For example (code below) I want make a spreadsheet property update (add worksheet) and then add data to the same, newly added worksheet. How can this be achieved, if it can be done using a single request? (not making 1 request .values().batchUpdate() and 2nd .batchUpdate())
I have the following:
REQUESTS = []
# addSheet request
REQUESTS.append({"addSheet": {"properties": {"title": "MySheet",'sheetId': '0'}}})
# add value request
REQUESTS.append({'range':'MySheet!A1', 'values': list_of_lists, 'majorDimension':'COLUMNS'})
# create a request body
body = {"requests": REQUESTS}
# make update
sheet_service.spreadsheets().batchUpdate(spreadsheetId=sheet_id, body=body).execute()
The code above return the following error:
"Invalid JSON payload received. Unknown name "range" at 'requests[1]': Cannot find field.
Invalid JSON payload received. Unknown name "values" at 'requests[1]': Cannot find field.
Invalid JSON payload received. Unknown name "majorDimension" at 'requests[1]': Cannot find field.". Details: "[{'#type': 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'field': 'requests[1]', 'description': 'Invalid JSON payload received. Unknown name "range" at \'requests[1]\': Cannot find field.'}, {'field': 'requests[1]', 'description': 'Invalid JSON payload received. Unknown name "values" at \'requests[1]\': Cannot find field.'}, {'field': 'requests[1]', 'description': 'Invalid JSON payload received. Unknown name "majorDimension" at \'requests[1]\': Cannot find field.'}]}]">
Thanks
I believe your goal as follows.
You want to insert new sheet to the Google Spreadsheet.
You want to add the values to the inserted sheet.
You want to achieve above 2 processes with one API call using the method of batchUpdate in Sheets API.
You want to achieve above using googleapis for python.
Modification points:
In this case, in order to add the values to the inserted sheet, I would like to propose to manually add the sheet ID as the unique value.
I think that your 1st request body can be used. But your 2nd request body cannot be used for the batchUpdate method.
When above points are reflected to your script, it becomes as follows.
Modified script:
spreadsheet_id = '###' # Please set the Spreadsheet ID.
list_of_lists = [['sample value 1', 123, 456], ['sample value 2', 789, 123]] ## Please set your values.
sheet_service = build('sheets', 'v4', credentials=creds)
rows = []
for r in list_of_lists:
col = []
for c in r:
col.append({"userEnteredValue": ({"numberValue": c} if str(c).replace('.', '', 1).isdigit() else {"stringValue": c})})
rows.append({"values": col})
print(rows)
new_sheet_id = 123456
body = {
"requests": [
{
"addSheet": {
"properties": {
"title": "MySheet",
"sheetId": new_sheet_id
}
}
},
{
"updateCells": {
"start": {
"sheetId": new_sheet_id,
"rowIndex": 0,
"columnIndex": 0
},
"rows": rows,
"fields": "userEnteredValue"
}
}
]
}
res = sheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheet_id, body=body).execute()
print(res)
In this sample script, 123456 is used as the sheet ID of the inserted sheet. If this value has already been used, please change it.
In this sample script, the string and number types are used as the additional value to the inserted sheet. If you want to use other types, please modify above script for your actual situation.
References:
Method: spreadsheets.batchUpdate
AddSheetRequest
UpdateCellsRequest

Can't get Tabulator select editor to work correctly

I'm new to the tabulator and am having trouble getting it to display droplist data in the correct format.
I have defined the column details thus:
{
title: "Status",
field: "Status",
width: 150,
headerFilter: "input",
editor: "select",
editorParams: {
listFormatter: populateStatusList
}
},
As you can see, the listFormatter calls function populateStatusList. This function builds an array of strings from an already-populated structure and returns the array.tostring() from the function.
The tabulator droplist does show the strings but horizontally on one long line and not vertically as I'd expect (i.e. it doesn't actually drop).
Can anyone help me?
Kind regards
The listFormatter should only be used to layout list items passed into the editor, the values for each of the items in the list should be passed into the values property
{title:"Gentlemen", field:"names", editor:"select", editorParams:{
listFormatter:function(value, title){ //prefix all titles with the work "Mr"
return "Mr " + title;
},
values:{
"steve":"Steve Boberson",
"bob":"Bob Jimmerson",
"jim":"Jim Stevenson",
}
}}
In the example above the list formatter will create a list of the titles passed into the values property, prepending each with the string "Mr"

Why did this mongoose search match these documents?

I was trying to figure out if one of my users had any data associated with a goal with code "2" (which would have meant a bug) so I searched mongoose for
Entry.find({userid: req.user._id, 'goalSummary.2': {$exists: true}})
The goalSummary property is of type mongoose.Schema.Types.Mixed with keys identical to the goal codes (as strings, if that matters) and objects as values.
I got back 16 results, which each had goalSummarys like this:
goalSummary: {
"1": {
outcomes: 1,
intendedcount: 1,
extrascount: 0,
notdonecount: 0,
enough: "e"
},
"3": {
outcomes: 1,
intendedcount: 1,
extrascount: 0,
notdonecount: 0,
enough: "e"
},
[...]
}
...ie no 2 key. Why could these have matched? Was 2 set to undefined but not deleted? It successfully didn't match hundreds of other entries.
"field.2" only makes sense in Array types of mongoose properties. For Mixed, mongoose doesn't know anything about your document, so it will match everything, as long as there is a value.
On a side note, being burned myself and seeing others repeating it, I can also advice you too not to use keys for naming stuff. Rather do something like { key: 1, value: {outcomes: 1 ... }}.

Resources