I have a few JSON files on my Google Drive from which I need to extract data into a spreadsheet. I have tried the ImportJson function from github but that is to fetch the JSON file directly from the API but the JSON files I have on my drive are not accessible to me directly from the API.
Can anyone help me in how can I get the JSON stored on the drive to be imported in the Google sheets.
The sample JSON is attached herewith:
{ "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" }] }
Data sample to look like this
You basically want to retrieve all the nested properties in your object (after you've converted the JSON string using JSON.parse() , and write the corresponding key-value pairs to the first two rows of your spreadsheet (key in row 1, value in row 2). When the value is an object, the key
will be written in row 1, but row 2 will remain blank (eg b2b
).
In this case, you could use recursion to iterate through and retrieve all the nested properties and values from the object. The function could be something like this:
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]);
}
}
The idea is that, for each value, it checks if the value is an object or a primitive data type. If it's the former, allProps
gets called recursively, and if it's the latter, the key-value pair is added to the spreadsheet.
And you could call it this way:
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.
}
The output looks like this:
If you want each ctin
header (apart from the first one, in column D) to occupy a new row, you can do the following once you have retrieved the 2D array:
array[0]
where the header is ctin
(excluding the first one).ctin
segment to the main array.setValues
(that would be recommended for efficiency purposes), you'd first have to find the maximum length of the inner array elements, and make all the inner arrays have this length. The function JSON_to_Spreadsheet
could be something like this:
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
}
In this case, the output is:
This should work for a specific json file. Since opening a JSON file in drive is a bit hard to get the file ID you can use the first function to get the ID.
EDIT:
When you run the first function you can look-up the jsonfile ID in the logs -> View -> Log. Then insert this ID in the second function under // 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);
}
EDIT: this should work custom for your json file.
//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);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.