How to delete rows from google spreadsheet
I am working on google spreadsheet with node.js, I'm able to read, write, update spread sheet, but need a code for deleting particular row.
sheets.spreadsheets.values.update({
auth: auth,
spreadsheetId: spreadsheetId,
range: sWorkSheet + '!A2:B', //Change Sheet1 if your worksheet's name is something else
valueInputOption: "USER_ENTERED",
resource: {
values: aSpreadSheetData
}
}, (err, response) => {
When it deletes 1st row, a following script can be used. The script deletes completely a row. I used batchUpdate.
In this case, a1Notation cannot be used. GridRange has to be used for this situation. If you want to delete several rows, you can do it by setting the GridRange.
Script :
sheets.spreadsheets.batchUpdate({
auth: auth,
spreadsheetId: spreadsheetId,
resource: {
"requests":
[
{
"deleteRange":
{
"range":
{
"sheetId": sheetId, // gid
"startRowIndex": 0,
"endRowIndex": 1
},
"shiftDimension": "ROWS"
}
}
]
}
}, (err, response) => {
If I misunderstand your question, I'm sorry.
Related
I'm using the Google Sheets API (v4) to create/update spreadsheets programmatically and have run into the following issue:
As per the documentation (https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells#CellFormat), I'm setting the number format to CURRENCY; this will correctly display the number as a numeric value with a ¥ sign at the front (Japanese locale). However, it does not seem to actually select the "Currency" option on the formats dropdown, and more importantly, does NOT reflect the specified format when downloading the spreadsheet (e.g. as an .xlsx file).
This is different from selecting the 'Currency' option manually (via the UI), in which case values are correctly displayed once downloaded.
Here's the relevant section of code:
import { google, sheets_v4 } from 'googleapis';
const sheetsApi = google.sheets({
version: 'v4',
auth: await this.getAuthClient(),
});
await sheetsApi.spreadsheets
.batchUpdate({
spreadsheetId: resource,
requestBody: {
requests: [
{
updateSpreadsheetProperties: {
fields: 'locale',
properties: {
locale: 'ja',
},
},
},
...,
{
repeatCell: {
fields: 'userEnteredFormat.numberFormat',
cell: {
userEnteredFormat: {
numberFormat: { type: 'CURRENCY' },
},
},
},
},
],
},
})
.catch((error) => {
console.log(error);
});
I've also tried settings the pattern (tried few different ones), but haven't been able to actually set the cell format, despite the value being displayed as such.
Probably a simple mistake, but I've been stuck on this for a while.. any help would be greatly appreciated!
In that case, I thought that the property of pattern might be required to be set. So in this case, how about modifying your request of repeatCell as follows?
Modified request:
{
"repeatCell": {
"range": {,,,}, // Please set range.
"cell": {
"userEnteredFormat": {
"numberFormat": {
"type": "CURRENCY",
"pattern": "[$¥-411]#,##0.00" // <--- Added
}
}
},
"fields": "userEnteredFormat.numberFormat" // or "fields": "userEnteredFormat"
}
}
Note:
In my environment, when above modified request is used for the batchUpdate method, I could confirm that "Currency" was checked.
References:
RepeatCellRequest- NumberFormat
I'm using the guide from https://docs.amazonaws.cn/en_us/amazondynamodb/latest/developerguide/GettingStarted.NodeJs.02.html to learn how to load data from a json into a dynamoDB table. I have done step 2, however, when I run my code, only some movie files are successfully put into the table and some are not. For a movie that cannot be added, I receive this error:
Unable to add movie Meet Dave . Error JSON: {
"message": "Requested resource not found",
"code": "ResourceNotFoundException",
"time": "2020-11-30T17:38:59.402Z",
"requestId": "2D23NEFAB33E62C6PEFUFGGNM7VV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 28.791430704572328
}
Every time I delete the db and try re-run my code, different movies are successfully added and unsuccessfully added. My code is identical to the step 2 of the guide on the link above.
var allMovies = JSON.parse(fs.readFileSync("movie_data.json", "utf8"));
allMovies.forEach(function (movie) {
var movie_params = {
TableName: "Movies",
Item: {
year: movie.year,
title: movie.title,
info: movie.info,
},
};
docClient.put(movie_params, function (err, data) {
if (err) {
console.error(
"Unable to add movie",
movie.title,
". Error JSON:",
JSON.stringify(err, null, 2)
);
} else {
console.log("PutItem succeeded:", movie.title);
}
});
});
The movie data is a json file containing a list movies with attributes: title, year and info. Does anyone have any idea why this is not working correctly i.e. not putting all of the data successfully into the db table?.
I want to create a new Google Spreadsheet using googleapis package.
Thanks to Daniel Apt's answer, I am able to create the blank file of it. But I want to give the file values.
I tried this way
const createOption = {
resource: {
properties: {
title: 'Ini judul spreadsetnya'
},
values: ['a']
}
}
But it said that Invalid JSON payload received. Unknown name "values" at 'spreadsheet': Cannot find field.. What field should I add to insert the values? And how do I create the spreadsheet in specific folder? Thank you.
What you are trying to accomplish:
You want to create a new spreadsheet with specific values.
You want this spreadsheet to be created on a specific folder on Google Drive.
Solution:
The first step to accomplish this is to understand why you can't use the values property in your request.
Looking into the documentation you can see that the request is supposed to be of an instance Spreadsheet, and this type does not contain values.
You can also see that there is no way to specify where the spreadsheet will be created, since the Spreadsheet resource does not contain any reference to it's parent folder.
If we break it down, you actually want to do three things:
Create a new spreadsheet
Move it to a specific folder
Fill it with values
Note: You can do step 1 and 2 with a single API call
Create a new spreadsheet:
Change your request body to be like the following:
const createOption = {
resource: {
properties: {
title: 'Ini judul spreadsetnya'
}
}
};
Move the spreadsheet to another folder
You will need to use the Drive API to move a file.
You do this by updating the file to have another parent. In this case, you will use the file.update call with the addParents option where you can add a comma-separated list of parentIds.
These parentIds are the Ids of the folder your file should belong to. (Yes, you can have it in multiple places).
You can extract these via API or thru the interface:
Here is how your request should look like:
const driveMoveOption = {
fileId: "", //You will insert this later
addParents: "<YOUR PARENT ID HERE>",
removeParents: "root" //To remove it from the "MyDrive" section
}
And here is a sample of how to use it:
sheets.spreadsheets.create(createOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the `Spreadsheet` resource we want, with it's fileId
driveMoveOption.fileId = response.spreadsheetId; //Set the spreadsheet Id to
drive.files.update(driveMoveOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the structure of a Files structure: https://developers.google.com/drive/api/v3/reference/files#resource
});
});
Creating a spreadsheet on a specific folder
If you use the Drive.files.create API instead you can use this request:
{
"mimeType": "application/vnd.google-apps.spreadsheet",
"name": "Test",
"parents": [
"<YOUR PARENT ID HERE>"
]
}
and call it with
const driveCreateAndMoveOption = {
"mimeType": "application/vnd.google-apps.spreadsheet",
"name": "Test",
"parents": [
"<YOUR PARENT ID HERE>"
]
};
drive.files.update(driveCreateAndMoveOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the structure of a Files structure. Use this to get the file ID for the spreadsheet call.
});
Insert your custom values
The request to insert values on your spreadsheet should look something like this:
const appendOption = {
"spreadsheetId": "", //You will insert this later
"range": "A:A",
"valueInputOption": "USER_ENTERED",
"resource": {
"values": [
[
"a"
]
]
}
}
To use the correct SpreadsheetId you will need to run this code after you create it, and use that number.
This can be done like this:
sheets.spreadsheets.create(createOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the `Spreadsheet` resource we want, with it's fileId
appendOption.spreadsheetId = response.spreadsheetId; //Set the spreadsheet Id to insert the values on.
sheets.spreadsheets.values.append(appendOption, function (err, response) {
if (err) {
console.error(err);
return;
}
//response contains the structure detailed on: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append#response-body
});
});
So as jonrsharpe's comment, finally I tried to create the blank spreadsheet and update it (there are two command call).
I am trying to update the background color of cells using google sheets v4 api but keep running in circles. I am able to update the cells value on each iteration but when I try changing the background color,
"cell": {
"userEnteredFormat": {
"backgroundColor": {
"red": 1.0,
"green": 0.4,
"blue": 0.4
}
}
},
in the below code I keep getting the error - GaxiosError: Invalid JSON payload received. Unknown name "cell" at 'data[0]': Cannot find field.
function updateClientFeedbackCells(auth) {
var sheets = google.sheets({ version: 'v4' });
authorize(function () {
var request = {
spreadsheetId: process.env['GOOGLE_SHEET_ID_' + envString], //
valueInputOption: 'RAW',
resource: {
"data": [
{
"range": "N" + ucfSelectedRowIndex,
"majorDimension": "COLUMNS",
"cell": {
"userEnteredFormat": {
"backgroundColor": {
"red": 1.0,
"green": 0.4,
"blue": 0.4
}
}
},
"values": [
[
true
],
]
},
],
},
auth,
};
sheets.spreadsheets.values.batchUpdate(request, function (err, response) {
if (err) {
console.error(err);
return;
}
else {
console.info(response);
console.log("Client Feedback Sent Col Values updated");
};
});
});
function authorize(callback) {
// 'https://www.googleapis.com/auth/drive'
// 'https://www.googleapis.com/auth/drive.file'
// 'https://www.googleapis.com/auth/spreadsheets'
var auth = "https://www.googleapis.com/auth/drive";
if (auth == null) {
console.log('authentication failed');
return;
}
callback(auth);
}
}
I've been going through the following documentation but cant seem to figure out what I'm doing incorrectly as there is so much different info. Please, is my problem with my scope or with the api type or in my syntax?
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/cells
https://developers.google.com/sheets/api/samples/formatting
https://developers.google.com/sheets/api/guides/batchupdate#example
https://developers.google.com/sheets/api/guides/conditional-format
You want to update the value and the background of cell by one API call with the batchUpdate method.
You want to update the cell of the column "N". And the row number is given by ucfSelectedRowIndex.
You want to achieve this using googleapis of Node.js.
You have already been able to get and put values for Spreadsheet with Sheets API.
If my understanding is correct, how about this answer?
Modification points:
In order to update the value and the background of cell by one API call with the batchUpdate method, please use the method of spreadsheets.batchUpdate of Sheets API. This is different from the method of spreadsheets.values.batchUpdate.
When the method of spreadsheets.batchUpdate is used, please use the gridrange as the range instead of a1Notation.
Modified script:
In this modified script, I modified the script for the API call. Before you use this script, please set the Spreadsheet ID and sheet ID. And also please set the value of ucfSelectedRowIndex.
const sheets = google.sheets({ version: "v4" });
const spreadsheetId = "###";
const sheetId = "###";
const ucfSelectedRowIndex = 1; // Please set more than 0.
const request = {
requests: [
{
updateCells: {
range: {
sheetId: sheetId,
startRowIndex: ucfSelectedRowIndex - 1,
endRowIndex: ucfSelectedRowIndex,
startColumnIndex: 13, // Column "N"
endColumnIndex: 14 // Column "N"
},
rows: [
{
values: [
{
userEnteredFormat: {
backgroundColor: {
red: 1,
green: 0.4,
blue: 0.4
}
},
userEnteredValue: {
boolValue: true
}
}
]
}
],
fields: "userEnteredFormat,userEnteredValue"
}
}
]
};
sheets.spreadsheets.batchUpdate(
{ spreadsheetId: spreadsheetId, requestBody: request, auth },
function(err, response) {
if (err) {
console.error(err);
return;
} else {
console.info(response);
console.log("Client Feedback Sent Col Values updated");
}
}
);
When you run the script, the value and background of the cell "N1" are modified.
References:
Method: spreadsheets.batchUpdate
UpdateCellsRequest
GridRange
Method: spreadsheets.values.batchUpdate
If I misunderstood your question and this was not the result you want, I apologize.
I am facing an issue with mongodb and mongoose with pagination.
I am trying to query over a set of Tutors and get those who are matching the query in a paginated and sorted (by updatedDate) result.
But the fact is I get multiple same documents over different pages ...
I would like it to return a set of unique documents.
Here is part of my function (the rest is just to build the query from the request body):
exports.search = (req, res) => {
var options = { page: page, limit: perPage, sortBy: { updatedDate: -1 }}
const aggregate = Tutor.aggregate([
{
"$geoNear":
{
"near":
{
"type": "Point",
"coordinates": [lon1, lat1]
},
"distanceField": "distance",
"spherical": true,
"maxDistance": radius
}
},
{
$match: match
}
]);
Tutor
.aggregatePaginate(aggregate, options, function (err, result, pageCount, count) {
if (err) {
return res.status(400).send(err);
}
else {
var opts = [
{ path: 'levels', select: 'name' },
{ path: 'subjects', select: 'name' },
{ path: 'assos', select: 'name' }
];
Tutor
.populate(result, opts)
.then(result2 => {
return res.send({
page: page,
perPage: perPage,
pageCount: pageCount,
documentCount: count,
tutors: result2
});
})
.catch(err => {
return res.status(400).send(err);
});
}
})
};
Now, imagine I am querying page 1 with a limit per page of 8. I 've got back my 8 documents correctly, all different. But when I am querying page 2, with the same limit per page, half of the documents were already returned in page 1 !
Would you know why is that so ? Thank you !
EDIT
I figured it was the sortBy that makes it happen. If i remove it, everything works correctly. I need it though ...
After doing alot of research. I found this solution. Hope it will solve your issue.
Jobs.aggregatePaginate(aggregateQuery, { page: 1, limit: 10, sort: { 'createdAt': 'desc' } }, function (){});