【问题标题】:Populating and formatting JSON into a Google Sheet将 JSON 填充并格式化为 Google 表格
【发布时间】:2021-03-01 05:11:51
【问题描述】:

提前感谢任何能够帮助我的人。我已经尝试了好几天来完成这项工作,只是对此了解不够,无法通过示例来解决。

我开发了一个 Android 应用,可以在实时数据库中下订单。每个订单都有自己的 ID,由应用程序生成。当我运行代码并根据列标题进入正确的列时,我希望每个订单都显示在一行中。我发现这个example 似乎完全符合我的需要(相同的 JSON 结构),但是当我尝试重新调整用途时不起作用。这是我所拥有的:

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.
}

代码用于提取 JSON 数据,并将每个订单的键正确地放在从 A2 开始的 A 列中。之后,使用此代码时有两个问题:

  1. 标题被覆盖并且它们的顺序被改变(字母化) - 这不是一个交易破坏者,如果需要可以重新排序,但理想情况下,当将值放在单元格中时,它会查看列标题(相同作为 JSON 中的值标头)并将正确的值放置在单元格中。 预期的: What the spreadsheet should look like 实际的: Reordering when code is run

  2. Object.values 抛出错误:TypeError: Cannot find function values in object function Object() { [native code for Object.Object, arity=1] }. (line 152, file "Code"). 我已将其替换为.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")"

这是 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
   }
}

再次,我们将不胜感激任何方向!

【问题讨论】:

  • 关于Expected: What the spreadsheet should look like,我无法理解检索您期望的标题顺序的逻辑。我可以问你目标的细节吗?
  • @Tanaike 标题的目标是将其保持在“预期”图片的顺序中。运行脚本时,标题的顺序变为字母顺序。总体目标是将每个 JSON 条目推送到正确标题下的每一行。抱歉,如果我解释得不好。
  • 感谢您的回复。根据您的回复,我提出了一个修改后的脚本作为答案。你能确认一下吗?如果我误解了您的目标,我深表歉意。
  • @Tanaike 感谢您的帮助!我收到代码const values = Object.entries(json).map(([k, v]) =&gt; { 的以下错误:Syntax error. (line 167, file "Code")
  • 感谢您的回复。我带来的不便表示歉意。从你的回复。我担心您可能没有在脚本编辑器中启用 V8 运行时。如果是这样,请启用 V8 运行时并再次测试。如果我误解了您的情况,您能否提供复制问题的详细流程。借此,我想确认一下。顺便说一句,根据您的问题,我提出了使用Here is the JSON 的样本值作为var json = JSON.parse(content);json 的脚本。我的理解正确吗?

标签: javascript json google-apps-script firebase-realtime-database google-sheets


【解决方案1】:

我相信你的目标如下。

  • 您想从json 中检索值,并将解析后的值按照标题"id", "orderId", "orderName", "orderAddress", "orderPhone", "orderEmail", "orderLatLong", "orderDent", "orderLend", "orderTrain", "orderDish", "orderSans", "orderTint", "orderText", "orderSign", "orderTree", "orderTotal", "orderTotalCost", "orderPaid", "orderDelivered" 的顺序放置。
  • 您希望使用 Google Apps 脚本实现此目的。

修改点:

  • 在 JSON 对象中,不保证键的顺序。所以在你的情况下,我认为给出有序的标题值是合适的。
  • 通过将标头值声明为数组,我想提出以下流程。
    1. 声明标头值。
    2. 创建一个数组以放入电子表格。
    3. 将创建的数组放入电子表格。

以上几点反映到你的脚本中,变成如下。

修改脚本:

请按如下方式修改您的脚本。

从:
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.
到:
// 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);

注意:

  • 使用此脚本时,请启用 V8 运行时。

参考:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-22
    • 2015-03-21
    • 2021-11-08
    • 1970-01-01
    • 2022-11-18
    • 1970-01-01
    • 2015-09-20
    • 2022-01-08
    相关资源
    最近更新 更多