-
Star
(222)
You must be signed in to star a gist -
Fork
(63)
You must be signed in to fork a gist
-
-
Save mhawksey/1442370 to your computer and use it in GitHub Desktop.
| function getJSON(aUrl,sheetname) { | |
| //var sheetname = "test"; | |
| //var aUrl = "http://pipes.yahoo.com/pipes/pipe.run?_id=286bbb1d8d30f65b54173b3b752fa4d9&_render=json"; | |
| var response = UrlFetchApp.fetch(aUrl); // get feed | |
| var dataAll = JSON.parse(response.getContentText()); // | |
| var data = dataAll.value.items; | |
| for (i in data){ | |
| data[i].pubDate = new Date(data[i].pubDate); | |
| data[i].start = data[i].pubDate; | |
| } | |
| var doc = SpreadsheetApp.getActiveSpreadsheet(); | |
| var temp = doc.getSheetByName("TMP"); | |
| if (!doc.getSheetByName(sheetname)){ | |
| var sheet = doc.insertSheet(sheetname, {template:temp}); | |
| } else { | |
| var sheet = doc.getSheetByName(sheetname); | |
| sheet.getRange(2, 1, sheet.getLastRow(), sheet.getMaxColumns()).clear({contentsOnly:true}); | |
| } | |
| insertData(sheet,data); | |
| } | |
| function insertData(sheet, data){ | |
| var ss = SpreadsheetApp.getActiveSpreadsheet(); | |
| if (data.length>0){ | |
| ss.toast("Inserting "+data.length+" rows"); | |
| sheet.insertRowsAfter(1, data.length); | |
| setRowsData(sheet, data); | |
| } else { | |
| ss.toast("All done"); | |
| } | |
| } | |
| // Back to the stuff from Google --> | |
| // setRowsData fills in one row of data per object defined in the objects Array. | |
| // For every Column, it checks if data objects define a value for it. | |
| // Arguments: | |
| // - sheet: the Sheet Object where the data will be written | |
| // - objects: an Array of Objects, each of which contains data for a row | |
| // - optHeadersRange: a Range of cells where the column headers are defined. This | |
| // defaults to the entire first row in sheet. | |
| // - optFirstDataRowIndex: index of the first row where data should be written. This | |
| // defaults to the row immediately below the headers. | |
| function setRowsData(sheet, objects, optHeadersRange, optFirstDataRowIndex) { | |
| var headersRange = optHeadersRange || sheet.getRange(1, 1, 1, sheet.getMaxColumns()); | |
| var firstDataRowIndex = optFirstDataRowIndex || headersRange.getRowIndex() + 1; | |
| var headers = normalizeHeaders(headersRange.getValues()[0]); | |
| var data = []; | |
| for (var i = 0; i < objects.length; ++i) { | |
| var values = [] | |
| for (j = 0; j < headers.length; ++j) { | |
| var header = headers[j]; | |
| values.push(header.length > 0 && objects[i][header] ? objects[i][header] : ""); | |
| } | |
| data.push(values); | |
| } | |
| var destinationRange = sheet.getRange(firstDataRowIndex, headersRange.getColumnIndex(), | |
| objects.length, headers.length); | |
| destinationRange.setValues(data); | |
| } | |
| // getRowsData iterates row by row in the input range and returns an array of objects. | |
| // Each object contains all the data for a given row, indexed by its normalized column name. | |
| // Arguments: | |
| // - sheet: the sheet object that contains the data to be processed | |
| // - range: the exact range of cells where the data is stored | |
| // - columnHeadersRowIndex: specifies the row number where the column names are stored. | |
| // This argument is optional and it defaults to the row immediately above range; | |
| // Returns an Array of objects. | |
| function getRowsData(sheet, range, columnHeadersRowIndex) { | |
| columnHeadersRowIndex = columnHeadersRowIndex || range.getRowIndex() - 1; | |
| var numColumns = range.getEndColumn() - range.getColumn() + 1; | |
| var headersRange = sheet.getRange(columnHeadersRowIndex, range.getColumn(), 1, numColumns); | |
| var headers = headersRange.getValues()[0]; | |
| return getObjects(range.getValues(), normalizeHeaders(headers)); | |
| } | |
| // For every row of data in data, generates an object that contains the data. Names of | |
| // object fields are defined in keys. | |
| // Arguments: | |
| // - data: JavaScript 2d array | |
| // - keys: Array of Strings that define the property names for the objects to create | |
| function getObjects(data, keys) { | |
| var objects = []; | |
| for (var i = 0; i < data.length; ++i) { | |
| var object = {}; | |
| var hasData = false; | |
| for (var j = 0; j < data[i].length; ++j) { | |
| var cellData = data[i][j]; | |
| if (isCellEmpty(cellData)) { | |
| continue; | |
| } | |
| object[keys[j]] = cellData; | |
| hasData = true; | |
| } | |
| if (hasData) { | |
| objects.push(object); | |
| } | |
| } | |
| return objects; | |
| } | |
| // Returns an Array of normalized Strings. | |
| // Arguments: | |
| // - headers: Array of Strings to normalize | |
| function normalizeHeaders(headers) { | |
| var keys = []; | |
| for (var i = 0; i < headers.length; ++i) { | |
| var key = normalizeHeader(headers[i]); | |
| if (key.length > 0) { | |
| keys.push(key); | |
| } | |
| } | |
| return keys; | |
| } | |
| // Normalizes a string, by removing all alphanumeric characters and using mixed case | |
| // to separate words. The output will always start with a lower case letter. | |
| // This function is designed to produce JavaScript object property names. | |
| // Arguments: | |
| // - header: string to normalize | |
| // Examples: | |
| // "First Name" -> "firstName" | |
| // "Market Cap (millions) -> "marketCapMillions | |
| // "1 number at the beginning is ignored" -> "numberAtTheBeginningIsIgnored" | |
| function normalizeHeader(header) { | |
| var key = ""; | |
| var upperCase = false; | |
| for (var i = 0; i < header.length; ++i) { | |
| var letter = header[i]; | |
| if (letter == " " && key.length > 0) { | |
| upperCase = true; | |
| continue; | |
| } | |
| //if (!isAlnum(letter)) { | |
| // continue; | |
| //} | |
| if (key.length == 0 && isDigit(letter)) { | |
| continue; // first character must be a letter | |
| } | |
| if (upperCase) { | |
| upperCase = false; | |
| key += letter.toUpperCase(); | |
| } else { | |
| key += letter.toLowerCase(); | |
| } | |
| } | |
| return key; | |
| } | |
| // Returns true if the cell where cellData was read from is empty. | |
| // Arguments: | |
| // - cellData: string | |
| function isCellEmpty(cellData) { | |
| return typeof(cellData) == "string" && cellData == ""; | |
| } | |
| // Returns true if the character char is alphabetical, false otherwise. | |
| function isAlnum(char) { | |
| return char >= 'A' && char <= 'Z' || | |
| char >= 'a' && char <= 'z' || | |
| isDigit(char); | |
| } | |
| // Returns true if the character char is a digit, false otherwise. | |
| function isDigit(char) { | |
| return char >= '0' && char <= '9'; | |
| } | |
| // http://jsfromhell.com/array/chunk | |
| function chunk(a, s){ | |
| for(var x, i = 0, c = -1, l = a.length, n = []; i < l; i++) | |
| (x = i % s) ? n[c][x] = a[i] : n[++c] = [a[i]]; | |
| return n; | |
| } |
Just like one of the above comments, also getting the error: TypeError: Cannot read property "items" from undefined.
Due to this line: var data = dataAll.value.items
Manually adding headers to my sheet did not solve the issue.
Very cool. I can run the script from the menu, but I get this error when I run from cell contents:
error: You do not have permission to call insertRowsAfter (line 27, file "getJSON")I researched this error here https://developers.google.com/apps-script/execution_custom_functions#permissions, and there does not appear to be a solution - anybody know of one?
hi - the script needs a bump to trigger authorisation to write to the sheet. In the Tools > Script Editor try to Run > getJSON This should trigger the Google internal authentication processes. Once it is done the custom formula should then work.
This gist was a bit of a hack job used here http://mashe.hawksey.info/2011/12/oer-visualisation-project-processing-a-resource-feed-to-find-frequency-using-google-spreadsheets-day-3-ukoer-ooher/ so could do with a tidy up
Awsome!
I got an error running this, found this working alternative however https://sheet2api.com/google-sheet-to-json-api/
@mhawksey, how do i parse a JSON like this? Your code doesn't work with this JSON. Can you help urgently?