简体   繁体   English

将 JSON 填充并格式化为 Google Sheet

[英]Populating and formatting JSON into a Google Sheet

Thank you in advance to anyone that is able to help me on this.在此先感谢任何能够帮助我的人。 I have been trying for days to make this work, and just don't know enough about this to figure it out using examples.几天来我一直在努力使这项工作顺利进行,只是对此知之甚少,无法使用示例来弄清楚。

I have developed an Android app that places orders in a Realtime Database.我开发了一个在实时数据库中下订单的 Android 应用程序。 Each order has its own ID that is generated by the app.每个订单都有自己的 ID,由应用程序生成。 I would like each order to display in a row when I run the code and go into the correct column based on the column header.当我运行代码并根据列标题进入正确的列时,我希望每个订单都显示在一行中。 I have found this example that seems to fit my need exactly (same JSON structure), but does not work when I try to repurpose.我发现这个例子似乎完全符合我的需要(相同的 JSON 结构),但是当我尝试重新调整用途时不起作用。 Here is what I have:这是我所拥有的:

function chunkArray(myArray, chunk_size){
    var index = 0;
    var arrayLength = myArray.length;
    var tempArray = [];
    
    for (index = 0; index < arrayLength; index += chunk_size) {
        myChunk = myArray.slice(index, index+chunk_size);
        // Do something if you want with the group
        tempArray.push(myChunk);
    }

    return tempArray;
}

function flatten(arrayOfArrays){
  return [].concat.apply([], arrayOfArrays);
}


function insertJSON(){
  
  // this puts the keys in the correct place
  var aOneName = "id";
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName("orders");
  var fileURL = "<-RT DB Link ->";
  var res = UrlFetchApp.fetch(fileURL,{'muteHttpExceptions': true});
  var content = res.getContentText();
  var json = JSON.parse(content);
  var rows = [Object.keys(json)]; // Retrieve entry column.
  var toRows = rows[0].length;
  var toRows = toRows + 1;
  var rowsflate = flatten(rows);
  var rowstocols  = chunkArray(rowsflate, 1);
  sheet.getRange("A2:A" + toRows).setValues(rowstocols); // sets column of IDs
  sheet.getRange(1, 1).setValue(aOneName); // A1 name
  var headers = json[rows[0][2]];
  var getHeaders = [Object.keys(headers)];
  sheet.getRange(1,2,getHeaders.length,getHeaders[0].length).setValues(getHeaders); // Put values to Spreadsheet.
  content
  var content = [];
  var temp = [];
  for (var i = 0; i < rows[0].length; i++) {
    var temp2 = [Object.values(json[rows[0][i]])];// Retrieve values to be split.
    Logger.log(temp2);
    content.push(flatten(temp2));
  }
  var columncount1= rows[0].length;
  var columncount2 = getHeaders[0].length;
  sheet.getRange(2,2,columncount1,columncount2).setValues(content); // Put values to Spreadsheet.
}

The code works to pull the JSON data and correctly puts the keys for each order in column A starting at A2.该代码用于提取 JSON 数据,并将每个订单的键正确地放在 A 列中,从 A2 开始。 After that however there are 2 problems when using this code:之后,使用此代码时有两个问题:

  1. The headers are overwritten and the order of them is changed (alphabetized) - this is not a deal breaker and can reorder around this if needed, but ideally when placing the values in the cells it will look at the column header (same as the value header in the JSON) and place the correct values in the cells.标题被覆盖并更改它们的顺序(按字母顺序排列) - 这不是交易破坏者,如果需要,可以围绕此重新排序,但理想情况下,将值放入单元格时,它将查看列标题(与值相同) JSON 中的标头)并在单元格中放置正确的值。 Expected: What the spreadsheet should look like Actual: Reordering when code is run预期:电子表格应该是什么样子实际:代码运行时重新排序

  2. Object.values throws the error: TypeError: Cannot find function values in object function Object() { [native code for Object.Object, arity=1] }. (line 152, file "Code"). Object.values抛出错误: TypeError: Cannot find function values in object function Object() { [native code for Object.Object, arity=1] }. (line 152, file "Code"). TypeError: Cannot find function values in object function Object() { [native code for Object.Object, arity=1] }. (line 152, file "Code"). I have replaced this with .keys and attempted to use .map but then receive an error message below in the line sheet.getRange(2,2,columncount1,columncount2).setValues(content);我已将其替换为.keys并尝试使用.map但随后在sheet.getRange(2,2,columncount1,columncount2).setValues(content);行中收到一条错误消息: "The number of columns in the data does not match the number of columns in the range. The data has 1 but the range has 19. (line 161, file "Code")" "The number of columns in the data does not match the number of columns in the range. The data has 1 but the range has 19. (line 161, file "Code")"

Here is the JSON这是JSON

