Last active
January 31, 2022 14:13
-
-
Save cvillarongace/7d178048bfe790037c8ca05c54f82159 to your computer and use it in GitHub Desktop.
Creates a JSON string based on headers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Json From Headers | |
description: Creates a JSON string based on headers | |
host: EXCEL | |
api_set: {} | |
script: | |
content: |- | |
/** | |
* Evaluate a range of values and calculate a JSON string using headers as parents | |
* @customfunction | |
* @param {string[][]} fieldsRange | |
* @param {string[][]} valuesRange | |
* @returns JSON String. | |
*/ | |
function rangeJSONTest(fieldsRange, valuesRange) { | |
const parents = fieldsRange.reverse(); | |
/** | |
* Simple object check. | |
* @param item | |
* @returns {boolean} | |
*/ | |
const isObject = (item) => { | |
return (item && typeof item === 'object' && !Array.isArray(item)); | |
} | |
/** | |
* Deep merge two objects. | |
* @param target | |
* @param ...sources | |
*/ | |
const mergeDeep = (target, ...sources) => { | |
if (!sources.length) return target; | |
const source = sources.shift(); | |
if (isObject(target) && isObject(source)) { | |
for (const key in source) { | |
if (isObject(source[key])) { | |
if (!target[key]) Object.assign(target, { [key]: {} }); | |
mergeDeep(target[key], source[key]); | |
} else { | |
Object.assign(target, { [key]: source[key] }); | |
} | |
} | |
} | |
return mergeDeep(target, ...sources); | |
} | |
/* | |
Look for parent object | |
*/ | |
const lookUpForParent = (row, fields, index) => { | |
if ((index < 0) || row > fields.length) { | |
return; | |
} | |
if ((row === 0) && (fields[row][index] == "")) { | |
return lookUpForParent(row + 1, fields, index); | |
} | |
if ((fields[row][index] == "") && (index >= 0)) { | |
return lookUpForParent(row, fields, index - 1); | |
} | |
return fields[row][index] | |
} | |
/* | |
Look for Preperty Name | |
*/ | |
const lookUpForName = (row, fields, index, value) => { | |
const item = {}; | |
const result = {}; | |
if ((index < 0) || row > fields.length) { | |
return; | |
} | |
if ((row === 0) && (fields[row][index] == "")) { | |
return lookUpForName(row + 1, fields, index, value); | |
} | |
if ((fields[row][index] == "") && (index >= 0)) { | |
return lookUpForName(row, fields, index - 1, value); | |
} | |
item[fields[row][index]] = value; | |
if (row + 1 <= fields.length) { | |
const parent = lookUpForParent(row + 1, fields, index); | |
result[parent] = Object.assign({}, item); | |
} | |
return result | |
} | |
/* | |
Iterate Objects and headers | |
*/ | |
const findParents = (parents, index, value) => { | |
let actualRow = 0; | |
let actualPos = index; | |
if (!isNaN(value)) { | |
var x = value; | |
var y: number = +x; | |
value = y; | |
} | |
let fieldName = lookUpForName(actualRow, parents, actualPos, value); | |
return fieldName; | |
}; | |
let globalResult = {}; | |
let values = valuesRange[0]; | |
for (let _i = 0; _i < values.length; _i++) { | |
let value = values[_i]; | |
if (value != "") { | |
const X = Object.assign({}, findParents(fieldsRange, _i, value)); | |
globalResult = mergeDeep(globalResult, X); | |
} | |
} | |
return JSON.stringify(globalResult); | |
} | |
language: typescript | |
libraries: | | |
https://appsforoffice.microsoft.com/lib/1/hosted/office.js | |
@types/office-js | |
[email protected]/client/core.min.js |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment