3
3
import gspread
4
4
import gspread_formatting
5
5
from enum import Enum
6
+ import pandas as pd
6
7
7
8
FONT_SIZE_PTS = 10
8
9
PTS_PIXELS_RATIO = 4 / 3
@@ -35,7 +36,9 @@ class CHART_TYPES(Enum):
35
36
"bold_header" : True ,
36
37
"center_header" : True ,
37
38
"freeze_header" : True ,
38
- "column_widths" : {"justify" : True , "buffer_chars" : DEFAULT_BUFFER_CHARS }
39
+ "column_widths" : {"justify" : True , "buffer_chars" : DEFAULT_BUFFER_CHARS },
40
+ "extra_columns" : 0 ,
41
+ "extra_columns_width" : 50 ,
39
42
}
40
43
41
44
def extract_credentials (authentication_response ):
@@ -169,7 +172,7 @@ def fill_worksheet_with_df(
169
172
df ,
170
173
worksheet_name ,
171
174
overlapBehavior ,
172
- sheet_formatting_options = DEFAULT_SHEET_FORMATTING_OPTIONS ,
175
+ sheet_formatting_options = {} ,
173
176
column_formatting_options = {}
174
177
):
175
178
"""
@@ -199,38 +202,47 @@ def fill_worksheet_with_df(
199
202
title = worksheet_name , rows = df .shape [0 ], cols = df .shape [1 ]
200
203
)
201
204
205
+ sheet_formatting_options_filled = {** DEFAULT_SHEET_FORMATTING_OPTIONS , ** sheet_formatting_options }
206
+
207
+ # Add extra blank columns to the right of the worksheet
208
+ df_to_insert = pd .concat (
209
+ [df ] + [pd .Series (" " , index = df .index , name = "" )] * sheet_formatting_options_filled ["extra_columns" ],
210
+ axis = 1
211
+ )
202
212
# Add data to worksheet
203
- worksheet .update ([df .columns .values .tolist ()] + df .fillna ("NA" ).values .tolist ())
213
+ worksheet .update ([df_to_insert .columns .values .tolist ()] + df_to_insert .fillna ("NA" ).values .tolist ())
204
214
205
215
# Format worksheet
206
216
# Justify Column Widths
207
- if "column_widths" not in sheet_formatting_options or sheet_formatting_options ["column_widths" ]["justify" ]:
217
+ if "column_widths" not in sheet_formatting_options_filled or sheet_formatting_options_filled ["column_widths" ]["justify" ]:
208
218
text_widths = df .astype (str ).columns .map (
209
219
lambda column_name : df [column_name ].astype (str ).str .len ().max ()
210
220
)
211
221
header_widths = df .columns .str .len ()
212
222
buffer_chars = (
213
223
DEFAULT_BUFFER_CHARS
214
- if ("column_widths" not in sheet_formatting_options or "buffer_chars" not in sheet_formatting_options ["column_widths" ])
215
- else sheet_formatting_options ["column_widths" ]["buffer_chars" ]
224
+ if ("column_widths" not in sheet_formatting_options_filled or "buffer_chars" not in sheet_formatting_options_filled ["column_widths" ])
225
+ else sheet_formatting_options_filled ["column_widths" ]["buffer_chars" ]
216
226
)
217
- column_widths = [
227
+ data_column_widths = [
218
228
round ((max (len_tuple ) + buffer_chars ) * FONT_SIZE_PTS * 1 / PTS_PIXELS_RATIO )
219
229
for len_tuple in zip (text_widths , header_widths )
220
230
]
231
+ extra_column_widths = [sheet_formatting_options_filled ["extra_columns_width" ]] * sheet_formatting_options_filled ["extra_columns" ]
232
+ combined_column_widths = data_column_widths + extra_column_widths
221
233
column_positions = [
222
- gspread .utils .rowcol_to_a1 (1 , i + 1 )[0 ] for i , _ in enumerate (column_widths )
234
+ gspread .utils .rowcol_to_a1 (1 , i + 1 )[0 ] for i , _ in enumerate (combined_column_widths )
223
235
]
224
- gspread_formatting .set_column_widths (worksheet , zip (column_positions , column_widths ))
236
+ gspread_formatting .set_column_widths (worksheet , zip (column_positions , combined_column_widths ))
225
237
# Freeze Header
226
- if "freeze_header" not in sheet_formatting_options or sheet_formatting_options ["freeze_header" ]:
238
+ if "freeze_header" not in sheet_formatting_options_filled or sheet_formatting_options_filled ["freeze_header" ]:
227
239
gspread_formatting .set_frozen (worksheet , rows = 1 )
228
240
base_format_options = gspread_formatting .CellFormat ()
229
241
# Bold Header
230
- if "bold_header" not in sheet_formatting_options or sheet_formatting_options ["bold_header" ]:
242
+ if "bold_header" not in sheet_formatting_options_filled or sheet_formatting_options_filled ["bold_header" ]:
231
243
base_format_options += gspread_formatting .CellFormat (textFormat = gspread_formatting .TextFormat (bold = True ))
232
244
# Center Header
233
- if "center_header" not in sheet_formatting_options or sheet_formatting_options ["center_header" ]:
245
+ if "center_header" not in sheet_formatting_options_filled or sheet_formatting_options_filled ["center_header" ]:
234
246
base_format_options += gspread_formatting .CellFormat (horizontalAlignment = "CENTER" )
235
247
# Handle column specific formatting
236
248
for column in column_formatting_options :
@@ -313,7 +325,7 @@ def fill_spreadsheet_with_df_dict(sheet, df_dict, overlapBehavior, sheet_formatt
313
325
for worksheet_name , df in df_dict .items ():
314
326
fill_worksheet_with_df (
315
327
sheet , df , worksheet_name , overlapBehavior ,
316
- sheet_formatting_options = sheet_formatting_options .get (worksheet_name , DEFAULT_SHEET_FORMATTING_OPTIONS ),
328
+ sheet_formatting_options = sheet_formatting_options .get (worksheet_name , {} ),
317
329
column_formatting_options = column_formatting_options .get (worksheet_name , {})
318
330
)
319
331
@@ -338,7 +350,12 @@ def update_sheet_raw(sheets_authentication_response, sheet, *updates):
338
350
"title" : "" ,
339
351
"x_axis_title" : "" ,
340
352
"y_axis_title" : "" ,
341
- "chart_position" : None # Means it will be created in a new sheet
353
+ "invert_x_axis" : False ,
354
+ "chart_position" : None , # None means it will be created in a new sheet
355
+ "chart_position_offset_x" : 0 ,
356
+ "chart_position_offset_y" : 0 ,
357
+ "chart_width" : 600 ,
358
+ "chart_height" : 371 ,
342
359
}
343
360
344
361
@dataclass
@@ -366,11 +383,14 @@ def _cell_to_grid_coordinate(cell, worksheet):
366
383
367
384
def add_chart_to_sheet (sheets_authentication_response , sheet , worksheet , chart_type , domain , series , ** chart_args ):
368
385
complete_chart_args = {** DEFAULT_CHART_ARGS , ** chart_args }
369
- print (worksheet .id )
370
386
if complete_chart_args ["chart_position" ] is not None :
371
387
position_dict = {
372
388
"overlayPosition" : {
373
- "anchorCell" : _cell_to_grid_coordinate (complete_chart_args ["chart_position" ], worksheet )
389
+ "anchorCell" : _cell_to_grid_coordinate (complete_chart_args ["chart_position" ], worksheet ),
390
+ "offsetXPixels" : complete_chart_args ["chart_position_offset_x" ],
391
+ "offsetYPixels" : complete_chart_args ["chart_position_offset_y" ],
392
+ "widthPixels" : complete_chart_args ["chart_width" ],
393
+ "heightPixels" : complete_chart_args ["chart_height" ],
374
394
}
375
395
}
376
396
else :
@@ -385,6 +405,7 @@ def add_chart_to_sheet(sheets_authentication_response, sheet, worksheet, chart_t
385
405
],
386
406
},
387
407
},
408
+ "reversed" : complete_chart_args ["invert_x_axis" ],
388
409
},
389
410
]
390
411
formatted_series = [
@@ -411,8 +432,6 @@ def add_chart_to_sheet(sheets_authentication_response, sheet, worksheet, chart_t
411
432
"title" : complete_chart_args ["y_axis_title" ],
412
433
"position" : "LEFT_AXIS" ,
413
434
})
414
- print (formatted_domains )
415
- print (formatted_series )
416
435
request = {
417
436
"addChart" : {
418
437
"chart" : {
@@ -432,7 +451,6 @@ def add_chart_to_sheet(sheets_authentication_response, sheet, worksheet, chart_t
432
451
},
433
452
},
434
453
}
435
- print (request )
436
454
437
455
response = update_sheet_raw (sheets_authentication_response , sheet , request )
438
456
return response
0 commit comments