{
   "12":{
      "orderAddress":"address 1",
      "orderDelivered":"No",
      "orderDent":2,
      "orderDish":0,
      "orderEmail":"Not Provided",
      "orderId":"12",
      "orderLatLong":"Not Captured",
      "orderLend":1,
      "orderName":"Name 1",
      "orderPaid":"No",
      "orderPhone":"Phone 1",
      "orderSans":0,
      "orderSign":8,
      "orderText":6,
      "orderTint":0,
      "orderTotal":17,
      "orderTotalCost":200,
      "orderTrain":0,
      "orderTree":0
   },
   "13":{
      "orderAddress":"address 2",
      "orderDelivered":"No",
      "orderDent":0,
      "orderDish":1,
      "orderEmail":"Not Provided",
      "orderId":"13",
      "orderLatLong":"Not Captured",
      "orderLend":1,
      "orderName":"Name 2",
      "orderPaid":"Yes",
      "orderPhone":"Phone 2",
      "orderSans":0,
      "orderSign":0,
      "orderText":0,
      "orderTint":0,
      "orderTotal":27,
      "orderTotalCost":40,
      "orderTrain":0,
      "orderTree":0
   },
   "-MMIu9hQrxlZNs91nl2M":{
      "orderAddress":"address 3",
      "orderDelivered":"Yes",
      "orderDent":0,
      "orderDish":0,
      "orderEmail":"Not Provided",
      "orderId":"-MMIu9hQrxlZNs91nl2M",
      "orderLatLong":"Not Captured",
      "orderLend":1,
      "orderName":"Name 3",
      "orderPaid":"Yes",
      "orderPhone":"Phone 3",
      "orderSans":0,
      "orderSign":0,
      "orderText":0,
      "orderTint":0,
      "orderTotal":1,
      "orderTotalCost":12,
      "orderTrain":0,
      "orderTree":0
   }
}

Again, any direction on this would be greatly appreciated!再次,对此的任何方向将不胜感激!

I believe your goal as follows.我相信你的目标如下。

  • You want to retrieve the values from json and put the parsed values with the order of header of "id", "orderId", "orderName", "orderAddress", "orderPhone", "orderEmail", "orderLatLong", "orderDent", "orderLend", "orderTrain", "orderDish", "orderSans", "orderTint", "orderText", "orderSign", "orderTree", "orderTotal", "orderTotalCost", "orderPaid", "orderDelivered" .您想从json检索值并将解析后的值按照"id", "orderId", "orderName", "orderAddress", "orderPhone", "orderEmail", "orderLatLong", "orderDent", "orderLend", "orderTrain", "orderDish", "orderSans", "orderTint", "orderText", "orderSign", "orderTree", "orderTotal", "orderTotalCost", "orderPaid", "orderDelivered"的标头顺序"id", "orderId", "orderName", "orderAddress", "orderPhone", "orderEmail", "orderLatLong", "orderDent", "orderLend", "orderTrain", "orderDish", "orderSans", "orderTint", "orderText", "orderSign", "orderTree", "orderTotal", "orderTotalCost", "orderPaid", "orderDelivered"
  • You want to achieve this using Google Apps Script.您想使用 Google Apps 脚本来实现这一点。

Modification points:改装要点:

  • At JSON object, the order of keys are not guaranteed.在 JSON 对象中,不保证键的顺序。 So in your case, I think that giving the ordered header values is suitable.所以在你的情况下,我认为给出有序的标题值是合适的。
  • By declaring the header values as an array, I would like to propose the following flow.通过将标头值声明为数组,我想提出以下流程。
    1. Declare the header values.声明标题值。
    2. Create an array for putting to Spreadsheet.创建一个用于放入电子表格的数组。
    3. Put the created array to Spreadsheet.将创建的数组放入电子表格。

Whe above points are reflected to your script, it becomes as follows.当以上几点反映到你的脚本中时,它变成如下。

Modified script:修改后的脚本:

Please modify your script as follows.请按如下方式修改您的脚本。

From: 从:
 var rows = [Object.keys(json)]; // Retrieve entry column. var toRows = rows[0].length; var toRows = toRows + 1; var rowsflate = flatten(rows); var rowstocols = chunkArray(rowsflate, 1); sheet.getRange("A2:A" + toRows).setValues(rowstocols); // sets column of IDs sheet.getRange(1, 1).setValue(aOneName); // A1 name var headers = json[rows[0][2]]; var getHeaders = [Object.keys(headers)]; sheet.getRange(1,2,getHeaders.length,getHeaders[0].length).setValues(getHeaders); // Put values to Spreadsheet. content var content = []; var temp = []; for (var i = 0; i < rows[0].length; i++) { var temp2 = [Object.values(json[rows[0][i]])];// Retrieve values to be split. Logger.log(temp2); content.push(flatten(temp2)); } var columncount1= rows[0].length; var columncount2 = getHeaders[0].length; sheet.getRange(2,2,columncount1,columncount2).setValues(content); // Put values to Spreadsheet.
To: 到:
 // 1. Declare the header values. const header = ["id", "orderId", "orderName", "orderAddress", "orderPhone", "orderEmail", "orderLatLong", "orderDent", "orderLend", "orderTrain", "orderDish", "orderSans", "orderTint", "orderText", "orderSign", "orderTree", "orderTotal", "orderTotalCost", "orderPaid", "orderDelivered"]; // 2. Create an array for putting to Spreadsheet. const values = Object.entries(json).map(([k, v]) => { v.id = k; return header.map(h => v[h]); }); values.unshift(header); // When you want to add the header, please use this. // 3. Put the created array to Spreadsheet. sheet.getRange(1, 1, values.length, values[0].length).setValues(values);

Note:笔记:

  • When you use this script, please enable V8 runtime.使用此脚本时,请启用 V8 运行时。

Reference:参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM