Advertisement
Guest User

Untitled

a guest
Mar 25th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.65 KB | None | 0 0
  1. // Includes functions for exporting active sheet or all sheets as JSON object (also Python object syntax compatible).
  2. // Tweak the makePrettyJSON_ function to customize what kind of JSON to export.
  3.  
  4. var FORMAT_ONELINE = 'One-line';
  5. var FORMAT_MULTILINE = 'Multi-line';
  6. var FORMAT_PRETTY = 'Pretty';
  7.  
  8. var LANGUAGE_JS = 'JavaScript';
  9. var LANGUAGE_PYTHON = 'Python';
  10.  
  11. var STRUCTURE_LIST = 'List';
  12. var STRUCTURE_HASH = 'Hash (keyed by "id" column)';
  13.  
  14. /* Defaults for this particular spreadsheet, change as desired */
  15. var DEFAULT_FORMAT = FORMAT_PRETTY;
  16. var DEFAULT_LANGUAGE = LANGUAGE_JS;
  17. var DEFAULT_STRUCTURE = STRUCTURE_LIST;
  18.  
  19. /* Numero de fila (empezando en 0) donde se encuentran los encabezados expresados en formato camel case */
  20. var FILA_ENCABEZADOS_CAMEL_CASE = 1;
  21.  
  22.  
  23.  
  24. function onOpen() {
  25. var ss = SpreadsheetApp.getActiveSpreadsheet();
  26. var menuEntries = [
  27. {name: "Export JSON for this sheet", functionName: "exportSheet"},
  28. {name: "Export JSON for all sheets", functionName: "exportAllSheets"},
  29. {name: "Configure export", functionName: "exportOptions"},
  30. ];
  31. ss.addMenu("Export JSON", menuEntries);
  32. }
  33.  
  34.  
  35. function exportOptions() {
  36. var doc = SpreadsheetApp.getActiveSpreadsheet();
  37. var app = UiApp.createApplication().setTitle('Export JSON');
  38.  
  39. var grid = app.createGrid(4, 2);
  40. grid.setWidget(0, 0, makeLabel(app, 'Language:'));
  41. grid.setWidget(0, 1, makeListBox(app, 'language', [LANGUAGE_JS, LANGUAGE_PYTHON]));
  42. grid.setWidget(1, 0, makeLabel(app, 'Format:'));
  43. grid.setWidget(1, 1, makeListBox(app, 'format', [FORMAT_PRETTY, FORMAT_MULTILINE, FORMAT_ONELINE]));
  44. grid.setWidget(2, 0, makeLabel(app, 'Structure:'));
  45. grid.setWidget(2, 1, makeListBox(app, 'structure', [STRUCTURE_LIST, STRUCTURE_HASH]));
  46. grid.setWidget(3, 0, makeButton(app, grid, 'Export Active Sheet', 'exportSheet'));
  47. grid.setWidget(3, 1, makeButton(app, grid, 'Export All Sheets', 'exportAllSheets'));
  48. app.add(grid);
  49.  
  50. doc.show(app);
  51. }
  52.  
  53. function makeLabel(app, text, id) {
  54. var lb = app.createLabel(text);
  55. if (id) lb.setId(id);
  56. return lb;
  57. }
  58.  
  59. function makeListBox(app, name, items) {
  60. var listBox = app.createListBox().setId(name).setName(name);
  61. listBox.setVisibleItemCount(1);
  62.  
  63. var cache = CacheService.getPublicCache();
  64. var selectedValue = cache.get(name);
  65. Logger.log(selectedValue);
  66. for (var i = 0; i < items.length; i++) {
  67. listBox.addItem(items[i]);
  68. if (items[1] == selectedValue) {
  69. listBox.setSelectedIndex(i);
  70. }
  71. }
  72. return listBox;
  73. }
  74.  
  75. function makeButton(app, parent, name, callback) {
  76. var button = app.createButton(name);
  77. app.add(button);
  78. var handler = app.createServerClickHandler(callback).addCallbackElement(parent);;
  79. button.addClickHandler(handler);
  80. return button;
  81. }
  82.  
  83. function makeTextBox(app, name) {
  84. var textArea = app.createTextArea().setWidth('100%').setHeight('200px').setId(name).setName(name);
  85. return textArea;
  86. }
  87.  
  88. function exportAllSheets(e) {
  89.  
  90. var ss = SpreadsheetApp.getActiveSpreadsheet();
  91. var sheets = ss.getSheets();
  92. var sheetsData = {};
  93. for (var i = 0; i < sheets.length; i++) {
  94. var sheet = sheets[i];
  95. var rowsData = getRowsData_(sheet, getExportOptions(e));
  96. var sheetName = sheet.getName();
  97. sheetsData[sheetName] = rowsData;
  98. }
  99. var json = makeJSON_(sheetsData, getExportOptions(e));
  100. return displayText_(json);
  101. }
  102.  
  103. function exportSheet(e) {
  104. var ss = SpreadsheetApp.getActiveSpreadsheet();
  105. var sheet = ss.getActiveSheet();
  106. var rowsData = getRowsData_(sheet, getExportOptions(e));
  107. var json = makeJSON_(rowsData, getExportOptions(e));
  108. return displayText_(json);
  109. }
  110.  
  111. function getExportOptions(e) {
  112. var options = {};
  113.  
  114. options.language = e && e.parameter.language || DEFAULT_LANGUAGE;
  115. options.format = e && e.parameter.format || DEFAULT_FORMAT;
  116. options.structure = e && e.parameter.structure || DEFAULT_STRUCTURE;
  117.  
  118. var cache = CacheService.getPublicCache();
  119. cache.put('language', options.language);
  120. cache.put('format', options.format);
  121. cache.put('structure', options.structure);
  122.  
  123. Logger.log(options);
  124. return options;
  125. }
  126.  
  127. function makeJSON_(object, options) {
  128. if (options.format == FORMAT_PRETTY) {
  129. var jsonString = JSON.stringify(object, null, 4);
  130. } else if (options.format == FORMAT_MULTILINE) {
  131. var jsonString = Utilities.jsonStringify(object);
  132. jsonString = jsonString.replace(/},/gi, '},\n');
  133. jsonString = prettyJSON.replace(/":\[{"/gi, '":\n[{"');
  134. jsonString = prettyJSON.replace(/}\],/gi, '}],\n');
  135. } else {
  136. var jsonString = Utilities.jsonStringify(object);
  137. }
  138. if (options.language == LANGUAGE_PYTHON) {
  139. // add unicode markers
  140. jsonString = jsonString.replace(/"([a-zA-Z]*)":\s+"/gi, '"$1": u"');
  141. }
  142. return jsonString;
  143. }
  144.  
  145. function displayText_(text) {
  146. var app = UiApp.createApplication().setTitle('Exported JSON');
  147. app.add(makeTextBox(app, 'json'));
  148. app.getElementById('json').setText(text);
  149. var ss = SpreadsheetApp.getActiveSpreadsheet();
  150. ss.show(app);
  151. return app;
  152. }
  153.  
  154. // getRowsData iterates row by row in the input range and returns an array of objects.
  155. // Each object contains all the data for a given row, indexed by its normalized column name.
  156. // Arguments:
  157. // - sheet: the sheet object that contains the data to be processed
  158. // - range: the exact range of cells where the data is stored
  159. // - columnHeadersRowIndex: specifies the row number where the column names are stored.
  160. // This argument is optional and it defaults to the row immediately above range;
  161. // Returns an Array of objects.
  162. function getRowsData_(sheet, options) {
  163. var headersRange = sheet.getRange(1, 1, sheet.getFrozenRows(), sheet.getMaxColumns());
  164. var headers = headersRange.getValues()[FILA_ENCABEZADOS_CAMEL_CASE];
  165. var dataRange = sheet.getRange(sheet.getFrozenRows()+1, 1, sheet.getMaxRows(), sheet.getMaxColumns());
  166. var objects = getObjects_(dataRange.getValues(), headers);
  167. if (options.structure == STRUCTURE_HASH) {
  168. var objectsById = {};
  169. objects.forEach(function(object) {
  170. objectsById[object.id] = object;
  171. });
  172. return objectsById;
  173. } else {
  174. return objects;
  175. }
  176. }
  177.  
  178. // getColumnsData iterates column by column in the input range and returns an array of objects.
  179. // Each object contains all the data for a given column, indexed by its normalized row name.
  180. // Arguments:
  181. // - sheet: the sheet object that contains the data to be processed
  182. // - range: the exact range of cells where the data is stored
  183. // - rowHeadersColumnIndex: specifies the column number where the row names are stored.
  184. // This argument is optional and it defaults to the column immediately left of the range;
  185. // Returns an Array of objects.
  186. function getColumnsData_(sheet, range, rowHeadersColumnIndex) {
  187. rowHeadersColumnIndex = rowHeadersColumnIndex || range.getColumnIndex() - 1;
  188. var headersTmp = sheet.getRange(range.getRow(), rowHeadersColumnIndex, range.getNumRows(), 1).getValues();
  189. var headers = normalizeHeaders_(arrayTranspose_(headersTmp)[0]);
  190. return getObjects(arrayTranspose_(range.getValues()), headers);
  191. }
  192.  
  193.  
  194. // For every row of data in data, generates an object that contains the data. Names of
  195. // object fields are defined in keys.
  196. // Arguments:
  197. // - data: JavaScript 2d array
  198. // - keys: Array of Strings that define the property names for the objects to create
  199. function getObjects_(data, keys) {
  200. var objects = [];
  201. for (var i = 0; i < data.length; ++i) {
  202. var object = {};
  203. var hasData = false;
  204. for (var j = 0; j < data[i].length; ++j) {
  205. var cellData = data[i][j];
  206. if (isCellEmpty_(cellData)) {
  207. continue;
  208. }
  209. object[keys[j]] = cellData;
  210. hasData = true;
  211. }
  212. if (hasData) {
  213. objects.push(object);
  214. }
  215. }
  216. return objects;
  217. }
  218.  
  219.  
  220.  
  221. // Returns true if the cell where cellData was read from is empty.
  222. // Arguments:
  223. // - cellData: string
  224. function isCellEmpty_(cellData) {
  225. return typeof(cellData) == "string" && cellData == "";
  226. }
  227.  
  228. // Returns true if the character char is alphabetical, false otherwise.
  229. function isAlnum_(char) {
  230. return char >= 'A' && char <= 'Z' ||
  231. char >= 'a' && char <= 'z' ||
  232. isDigit_(char);
  233. }
  234.  
  235. // Returns true if the character char is a digit, false otherwise.
  236. function isDigit_(char) {
  237. return char >= '0' && char <= '9';
  238. }
  239.  
  240. // Given a JavaScript 2d Array, this function returns the transposed table.
  241. // Arguments:
  242. // - data: JavaScript 2d Array
  243. // Returns a JavaScript 2d Array
  244. // Example: arrayTranspose([[1,2,3],[4,5,6]]) returns [[1,4],[2,5],[3,6]].
  245. function arrayTranspose_(data) {
  246. if (data.length == 0 || data[0].length == 0) {
  247. return null;
  248. }
  249.  
  250. var ret = [];
  251. for (var i = 0; i < data[0].length; ++i) {
  252. ret.push([]);
  253. }
  254.  
  255. for (var i = 0; i < data.length; ++i) {
  256. for (var j = 0; j < data[i].length; ++j) {
  257. ret[j][i] = data[i][j];
  258. }
  259. }
  260.  
  261. return ret;
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement