JSON 云端硬盘上的文件为 Google 张

JSON File on Drive to Google sheets

我的 Google 驱动器 上有几个 JSON 文件,我需要从中提取数据到电子表格中。我已经从 github 尝试了 ImportJson 函数,但那是直接从 [=38] 获取 JSON 文件=] 但我无法直接从 API.

访问我驱动器上的 JSON 文件

任何人都可以帮助我如何将存储在驱动器上的 JSON 导入到 Google 工作表中。

附上样本JSON:

{
  "gstin": "12ABCDE",
  "fp": "082019",
  "b2b": [{
        "ctin": "2312ABCDEY",
        "cfs": "Y",
        "cfs3b": "Y",
        "inv": [{
          "val": 1072,
          "itms": [{
            "num": 1,
            "itm_det": {
              "csamt": 0,
              "samt": 81.76,
              "rt": 18,
              "txval": 908.48,
              "camt": 81.76
            }
          }],
          "inv_typ": "R",
          "pos": "23",
          "idt": "02-08-2019",
          "rchrg": "N",
          "inum": "642",
          "chksum": "7a58ec7342001040acf4509176ba22ceb03d9ad0ecf7e74d572af0ec4d8429fa"
        }, {
          "val": 1072,
          "itms": [{
            "num": 1,
            "itm_det": {
              "csamt": 0,
              "samt": 81.76,
              "rt": 18,
              "txval": 908.48,
              "camt": 81.76
            }
          }],
          "inv_typ": "R",
          "pos": "23",
          "idt": "17-08-2019",
          "rchrg": "N",
          "inum": "722",
          "chksum": "0597afa614e27aa78dc252f2530172007e574f52d1ceea9e433e04f474414bbf"
        }],
        "fldtr1": "10-Sep-19",
        "flprdr1": "Aug-19"
      }, {
        "ctin": "22AAB1Z5",
        "cfs": "Y",
        "cfs3b": "Y",
        "inv": [{
          "val": 459463,
          "itms": [{
            "num": 1801,
            "itm_det": {
              "csamt": 0,
              "rt": 18,
              "txval": 389375,
              "iamt": 70087.5
            }
          }],
          "inv_typ": "R",
          "pos": "23",
          "idt": "30-08-2019",
          "rchrg": "N",
          "inum": "2495",
          "chksum": "15ef392cfd4fd3af2fce1ad8549f93bac20cf17308df9bf9256ae838db45a440"
        }],
        "fldtr1": "11-Sep-19",
        "flprdr1": "Aug-19"
      }, {
        "ctin": "23AFEZI",
        "cfs": "Y",
        "cfs3b": "Y",
        "inv": [{
          "val": 9350,
          "itms": [{
            "num": 1,
            "itm_det": {
              "csamt": 0,
              "samt": 713.16,
              "rt": 18,
              "txval": 7924,
              "camt": 713.16
            }
          }],
          "inv_typ": "R",
          "pos": "23",
          "idt": "02-08-2019",
          "rchrg": "N",
          "inum": "00075",
          "chksum": "cb4fe40cb2f39f8782a160ece273991daae68b739dfba454ffeb364150d03580"
        }, {
          "val": 12312,
          "itms": [{
            "num": 1,
            "itm_det": {
              "csamt": 0,
              "samt": 939.07,
              "rt": 18,
              "txval": 10434.09,
              "camt": 939.07
            }
          }],
          "inv_typ": "R",
          "pos": "23",
          "idt": "10-08-2019",
          "rchrg": "N",
          "inum": "00084",
          "chksum": "1d0fa36c2a7f1ffe7d7c07a829056e4e28fd0300fd593f91ba8216ace4e54f2a"
        }],
        "fldtr1": "05-Sep-19",
        "flprdr1": "Aug-19"
      }, {
        "ctin": "23ECVPSQ",
        "cfs": "Y",
        "cfs3b": "Y",
        "inv": [{
          "val": 10200,
          "itms": [{
            "num": 1,
            "itm_det": {
              "csamt": 0,
              "samt": 777.97,
              "rt": 18,
              "txval": 8644.1,
              "camt": 777.97
            }
          }],
          "inv_typ": "R",
          "pos": "23",
          "idt": "13-08-2019",
          "rchrg": "N",
          "inum": "650",
          "chksum": "43bcf7c73bf94013344111d95c6f80dea47980ef4bfd3093a33e2c385baa2fdd"
        }, {
          "val": 4745,
          "itms": [{
            "num": 1,
            "itm_det": {
              "csamt": 0,
              "samt": 361.91,
              "rt": 18,
              "txval": 4021.18,
              "camt": 361.91
            }
          }],
          "inv_typ": "R",
          "pos": "23",
          "idt": "30-08-2019",
          "rchrg": "N",
          "inum": "727",
          "chksum": "fae1037d879dc718f322e8622a5323344a6cf88b68f68620aaa7ed5d92a15a23"
        }]
      }

数据样本看起来像这样

这应该适用于特定的 json 文件。由于在驱动器中打开 JSON 文件有点难以获取文件 ID,因此您可以使用第一个函数来获取 ID。

编辑:

当您运行第一个函数时,您可以look-up json日志中的json文件ID -> 查看-> 日志。然后将此 ID 插入到 // Change file id

下的第二个函数中
//With this function you can get the ID of you json file. After running see the view -> Logs for the info.
function getDriveFileID() {

  //Change id of the drive folder found in the url
  const folderID = "1UN3xxxpE8mXjHHJJF";
  const driveFolder = DriveApp.getFolderById(folderID);
  const driveFiles = driveFolder.getFiles();

  while(driveFiles.hasNext()){
    let file = driveFiles.next();
    console.log(file.getName()," = ",file.getId());
  };
}

function JSON_from_DRIVE() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  //change output sheetname
  const sheet = ss.getSheetByName("Data");
  //Change file id
  const file = DriveApp.getFileById("1IPyU2nxxxxx_lr0F").getBlob().getDataAsString();
  const dataAll = JSON.parse(file);
  const dataRows = dataAll['b2b'];
  
  const rowHeaders = Object.keys(dataRows[0]);
  const rows = [rowHeaders];
  for (var i = 0; i < dataRows.length; i++) {
    var rowData = [];
    for (var j = 0; j < rowHeaders.length; j++) {
      rowData.push(dataRows[i][rowHeaders[j]]); 
    }
    rows.push(rowData);
  }

  sheet.getRange(1,1,rows.length,rows[0].length).setValues(rows); 

}

编辑:这应该适用于您的 json 文件。

//With this function you can get the ID of you json file. After running see the view -> Logs for the info.
function getDriveFileID() {

    //Change id of the drive folder found in the url
    const folderID = "1UN3xxxpE8mXjHHJJF";
    const driveFolder = DriveApp.getFolderById(folderID);
    const driveFiles = driveFolder.getFiles();

    while (driveFiles.hasNext()) {
        let file = driveFiles.next();
        console.log(file.getName(), " = ", file.getId());
    };
}

function JSON_from_DRIVE() {
    const ss = SpreadsheetApp.getActiveSpreadsheet();
    //change output sheetname
    const sheet = ss.getSheetByName("Data");
    //Change file id
    const file = DriveApp.getFileById("1IPyU2nxxxxx_lr0F").getBlob().getDataAsString();
    const dataAll = JSON.parse(file);
    const b2b = dataAll['b2b'];
    const dataRows = [];

    b2b.forEach(base => {
        base.inv.forEach(inv => {
            const obj = {
                "ctin": base.ctin,
                "cfs": base.cfs,
                "cfs3b": base.cfs3b,
                "val": inv.val,
                "num": inv.itms[0].itm_det.csamt,
                "csamt": inv.itms[0].itm_det.csamt,
                "samt": inv.itms[0].itm_det.samt,
                "rt": inv.itms[0].itm_det.rt,
                "txval": inv.itms[0].itm_det.txval,
                "camt": inv.itms[0].itm_det.camt,
                "inv_type": inv.inv_typ,
                "pos": inv.pos,
                "idt": inv.idt,
                "rchrg": inv.rchrg,
                "inum": inv.inum,
                "chksum": inv.chksum,
                "fldtr1": base.fldtr1,
                "flprdr1": base.flprdr1
            }
            newObj.push(obj);
        });
    });

    const rowHeaders = Object.keys(dataRows[0]);
    const rows = [rowHeaders];
    for (var i = 0; i < dataRows.length; i++) {
        var rowData = [];
        for (var j = 0; j < rowHeaders.length; j++) {
            rowData.push(dataRows[i][rowHeaders[j]]);
        }
        rows.push(rowData);
    }

    sheet.getRange(1, 1, rows.length, rows[0].length).setValues(rows);

}

您基本上想要检索 object 中的所有嵌套属性(在使用 JSON.parse() 转换 JSON 字符串之后,写入相应的 key-value pairs to the first throws of your spreadsheet (key in row 1, value in row 2). 当值为 object 时,key 将写入第 1 行,但第 2 行将保持空白(例如 b2b)。

在这种情况下,您可以使用递归遍历并检索 object 中的所有嵌套属性和值。该函数可能是这样的:

function allProps(element, array, parent = "") {
  if (typeof element === 'object' && element !== null) {
    if (parent != "") array.push([parent, ""]);
    const entries = Object.entries(element);    
    entries.forEach(entry => {
      const nextParent = Array.isArray(element) ? "" : entry[0];              
      allProps(entry[1], array, nextParent);
    });
  } else {
    array.push([parent, element]);
  }
}

这个想法是,对于每个值,它检查该值是 object 还是原始数据类型。如果是前者,allProps 被递归调用,如果是后者,key-value 对被添加到 spreadsheet.

你可以这样称呼它:

function JSON_to_Spreadsheet() {
  const id = "JSON_FILE_ID"; // Change to your FILE_ID
  const json = DriveApp.getFileById(id).getBlob().getDataAsString(); // Get JSON text from Drive file
  const obj = JSON.parse(json); // JSON text to JS object 
  let array = []; // 2D array where the output will be stored
  allProps(obj, array, parent = ""); // Call function recursively
  array = array[0].map((_, colIndex) => array.map(row => row[colIndex])); // Transpose 2D array
  const sheet = SpreadsheetApp.getActive().getActiveSheet(); // Retrieve active sheet. Change if you want to access another sheet or another spreadsheet
  sheet.getRange(1,1,array.length, array[0].length).setValues(array); // Write 2D array to your sheet.
}

输出如下所示:

编辑:

如果您希望每个 ctin header(除了第一个,在 D 列中)占据一个新行,您可以在检索到二维数组后执行以下操作:

  • 检索一个包含 array[0] 中所有索引的数组,其中 header 是 ctin(不包括第一个)。
  • 使用这些索引,将每个 ctin 段添加到主数组。
  • 将数组写入sheet,考虑到不同行的长度不同。如果您想使用单个 setValues(出于效率目的建议这样做),您首先必须找到内部数组元素的最大长度,并使所有内部数组都具有此长度。

函数 JSON_to_Spreadsheet 可能是这样的:

function JSON_to_Spreadsheet() {
  const id = "JSON_FILE_ID"; // Change to your FILE_ID
  const json = DriveApp.getFileById(id).getBlob().getDataAsString(); // Get JSON text from Drive file
  const obj = JSON.parse(json); // JSON text to JS object 
  let array = []; // 2D array where the output will be stored
  allProps(obj, array, parent = ""); // Call function recursively
  array = array[0].map((_, colIndex) => array.map(row => row[colIndex])); // Transpose 2D array
  const ctinFirstIndex = 3; // Column D (first ctin)
  const ctinIndexes = array[0].reduce((acc, current, i) => {
    if (current === "ctin" && i !== ctinFirstIndex) {
      acc.push(i);
    } 
    return acc;
  }, []); // Find indexes for all ctin headers
  for (let i = 0; i < ctinIndexes.length; i++) {
    [0,1].forEach(rowIndex => {
      const sliced = array[rowIndex].slice(ctinIndexes[i], ctinIndexes[i + 1]); // Extract ctin segment
      sliced.unshift("","",""); // Columns A to C should be empty
      array.push(sliced); // Add each ctin segment to the 2D array
    });    
  }
  [0,1].forEach(rowIndex => array[rowIndex].splice(ctinIndexes[0])); // Remove other ctin data from first two rows
  const sheet = SpreadsheetApp.getActive().getSheetByName("Copy of Data");
  for (let i = 0; i < array.length; i = i + 2) {
    sheet.getRange(sheet.getLastRow() + 1, 1, 2, array[i].length).setValues(array.slice(i, i + 2));
  } // Write array to sheet. Rows have different dimensions, so cannot be written all at once
}

在这种情况下,输出为: