Related
How to replace the contents in multiple JSON files based on their file name?
I have a certain number of description files and I need to sort their contents by file name.
For ex. files numbered 1.json, 2.json, ... 10.json
All files inside have the same object names, but different numbers
{
"name": "Garlic 8",
"position": 8,
"description": "Only for stuff.",
"external": "row five",
"image": "buffer/8.png",
"basic": [
{
"type": "row",
"value": "one"
},
{
"color": "pure",
"value": "no"
}
]
}
How to replace numbers in all files with numbers from file names?
(i.e. the numbers inside the file must match the file number)
const basePath = process.cwd();
const fs = require("fs");
const {baseUri, namePrefix,} = require(`${basePath}/src/config.js`);
for (
let i = 1;
i <= 10;
i++
)
{
let rawdata = fs.readFileSync(`${basePath}/rename/json/${i}.json`);
let data = JSON.parse(rawdata);
var originalMsg = JSON.stringify(data);
data.each(function(item) {
{
item.name = `${namePrefix} #${i}`;
item.position = `${i}`;
item.image = `${baseUri}/${i}.png`;
}
});
console.log(originalMsg)
console.log(data)
But typeError: data.each is not a function
I have a sheet where for each row in column Z there is a JSON string recovered from Twitter via TAGS.
The JSON strings in column Z all have a similar structure:
{
"hashtags": [
{
"text": "Negev_Summit",
"indices": [
172,
185
]
}
],
"symbols": [],
"user_mentions": [
{
"screen_name": "JY_LeDrian",
"name": "Jean-Yves Le Drian",
"id": 1055021191,
"id_str": "1055021191",
"indices": [
69,
80
]
}
],
"urls": [],
"media": [
{
"id": 1513588335893258200,
"id_str": "1513588335893258240",
"indices": [
271,
294
],
"media_url": "http://pbs.twimg.com/media/FQFYknkXoAAxgYd.jpg",
"media_url_https": "https://pbs.twimg.com/media/FQFYknkXoAAxgYd.jpg",
"url": "https://twitter.com/yairlapid/status/1513588345468825605",
"display_url": "pic.twitter.com/dA4cBepIh2",
"expanded_url": "https://twitter.com/yairlapid/status/1513588345468825605/photo/1",
"type": "photo",
"sizes": {
"medium": {
"w": 1024,
"h": 576,
"resize": "fit"
},
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 1024,
"h": 576,
"resize": "fit"
},
"small": {
"w": 680,
"h": 383,
"resize": "fit"
}
}
}
]
}
I need to extract specific values for each JSON string in column Z and put them in columns AA, AB and AC (hashtags, user mentions, and URL's).
I've managed to achieve this with a really dirty multiple REGEXREPLACE formula but it doesn't seem logical that there is no way to fo this more efficiently:
=IFERROR("#"&JOIN(" #",SPLIT(REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(REGEXREPLACE(REGEXEXTRACT(INDIRECT("Y"&ROW()),".*user_mentions\"":\[(.*)\],\""urls.*"),"(,\""indices\"":\[\d+,\d+\])",""),"(,\""id_str\"":\""\d+\"")",""),"(,\""id\"":\d+)",""),"(\{\""screen_name\"":\"")",""),"\"",\""name\"":\""(.){1,50}\""\}",""),",")),"")
Ideally i'm looking for a script which would parse the JSON string and extract 1 or more values from each section of the JSON. For example:
For hashtags (column AA):
=PARSEJSON(Z1, "hashtags")
Result:
#hashtag1 #hashtag2
For user_mentions (column AB):
=PARSEJSON(Z1, "user_mentions/screen_name")
Result:
#username1 #username2
Would appreciate any help sending me in the right direction.
If your main purpose is to only get the values in screen_name I'd modify my script and I'd use =IMPORTJSON(url, "user_mentions/screen_name")
/**
* Imports JSON data to your spreadsheet Ex: IMPORTJSON("http://myapisite.com","city/population")
* #param url URL of your JSON data as string
* #param xpath simplified xpath as string
* #customfunction
*/
function IMPORTJSON(url,xpath){
try{
var res = UrlFetchApp.fetch(url);
var content = res.getContentText();
var json = JSON.parse(content);
var patharray = xpath.split("/");
for(var i=0;i<patharray.length;i++){
json = json[patharray[i]];
}
if(typeof(json) === "undefined"){
return "Node Not Available";
} else if(typeof(json) === "object"){
var tempArr = [];
for(var obj in json){
tempArr.push([obj,json[obj]]);
}
return tempArr;
} else if(typeof(json) !== "object") {
return json;
}
}
catch(err){
return "Error getting data";
}
}
I managed to do it with a different script I found here.
This is the script:
function getData(json, path) {
const obj = JSON.parse(json);
const keys = path.split('.');
let current = obj;
for( key of keys ){
current = current[key];
}
return current;
}
You would then enter in the cell with =getData(Z1, "hashtags")
#Yiddy s answer did not work for me. So i did some modifications to it and came up with this.
function getData(range, path, sheet_name) {
var sprsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = sprsheet.getSheetByName(sheet_name);
var string = sheet.getRange(range).getValue();
var json = JSON.parse(string);
const keys = path.split('.');
var current = json;
for (key of keys) {
current = current[key];
}
return current;
}
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 (e.g. 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:
Edit:
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:
Retrieve an array with all the indexes from array[0] where the header is ctin (excluding the first one).
Using these indexes, add each ctin segment to the main array.
Write the array to the sheet, taking into account that the different rows have different lengths. If you wanted to use a single 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);
}
I writing a script which calls REST API to get JSON to object as response and then import that JSON object in Google SpreadSheet. I have written the code to call the REST API and get the JSON object. Now I have to write such a code that will write the JSON object in a Google SpreadSheet.
Please see below code:
function myFunction() {
var options = {};
options.headers = {"Authorization": "Basic " + Utilities.base64Encode("username" + ":" + "password")}
options.muteHttpExceptions=true;
// var response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
var response=UrlFetchApp.fetch("url", options);
var dataAll=JSON.parse(response.getContentText())
Logger.log(dataAll)
/*
var sheet = Sheets.newSpreadsheet();
sheet.properties = Sheets.newSpreadsheetProperties();
sheet.properties.title = "Demo";
var spreadsheet = Sheets.Spreadsheets.create(sheet);
*/
}
This is code to call get the JSON object. The lines of code which have been commented out is for calling Google Sheets API.
I want such a script which will import the data in dataAll object, which is JSON object in Google SpreadSheet.
The JSON object is as below:
[
{
"id": 3428,
"type": "SUPER",
"firstName": "Nikhil",
"lastName": "Dingane",
"loginName": "nikhildingane",
"domain": "openspecimen",
"emailAddress": "nikhil#krishagni.com",
"instituteName": "Krishagni Institute",
"primarySite": "KSPL site",
"admin": true,
"instituteAdmin": false,
"manageForms": true,
"cpCount": 0,
"creationDate": 1586333347000,
"activityStatus": "Active"
},
{
"id": 3439,
"type": "NONE",
"firstName": "NikhilUpdated",
"lastName": "Dingane",
"loginName": "nikhildingane1",
"domain": "openspecimen",
"emailAddress": "nikhil.nikhil.dingane#gmail.com",
"instituteName": "Krishagni Institute",
"primarySite": "KSPL site",
"admin": false,
"instituteAdmin": false,
"manageForms": true,
"cpCount": 0,
"creationDate": 1586427573000,
"activityStatus": "Active"
}
]
I want to write this JSON in Google SpreadSheet
Assuming that dataAll is a 2D array of values
You can do it is as following with the SpreadsheetApp:
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var range = sheet.getRange(1,1, dataAll.length, dataAll[0].length);
range.setValues(dataAll);
References:
SpreadsheetApp
Range
setValues()
How to transform a JSON object into a 2D array
Use the Object.keys() method to access the key-value pairs of each of the JSON array elements
Use e.g. map to transform them into an array
Assemble the single arrays as desired to set them into the sheet
var array = [];
for (var i = 0; i< json.length; i++){
var newJson = Object.keys(json[i]).map(function (key) {
return [key, json[i][key]];
});
for(var j = 0; j< newJson.length; j++){
array.push(newJson[j]);
}
}
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var range = sheet.getRange(1,1, array.length, array[0].length);
range.setValues(array);
Range.setValues() is used to the set data as a two dimensional array to the sheet. Use Object.values and Object.keys with Array.map to convert array of objects to 2D array.
const data = [
{
"id": 3428,
"type": "SUPER",
"firstName": "Nikhil",
"lastName": "Dingane",
"loginName": "nikhildingane",
"domain": "openspecimen",
"emailAddress": "nikhil#krishagni.com",
"instituteName": "Krishagni Institute",
"primarySite": "KSPL site",
"admin": true,
"instituteAdmin": false,
"manageForms": true,
"cpCount": 0,
"creationDate": 1586333347000,
"activityStatus": "Active"
},
{
"id": 3439,
"type": "NONE",
"firstName": "NikhilUpdated",
"lastName": "Dingane",
"loginName": "nikhildingane1",
"domain": "openspecimen",
"emailAddress": "nikhil.nikhil.dingane#gmail.com",
"instituteName": "Krishagni Institute",
"primarySite": "KSPL site",
"admin": false,
"instituteAdmin": false,
"manageForms": true,
"cpCount": 0,
"creationDate": 1586427573000,
"activityStatus": "Active"
}
];
const out = [Object.keys(data[0]),...data.map(Object.values)];
console.info(out);
//SpreadsheetApp.getActive().getSheets()[0].getRange(1,1,out. length,out[0].length).setValues(out)
If I have the following post call:
$('#json_form').submit(function (event) {
event.preventDefault();
var url = $(this).attr('action');
var datos = {
"uno": "lalala",
"dos": "jojojo"
}
var data = JSON.stringify(datos);
$.post(url, data, function (resultado) {
$('#posted_values').html(resultado);
});
});
How can I receive and process the json object in a cshtml file? I mean what I put in Decode call:
if (IsPost)
{
var json_object = Json.Decode(Request???);
}
Edited to complete the answer of #MikeBrind, to help others with the same problem.
Example of using decode for a more complex json object.
$('#json_form').submit(function (event) {
event.preventDefault();
var url = $(this).attr('action');
var datos = {
"firstName": "John",
"lastName": "Smith",
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": 10021
},
"phoneNumber": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "fax",
"number": "646 555-4567"
}
]
}
var data = JSON.stringify(datos);
$.post(url, {"person": data}, function (resultado) {
$('#posted_values').html(resultado);
});
});
Receiving and using:
#{
dynamic json_object;
if (IsPost)
{
json_object = Json.Decode(Request["person"]);
#json_object.firstName<br/>
#json_object.lastName<br/>
#json_object.address.city<br/>
#json_object.address.postalCode<br/>
foreach (dynamic phone in json_object.phoneNumber)
{
#phone.type<br/>
#phone.number
}
}
}
Don't JSON.stringify the data if it is just key/value pairs like this. Do a form post:
$('#json_form').submit(function (event) {
event.preventDefault();
var url = $(this).attr('action');
var datos = {
"uno": "lalala",
"dos": "jojojo"
}
//var data = JSON.stringify(datos); no need for this
$.post(url, datos, function (resultado) {
$('#posted_values').html(resultado);
});
});
Then the values are available from Request["uno"] and Request["dos"]
If you ever do need to use JSON.stringify (which you would for more complex data structures), the JSON is transmitted in the Request body, so you need to extract it from Request.InputStream:
var reader = new StreamReader(Request.InputStream);
var json = reader.ReadToEnd();