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', () => {