问题
Trying to work with Sheets.Spreadsheets.Get and Sheets.Spreadsheets.Batchupdate. I'm trying to get pull formatting from one spreadsheet and paste that formatting to another. This is simply a proof of concept for further application. I get a JSON payload error with the following code and can't see to figure out how to format it to insert the Array.
function Test() {
//sheets[].data[].rowData[].values[].cellData.effectiveFormat.backgroundColor
var TestArray = Sheets.Spreadsheets.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", {
ranges:"Awesome!A1:C3",
fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
});
var spreadsheetId = "1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg";
var result = Sheets.Spreadsheets.batchUpdate({
requests: [{
updateCells: {
rows: [{
values: [{
userEnteredValue: {
stringValue: 'Test String'
}, userEnteredFormat: {
backgroundColor: TestArray
}
}]
}],//rows
fields: 'userEnteredValue.stringValue,userEnteredFormat.backgroundColor',
start: {
sheetId: 1616717220,
rowIndex: 0,
columnIndex: 0
}
}//update cell
}]//requests
}, spreadsheetId)
} ```
**EDIT:**
Rebuilt function copying both Text and Background colors.
function myFunction() {
var TestArray = Sheets.Spreadsheets.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", {
ranges:"Awesome!A1:C3",
fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
});
var backgroundColors = TestArray["sheets"][0]["data"][0]["rowData"]
.map(row => row["values"]
.map(value => value["effectiveFormat"]["backgroundColor"]));
var TotalText = Sheets.Spreadsheets.Values.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", "Awesome!A1:C3").values;
//Map Text
var textrows = TotalText.map(rowText => {
return {
values: rowText.map(cellText => {
return {
userEnteredValue: {
stringValue: cellText
}
}
})
}
})
//Map Background Colors
var colorrows = backgroundColors.map(rowColors => {
return {
values: rowColors.map(cellColor => {
return {
userEnteredFormat: {
backgroundColor: cellColor
}
}
})
}
})
var spreadsheetId = "1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg";
var result = Sheets.Spreadsheets.batchUpdate({
requests: [{
updateCells: {
rows: textrows,
fields: 'userEnteredValue.stringValue',
start: {
sheetId: 1616717220,
rowIndex: 0,
columnIndex: 0
}
}//update cell
},{
updateCells: {
rows: colorrows,
fields: 'userEnteredFormat.backgroundColor',
start: {
sheetId: 1616717220,
rowIndex: 0,
columnIndex: 0
}
}
}]
}, spreadsheetId)
}
Edit #2:
function myFunctionOneRequest() {
var TestArray = Sheets.Spreadsheets.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", {
ranges:"Awesome!A1:C3",
fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
});
var backgroundColors = TestArray["sheets"][0]["data"][0]["rowData"]
.map(row => row["values"]
.map(value => value["effectiveFormat"]["backgroundColor"]));
var TotalText = Sheets.Spreadsheets.Values.get("1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg", "Awesome!A1:C3").values;
//Map Text
var textrows = TotalText.map((rowText,i) => {
return {
values: rowText.map((cellText,j) => {
return {
userEnteredValue: {
stringValue: cellText
}
}
})
}
})
//Map Background Colors
var colorrows = backgroundColors.map((rowColors,k) => {
return {
values: rowColors.map((cellColor,l) => {
return {
userEnteredFormat: {
backgroundColor: cellColor
}
}
})
}
})
var spreadsheetId = "1eAq-RbtrCSMRPZ0p7XIpG3vd29yL-3SQ3D3JGyiUhKg";
var result = Sheets.Spreadsheets.batchUpdate({
requests: [{
updateCells: {
rows: textrows,
fields: 'userEnteredValue.stringValue',
start: {
sheetId: 1616717220,
rowIndex: 0,
columnIndex: 0
}
}//update cell
}]
}, spreadsheetId)
}
回答1:
Issue:
You are supplying at Spreadsheet resource (TestArray
, returned by spreadsheets.get) where you should provide a color. Hence, you are getting an invalid JSON payload error.
This is because the fields
parameter will filter which nested fields will be populated in the response of your first call, but these nested fields will still be nested on your JSON, and you'll have to access them by specifying the corresponding parent properties.
Solution:
The response to your first call is something like:
{
"sheets": [
{
"data": [
{
"rowData": [
{
"values": [
{
"effectiveFormat": {
"backgroundColor": {
"red": 1,
"green": 1,
"blue": 1
}
}
},
// Other cells in row
]
},
// Other rows in the requested range
]
} // Only one range is specified, so there's only one GridData element
]
},
// Other sheets
]
}
So, for example, if you want to access the backgroundColor
of the first cell of the first row in the requested range, you should do the following:
var backgroundColor = TestArray["sheets"][0]["data"][0]["rowData"][0]
["values"][0]["effectiveFormat"]["backgroundColor"];
Or, alternatively, if you want to retrieve a 2D array of the backgroundColors
of all the cells in the requested range, you could do this:
var backgroundColors = TestArray["sheets"][0]["data"][0]["rowData"]
.map(row => row["values"]
.map(value => value["effectiveFormat"]["backgroundColor"]));
If you want to update several cells, you would need to edit the request body accordingly, adding the additional rows
and values
to the corresponding arrays.
Edit:
For example, if you want the destination cells to have the same background colors as the source, and all of them to have the value Test String
, you could build your request body like this:
var rows = backgroundColors.map(rowColors => {
return {
values: rowColors.map(cellColor => {
return {
userEnteredValue: {
stringValue: 'Test String'
},
userEnteredFormat: {
backgroundColor: cellColor
}
}
})
}
})
var result = Sheets.Spreadsheets.batchUpdate({
requests: [{
updateCells: {
rows: rows,
fields: 'userEnteredValue.stringValue,userEnteredFormat.backgroundColor',
start: {
sheetId: 1616717220,
rowIndex: 0,
columnIndex: 0
}
}//update cell
}]//requests
}, spreadsheetId)
If each cell should have different string values, you should store those in a 2D array, and provide them inside the map
methods, instead of Test String
, specifying the corresponding indexes (provided as an optional parameter in each map
).
Edit 2:
In order to update both values and background colors with the same request, you can just iterate through one of them with map
, and use the corresponding index parameters (they are optional parameters of the map
method, called i
and j
in the sample below) to access the different values of the other one.
For example, if backgroundColors
and strings
the 2D arrays which you want to use to build rows
, you can do this:
var backgroundColors = [["2D array with colors"]];
var strings = [["2D array with strings"]];
var rows = backgroundColors.map((rowColors,i) => {
return {
values: rowColors.map((cellColor,j) => {
return {
userEnteredValue: {
stringValue: strings[i][j]
},
userEnteredFormat: {
backgroundColor: cellColor
}
}
});
}
});
来源:https://stackoverflow.com/questions/64198587/invalid-json-payload-with-sheets-spreadsheets-batchupdate