Suppose I have two spreadsheets of almost the same structure:
Spreadsheet A: [Sheet1(Charts and data summary)][Sheet2 (Data)][Sheet3(Data)]...
Spreadsheet B: [Sheet1(Empty)][Sheet2 (Data)][Sheet3(Data)]...
A.Sheet1 contains manually created charts and aggregated data from A.Sheet2 and A.Sheet3.
Spreadsheet B has the same worksheet ordering and worksheet names as in Spreadsheet A. The task is to copy Sheet1 from A to B so that all charts and formulas should be mapped to the data from corresponding worksheets of B of the same name.
So I'm using the following code to copy entire Sheet1 from A to B:
def duplicate_worksheet(from_spreadsheet_id,
sheet_id,
to_spreadsheet_id,
credentials,
title=None):
service = discovery.build('sheets', 'v4', credentials=credentials)
copy_sheet_to_another_spreadsheet_request_body = {
'destination_spreadsheet_id': to_spreadsheet_id
}
request = service.spreadsheets().sheets().copyTo(spreadsheetId=from_spreadsheet_id,
sheetId=sheet_id,
body=copy_sheet_to_another_spreadsheet_request_body)
response = request.execute()
if title:
new_sheet_id = response['sheetId']
new_title = title
rename_worksheet(to_spreadsheet_id, new_sheet_id, new_title, credentials)
After copying, B.Sheet1 looks like this:
Here we can see that aggregated tables copied successfully but 2 charts are empty (Instead, No data
message is shown]). The spreadsheet Itself is missing all specified chart data ranges and links, which are supposed to persist after copying from A. So my question is how to "deepcopy" a worksheet and keep all chart data and links? (Of course in case If It's possible by using Google API)
The chart is being copied empty, due to the Method: spreadsheets.sheets.copyTo endpoint only copies one sheet to the other spreadsheet, therefore if one chart is built using data from another sheet, it will lose it.
As a workaround, you could edit the empty chart's properties with the properties of your original chart, so it looks as it were a direct copy of it as you are desiring.
You will need to use the Method: spreadsheets.batchUpdate endpoint. In Python your request will look like this:
body = {
'requests': requests
}
response = service.spreadsheets().batchUpdate(
spreadsheetId=spreadsheet_id,
body=body).execute()