Formatting issues with Python amd GSpread

Question:

I have this panda Data Frame (DF1).

DF1= DF1.groupby(['Name', 'Type', 'Metric'])
DF1= DF1.first()

If I output to df1.to_excel("output.xlsx"). The format is correct see bellow :

screenshot 1

But when I upload to my google sheets using python and GSpread

from gspread_formatting import *
worksheet5.clear()

set_with_dataframe(worksheet=worksheet1, dataframe=DF1, row=1, include_index=True,
include_column_header=True, resize=True)

That’s the output

screenshot 2

How can I keep the same format in my google sheets using gspread_formatting like in screenshot 1?

Asked By: Simon GIS

||

Answers:

Issue and workaround:

In the current stage, it seems that the data frame including the merged cells cannot be directly put into the Spreadsheet with gspread. So, in this answer, I would like to propose a workaround. The flow of this workaround is as follows.

  1. Prepare a data frame including the merged cells.
  2. Convert the data frame to an HTML table.
  3. Put the HTML table with the batchUpdate method of Sheets API.

By this flow, the values can be put into the Spreadsheet with the merged cells. When this is reflected in a sample script, how about the following sample script?

Sample script:

# This is from your script.
DF1 = DF1.groupby(["Name", "Type", "Metric"])
DF1 = DF1.first()

# I added the below script.
spreadsheetId = "###" # Please set your spreadsheet ID.
sheetName = "Sheet1" # Please set your sheet name you want to put the values.
spreadsheet = client.open_by_key(spreadsheetId)
sheet = spreadsheet.worksheet(sheetName)
body = {
    "requests": [
        {
            "pasteData": {
                "coordinate": {"sheetId": sheet.id},
                "data": DF1.to_html(),
                "html": True,
                "type": "PASTE_NORMAL",
            }
        }
    ]
}
spreadsheet.batch_update(body)
  • When this script is run with your sample value including the merged cells, the values are put to the Spreadsheet by reflecting the merged cells.

  • If you want to clear the cell format, please modify body as follows.

    body = {
        "requests": [
            {
                "pasteData": {
                    "coordinate": {"sheetId": sheet.id},
                    "data": DF1.to_html(),
                    "html": True,
                    "type": "PASTE_NORMAL",
                }
            },
            {
                "repeatCell": {
                    "range": {"sheetId": sheet.id},
                    "cell": {},
                    "fields": "userEnteredFormat",
                }
            },
        ]
    }
    

References:

Answered By: Tanaike