def _fix_value_render(self, df, first_data_row, col_names, cols, value_render_option): """Replace values for columns that need a different value render option.""" if not is_indexes(cols): cols = find_col_indexes(cols, col_names) for ix, col in enumerate(self._get_columns(cols, value_render_option)): df.iloc[:, cols[ix] - 1] = rightpad(col[first_data_row:], len(df))
def df_to_sheet( self, df, index=True, headers=True, start=(1, 1), replace=False, sheet=None, raw_column_names=None, raw_columns=None, freeze_index=False, freeze_headers=False, fill_value="", add_filter=False, merge_headers=False, flatten_headers_sep=None, ): """ Save a DataFrame into a worksheet. Parameters ---------- df : DataFrame the DataFrame to save index : bool whether to include the index in worksheet (default True) headers : bool whether to include the headers in the worksheet (default True) start : tuple,str tuple indicating (row, col) or string like 'A1' for top left cell (default (1,1)) replace : bool whether to remove everything in the sheet first (default False) sheet : str,int,Worksheet optional, if you want to open or create a different sheet before saving, see :meth:`open_sheet <gspread_pandas.spread.Spread.open_sheet>` (default None) raw_column_names : list, str (DEPRECATED use raw_collumns instead) optional, list of columns from your dataframe that you want interpreted as RAW input in google sheets. raw_columns : list, str optional, list of columns from your dataframe that you want interpreted as RAW input in google sheets. This can be column names or column numbers. freeze_index : bool whether to freeze the index columns (default False) freeze_headers : bool whether to freeze the header rows (default False) fill_value : str value to fill nulls with (default '') add_filter : bool whether to add a filter to the uploaded sheet (default False) merge_headers : bool whether to merge cells in the header that have the same value (default False) flatten_headers_sep : str if you want to flatten your multi-headers to a single row, you can pass the string that you'd like to use to concatenate the levels, for example, ': ' (default None) Returns ------- None """ self._ensure_sheet(sheet) header = df.columns index_size = df.index.nlevels if index else 0 header_size = df.columns.nlevels if index: df = df.reset_index() df = fillna(df, fill_value) df_list = df.values.tolist() if headers: header_rows = parse_df_col_names(df, index, index_size, flatten_headers_sep) df_list = header_rows + df_list start = get_cell_as_tuple(start) sheet_rows, sheet_cols = self.get_sheet_dims() req_rows = len(df_list) + (start[ROW] - 1) req_cols = len(df_list[0]) + (start[COL] - 1) or 1 end = (req_rows, req_cols) if replace: # this takes care of resizing self.clear_sheet(req_rows, req_cols) else: # make sure sheet is large enough self.sheet.resize(max(sheet_rows, req_rows), max(sheet_cols, req_cols)) if raw_column_names: deprecate( "raw_column_names is deprecated, please use raw_columns instead." ) raw_columns = find_col_indexes(raw_column_names, header, start[COL] + index_size) elif raw_columns: if is_indexes(raw_columns): offset = index_size + start[COL] - 1 raw_columns = [ix + offset for ix in raw_columns] else: raw_columns = find_col_indexes(raw_columns, header, start[COL] + index_size) self.update_cells( start=start, end=end, vals=[str(val) for row in df_list for val in row], raw_columns=raw_columns, ) self.freeze( None if not freeze_headers else header_size + start[ROW] - 1, None if not freeze_index else index_size + start[COL] - 1, ) if add_filter: self.add_filter((header_size + start[ROW] - 2, start[COL] - 1), (req_rows, req_cols)) if merge_headers: self.spread.batch_update({ "requests": create_merge_headers_request(self.sheet.id, header, start, index_size) }) self.refresh_spread_metadata()