Advertisement
retnet

inportJSON_v1

Apr 25th, 2022
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.98 KB | None | 0 0
  1. function jsontocell(url,angkapage) {
  2. var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getName();
  3. return UrlFetchApp.fetch(url+angkapage).getContentText();
  4. }
  5. function jsontocell2(url,nCatTahun,nPage,) {
  6. return UrlFetchApp.fetch(url+nCatTahun+nPage).getContentText();
  7. }
  8.  
  9. /**
  10. * Retrieves all the rows in the active spreadsheet that contain data and logs the
  11. * values for each row.
  12. * For more information on using the Spreadsheet API, see
  13. * https://developers.google.com/apps-script/service_spreadsheet
  14. */
  15. function readRows() {
  16. var sheet = SpreadsheetApp.getActiveSheet();
  17. var rows = sheet.getDataRange();
  18. var numRows = rows.getNumRows();
  19. var values = rows.getValues();
  20.  
  21. for (var i = 0; i <= numRows - 1; i++) {
  22. var row = values[i];
  23. // Logger.log(row);
  24. }
  25. };
  26.  
  27. /**
  28. * Adds a custom menu to the active spreadsheet, containing a single menu item
  29. * for invoking the readRows() function specified above.
  30. * The onOpen() function, when defined, is automatically invoked whenever the
  31. * spreadsheet is opened.
  32. * For more information on using the Spreadsheet API, see
  33. * https://developers.google.com/apps-script/service_spreadsheet
  34. */
  35. // function onOpen() {
  36. // var sheet = SpreadsheetApp.getActiveSpreadsheet();
  37. // var entries = [{
  38. // name : "Read Data",
  39. // functionName : "readRows"
  40. // }];
  41. // sheet.addMenu("Script Center Menu", entries);
  42. // };
  43.  
  44. /*====================================================================================================================================*
  45. ImportJSON by Trevor Lohrbeer (@FastFedora)
  46. ====================================================================================================================================
  47. Version: 1.1
  48. Project Page: http://blog.fastfedora.com/projects/import-json
  49. Copyright: (c) 2012 by Trevor Lohrbeer
  50. License: GNU General Public License, version 3 (GPL-3.0)
  51. http://www.opensource.org/licenses/gpl-3.0.html
  52. ------------------------------------------------------------------------------------------------------------------------------------
  53. A library for importing JSON feeds into Google spreadsheets. Functions include:
  54.  
  55. ImportJSON For use by end users to import a JSON feed from a URL
  56. ImportJSONAdvanced For use by script developers to easily extend the functionality of this library
  57.  
  58. Future enhancements may include:
  59.  
  60. - Support for a real XPath like syntax similar to ImportXML for the query parameter
  61. - Support for OAuth authenticated APIs
  62.  
  63. Or feel free to write these and add on to the library yourself!
  64. ------------------------------------------------------------------------------------------------------------------------------------
  65. Changelog:
  66.  
  67. 1.1 Added support for the noHeaders option
  68. 1.0 Initial release
  69. *====================================================================================================================================*/
  70. /**
  71. * Imports a JSON feed and returns the results to be inserted into a Google Spreadsheet. The JSON feed is flattened to create
  72. * a two-dimensional array. The first row contains the headers, with each column header indicating the path to that data in
  73. * the JSON feed. The remaining rows contain the data.
  74. *
  75. * By default, data gets transformed so it looks more like a normal data import. Specifically:
  76. *
  77. * - Data from parent JSON elements gets inherited to their child elements, so rows representing child elements contain the values
  78. * of the rows representing their parent elements.
  79. * - Values longer than 256 characters get truncated.
  80. * - Headers have slashes converted to spaces, common prefixes removed and the resulting text converted to title case.
  81. *
  82. * To change this behavior, pass in one of these values in the options parameter:
  83. *
  84. * noInherit: Don't inherit values from parent elements
  85. * noTruncate: Don't truncate values
  86. * rawHeaders: Don't prettify headers
  87. * noHeaders: Don't include headers, only the data
  88. * debugLocation: Prepend each value with the row & column it belongs in
  89. *
  90. * For example:
  91. *
  92. * =ImportJSON("http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&alt=json", "/feed/entry/title,/feed/entry/content",
  93. * "noInherit,noTruncate,rawHeaders")
  94. *
  95. * @param {url} the URL to a public JSON feed
  96. * @param {query} a comma-separated lists of paths to import. Any path starting with one of these paths gets imported.
  97. * @param {options} a comma-separated list of options that alter processing of the data
  98. *
  99. * @return a two-dimensional array containing the data, with the first row containing headers
  100. * @customfunction
  101. **/
  102. function ImportJSON(url, query, options) {
  103. return ImportJSONAdvanced(url, query, options, includeXPath_, defaultTransform_);
  104. }
  105.  
  106. /**
  107. * An advanced version of ImportJSON designed to be easily extended by a script. This version cannot be called from within a
  108. * spreadsheet.
  109. *
  110. * Imports a JSON feed and returns the results to be inserted into a Google Spreadsheet. The JSON feed is flattened to create
  111. * a two-dimensional array. The first row contains the headers, with each column header indicating the path to that data in
  112. * the JSON feed. The remaining rows contain the data.
  113. *
  114. * Use the include and transformation functions to determine what to include in the import and how to transform the data after it is
  115. * imported.
  116. *
  117. * For example:
  118. *
  119. * =ImportJSON("http://gdata.youtube.com/feeds/api/standardfeeds/most_popular?v=2&alt=json",
  120. * "/feed/entry",
  121. * function (query, path) { return path.indexOf(query) == 0; },
  122. * function (data, row, column) { data[row][column] = data[row][column].toString().substr(0, 100); } )
  123. *
  124. * In this example, the import function checks to see if the path to the data being imported starts with the query. The transform
  125. * function takes the data and truncates it. For more robust versions of these functions, see the internal code of this library.
  126. *
  127. * @param {url} the URL to a public JSON feed
  128. * @param {query} the query passed to the include function
  129. * @param {options} a comma-separated list of options that may alter processing of the data
  130. * @param {includeFunc} a function with the signature func(query, path, options) that returns true if the data element at the given path
  131. * should be included or false otherwise.
  132. * @param {transformFunc} a function with the signature func(data, row, column, options) where data is a 2-dimensional array of the data
  133. * and row & column are the current row and column being processed. Any return value is ignored. Note that row 0
  134. * contains the headers for the data, so test for row==0 to process headers only.
  135. *
  136. * @return a two-dimensional array containing the data, with the first row containing headers
  137. **/
  138. function ImportJSONAdvanced(url, query, options, includeFunc, transformFunc) {
  139. var jsondata = UrlFetchApp.fetch(url);
  140. var object = JSON.parse(jsondata.getContentText());
  141.  
  142. return parseJSONObject_(object, query, options, includeFunc, transformFunc);
  143. }
  144.  
  145. /**
  146. * Encodes the given value to use within a URL.
  147. *
  148. * @param {value} the value to be encoded
  149. *
  150. * @return the value encoded using URL percent-encoding
  151. */
  152. function URLEncode(value) {
  153. return encodeURIComponent(value.toString());
  154. }
  155.  
  156. /**
  157. * Parses a JSON object and returns a two-dimensional array containing the data of that object.
  158. */
  159. function parseJSONObject_(object, query, options, includeFunc, transformFunc) {
  160. var headers = new Array();
  161. var data = new Array();
  162.  
  163. if (query && !Array.isArray(query) && query.toString().indexOf(",") != -1) {
  164. query = query.toString().split(",");
  165. }
  166.  
  167. if (options) {
  168. options = options.toString().split(",");
  169. }
  170.  
  171. parseData_(headers, data, "", 1, object, query, options, includeFunc);
  172. parseHeaders_(headers, data);
  173. transformData_(data, options, transformFunc);
  174.  
  175. return hasOption_(options, "noHeaders") ? (data.length > 1 ? data.slice(1) : new Array()) : data;
  176. }
  177.  
  178. /**
  179. * Parses the data contained within the given value and inserts it into the data two-dimensional array starting at the rowIndex.
  180. * If the data is to be inserted into a new column, a new header is added to the headers array. The value can be an object,
  181. * array or scalar value.
  182. *
  183. * If the value is an object, it's properties are iterated through and passed back into this function with the name of each
  184. * property extending the path. For instance, if the object contains the property "entry" and the path passed in was "/feed",
  185. * this function is called with the value of the entry property and the path "/feed/entry".
  186. *
  187. * If the value is an array containing other arrays or objects, each element in the array is passed into this function with
  188. * the rowIndex incremeneted for each element.
  189. *
  190. * If the value is an array containing only scalar values, those values are joined together and inserted into the data array as
  191. * a single value.
  192. *
  193. * If the value is a scalar, the value is inserted directly into the data array.
  194. */
  195. function parseData_(headers, data, path, rowIndex, value, query, options, includeFunc) {
  196. var dataInserted = false;
  197.  
  198. if (isObject_(value)) {
  199. for (key in value) {
  200. if (parseData_(headers, data, path + "/" + key, rowIndex, value[key], query, options, includeFunc)) {
  201. dataInserted = true;
  202. }
  203. }
  204. } else if (Array.isArray(value) && isObjectArray_(value)) {
  205. for (var i = 0; i < value.length; i++) {
  206. if (parseData_(headers, data, path, rowIndex, value[i], query, options, includeFunc)) {
  207. dataInserted = true;
  208. rowIndex++;
  209. }
  210. }
  211. } else if (!includeFunc || includeFunc(query, path, options)) {
  212. // Handle arrays containing only scalar values
  213. if (Array.isArray(value)) {
  214. value = value.join();
  215. }
  216.  
  217. // Insert new row if one doesn't already exist
  218. if (!data[rowIndex]) {
  219. data[rowIndex] = new Array();
  220. }
  221.  
  222. // Add a new header if one doesn't exist
  223. if (!headers[path] && headers[path] != 0) {
  224. headers[path] = Object.keys(headers).length;
  225. }
  226.  
  227. // Insert the data
  228. data[rowIndex][headers[path]] = value;
  229. dataInserted = true;
  230. }
  231.  
  232. return dataInserted;
  233. }
  234.  
  235. /**
  236. * Parses the headers array and inserts it into the first row of the data array.
  237. */
  238. function parseHeaders_(headers, data) {
  239. data[0] = new Array();
  240.  
  241. for (key in headers) {
  242. data[0][headers[key]] = key;
  243. }
  244. }
  245.  
  246. /**
  247. * Applies the transform function for each element in the data array, going through each column of each row.
  248. */
  249. function transformData_(data, options, transformFunc) {
  250. for (var i = 0; i < data.length; i++) {
  251. for (var j = 0; j < data[i].length; j++) {
  252. transformFunc(data, i, j, options);
  253. }
  254. }
  255. }
  256.  
  257. /**
  258. * Returns true if the given test value is an object; false otherwise.
  259. */
  260. function isObject_(test) {
  261. return Object.prototype.toString.call(test) === '[object Object]';
  262. }
  263.  
  264. /**
  265. * Returns true if the given test value is an array containing at least one object; false otherwise.
  266. */
  267. function isObjectArray_(test) {
  268. for (var i = 0; i < test.length; i++) {
  269. if (isObject_(test[i])) {
  270. return true;
  271. }
  272. }
  273.  
  274. return false;
  275. }
  276.  
  277. /**
  278. * Returns true if the given query applies to the given path.
  279. */
  280. function includeXPath_(query, path, options) {
  281. if (!query) {
  282. return true;
  283. } else if (Array.isArray(query)) {
  284. for (var i = 0; i < query.length; i++) {
  285. if (applyXPathRule_(query[i], path, options)) {
  286. return true;
  287. }
  288. }
  289. } else {
  290. return applyXPathRule_(query, path, options);
  291. }
  292.  
  293. return false;
  294. };
  295.  
  296. /**
  297. * Returns true if the rule applies to the given path.
  298. */
  299. function applyXPathRule_(rule, path, options) {
  300. return path.indexOf(rule) == 0;
  301. }
  302.  
  303. /**
  304. * By default, this function transforms the value at the given row & column so it looks more like a normal data import. Specifically:
  305. *
  306. * - Data from parent JSON elements gets inherited to their child elements, so rows representing child elements contain the values
  307. * of the rows representing their parent elements.
  308. * - Values longer than 256 characters get truncated.
  309. * - Values in row 0 (headers) have slashes converted to spaces, common prefixes removed and the resulting text converted to title
  310. * case.
  311. *
  312. * To change this behavior, pass in one of these values in the options parameter:
  313. *
  314. * noInherit: Don't inherit values from parent elements
  315. * noTruncate: Don't truncate values
  316. * rawHeaders: Don't prettify headers
  317. * debugLocation: Prepend each value with the row & column it belongs in
  318. */
  319. function defaultTransform_(data, row, column, options) {
  320. if (!data[row][column]) {
  321. if (row < 2 || hasOption_(options, "noInherit")) {
  322. data[row][column] = "";
  323. } else {
  324. data[row][column] = data[row-1][column];
  325. }
  326. }
  327.  
  328. if (!hasOption_(options, "rawHeaders") && row == 0) {
  329. if (column == 0 && data[row].length > 1) {
  330. removeCommonPrefixes_(data, row);
  331. }
  332.  
  333. data[row][column] = toTitleCase_(data[row][column].toString().replace(/[\/\_]/g, "_"));
  334. }
  335.  
  336. if (!hasOption_(options, "noTruncate") && data[row][column]) {
  337. data[row][column] = data[row][column].toString().substr(0, 256);
  338. }
  339.  
  340. if (hasOption_(options, "debugLocation")) {
  341. data[row][column] = "[" + row + "," + column + "]" + data[row][column];
  342. }
  343. }
  344.  
  345. /**
  346. * If all the values in the given row share the same prefix, remove that prefix.
  347. */
  348. function removeCommonPrefixes_(data, row) {
  349. var matchIndex = data[row][0].length;
  350.  
  351. for (var i = 1; i < data[row].length; i++) {
  352. matchIndex = findEqualityEndpoint_(data[row][i-1], data[row][i], matchIndex);
  353.  
  354. if (matchIndex == 0) {
  355. return;
  356. }
  357. }
  358.  
  359. for (var i = 0; i < data[row].length; i++) {
  360. data[row][i] = data[row][i].substring(matchIndex, data[row][i].length);
  361. }
  362. }
  363.  
  364. /**
  365. * Locates the index where the two strings values stop being equal, stopping automatically at the stopAt index.
  366. */
  367. function findEqualityEndpoint_(string1, string2, stopAt) {
  368. if (!string1 || !string2) {
  369. return -1;
  370. }
  371.  
  372. var maxEndpoint = Math.min(stopAt, string1.length, string2.length);
  373.  
  374. for (var i = 0; i < maxEndpoint; i++) {
  375. if (string1.charAt(i) != string2.charAt(i)) {
  376. return i;
  377. }
  378. }
  379.  
  380. return maxEndpoint;
  381. }
  382.  
  383.  
  384. /**
  385. * Converts the text to title case.
  386. */
  387. function toTitleCase_(text) {
  388. if (text == null) {
  389. return null;
  390. }
  391.  
  392. return text.replace(/\w\S*/g, function(word) { return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase(); });
  393. }
  394.  
  395. /**
  396. * Returns true if the given set of options contains the given option.
  397. */
  398. function hasOption_(options, option) {
  399. return options && options.indexOf(option) >= 0;
  400. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement