diff --git a/README.md b/README.md
index 15c7d86..3f7900b 100644
--- a/README.md
+++ b/README.md
@@ -63,8 +63,11 @@ More info:
const sheet = await doc.addSheet({ headers: ['name', 'email'] });
// append rows
-await sheet.addRow({ name: 'Larry Page', email: 'larry@google.com' });
-await sheet.addRow({ name: 'Sergey Brin', email: 'sergey@google.com' });
+const larryRow = await sheet.addRow({ name: 'Larry Page', email: 'larry@google.com' });
+const moreRows = await sheet.addRows([
+ { name: 'Sergey Brin', email: 'sergey@google.com' },
+ { name: 'Eric Schmidt', email: 'eric@google.com' },
+]);
// read rows
const rows = await sheet.getRows(); // can pass in { limit, offset }
diff --git a/docs/README.md b/docs/README.md
index ac3e4b9..3457113 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -59,8 +59,11 @@ More info:
const sheet = await doc.addSheet({ headers: ['name', 'email'] });
// append rows
-await sheet.addRow({ name: 'Larry Page', email: 'larry@google.com' });
-await sheet.addRow({ name: 'Sergey Brin', email: 'sergey@google.com' });
+const larryRow = await sheet.addRow({ name: 'Larry Page', email: 'larry@google.com' });
+const moreRows = await sheet.addRows([
+ { name: 'Sergey Brin', email: 'sergey@google.com' },
+ { name: 'Eric Schmidt', email: 'eric@google.com' },
+]);
// read rows
const rows = await sheet.getRows(); // can pass in { limit, offset }
diff --git a/docs/classes/google-spreadsheet-worksheet.md b/docs/classes/google-spreadsheet-worksheet.md
index cb4872c..fbb6cc1 100644
--- a/docs/classes/google-spreadsheet-worksheet.md
+++ b/docs/classes/google-spreadsheet-worksheet.md
@@ -77,16 +77,31 @@ Param|Type|Required|Description
- :sparkles: **Side effects** - first row of the sheet is filled, `sheet.headerValues` is populated
-#### `addRow(values)` (async) :id=fn-addRow
+#### `addRow(rowValues)` (async) :id=fn-addRow
> Append a new row to the sheet
Param|Type|Required|Description
---|---|---|---
-`values`|Object|✅|Object of cell values, keys are based on the header row
+`rowValues`
_option 1_|Object|✅|Object of cell values, keys are based on the header row
_ex: `{ col1: 'val1', col2: 'val2', ... }`_
+`rowValues`
_option 2_|Array|✅|Array of cell values in order from first column onwards
_ex: `['val1', 'val2', ...]`_
+
+
- :leftwards_arrow_with_hook: **Returns** - [GoogleSpreadsheetRow](classes/google-spreadsheet-row) (in a promise)
- :sparkles: **Side effects** - row is added to the sheet
+
+#### `addRows(arrayOfRowValues)` (async) :id=fn-addRows
+> Append multiple new rows to the sheet at once
+
+Param|Type|Required|Description
+---|---|---|---
+`arrayOfRowValues`|Array|✅|Array of rows values to append to the sheet
_see [`sheet.addRow()`](#fn-addRow) above for more info_
+
+- :leftwards_arrow_with_hook: **Returns** - [[GoogleSpreadsheetRow](classes/google-spreadsheet-row)] (in a promise)
+- :sparkles: **Side effects** - rows are added to the sheet
+
+
#### `getRows(options)` (async) :id=fn-getRows
> Fetch rows from the sheet
diff --git a/lib/GoogleSpreadsheetWorksheet.js b/lib/GoogleSpreadsheetWorksheet.js
index 71668bd..87aa1ed 100644
--- a/lib/GoogleSpreadsheetWorksheet.js
+++ b/lib/GoogleSpreadsheetWorksheet.js
@@ -322,29 +322,36 @@ class GoogleSpreadsheetWorksheet {
this.headerValues = response.data.updatedData.values[0];
}
- async addRow(values) {
- // values can be an array or object
+ async addRows(rows) {
+ // adds multiple rows in one API interaction using the append endpoint
+ // each row can be an array or object
// an array is just cells
// ex: ['column 1', 'column 2', 'column 3']
-
// an object must use the header row values as keys
// ex: { col1: 'column 1', col2: 'column 2', col3: 'column 3' }
+ if (!_.isArray(rows)) throw new Error('You must pass in an array of row values to append');
+
if (!this.headerValues) await this.loadHeaderRow();
- let valuesArray;
- if (_.isArray(values)) {
- valuesArray = values;
- } else if (_.isObject(values)) {
- valuesArray = [];
- for (let i = 0; i < this.headerValues.length; i++) {
- const propName = this.headerValues[i];
- valuesArray[i] = values[propName];
+ // convert each row into an array of cell values rather than the key/value object
+ const rowsAsArrays = [];
+ _.each(rows, (row) => {
+ let rowAsArray;
+ if (_.isArray(row)) {
+ rowAsArray = row;
+ } else if (_.isObject(row)) {
+ rowAsArray = [];
+ for (let i = 0; i < this.headerValues.length; i++) {
+ const propName = this.headerValues[i];
+ rowAsArray[i] = row[propName];
+ }
+ } else {
+ throw new Error('Each row must be an object or an array');
}
- } else {
- throw new Error('You must pass in an object or an array');
- }
+ rowsAsArrays.push(rowAsArray);
+ });
const response = await this._spreadsheet.axios.request({
method: 'post',
@@ -355,11 +362,9 @@ class GoogleSpreadsheetWorksheet {
includeValuesInResponse: true,
},
data: {
- values: [valuesArray],
+ values: rowsAsArrays,
},
});
- // console.log(response.data);
- // rows.push(new GoogleSpreadsheetRow(this, rowNum++, rawRows[i]));
// extract the new row number from the A1-notation data range in the response
// ex: in "'Sheet8!A2:C2" -- we want the `2`
@@ -367,11 +372,15 @@ class GoogleSpreadsheetWorksheet {
let rowNumber = updatedRange.match(/![A-Z]+([0-9]+):?/)[1];
rowNumber = parseInt(rowNumber);
- return new GoogleSpreadsheetRow(
- this,
- rowNumber,
- response.data.updates.updatedData.values[0],
- );
+ return _.map(response.data.updates.updatedData.values, (rowValues) => {
+ const row = new GoogleSpreadsheetRow(this, rowNumber++, rowValues);
+ return row;
+ });
+ }
+
+ async addRow(rowValues) {
+ const rows = await this.addRows([rowValues]);
+ return rows[0];
}
async getRows(options = {}) {
diff --git a/test/rows.test.js b/test/rows.test.js
index 1af4c41..22ab4f7 100644
--- a/test/rows.test.js
+++ b/test/rows.test.js
@@ -91,6 +91,17 @@ describe('Row-based operations', () => {
expect(row.numbers).toEqual(newRowData.numbers);
expect(row.letters).toEqual(newRowData.letters);
});
+
+ it('can add multiple rows', async () => {
+ const newRows = await sheet.addRows([
+ { numbers: '7', letters: 'H' },
+ { numbers: '8', letters: 'I' },
+ ['9', 'J'],
+ ]);
+ expect(newRows[0].numbers).toEqual('7');
+ expect(newRows[1].numbers).toEqual('8');
+ expect(newRows[2].numbers).toEqual('9');
+ });
});
describe('deleting rows', () => {