'How to convert Excel Table to specific JSON format using Office Scripts
I'm trying to get a specific JSON output from Office Scripts in order to make an API call with Power Automate. The output I'm receiving from Power Automate does not have the format required in the API docs (link to API docs below). Tried modifying the script to get the required output but unfortunately, I'm just starting out with js, so I can't figure out what I need.
Right now, the input must come from an Excel table. I can format the excel table differently for this flow if it's needed, but nevertheless, the input must come from an Excel table. Right now, the Excel table looks like this:
This is the Office Script I am using, comes from this blog post: https://docs.microsoft.com/en-us/office/dev/scripts/resources/samples/get-table-data:
function main(workbook: ExcelScript.Workbook): TableData[] {
// Get the first table in the "WithHyperLink" worksheet.
// If you know the table name, use `workbook.getTable('TableName')` instead.
const table = workbook.getWorksheet('WithHyperLink').getTables()[0];
// Get all the values from the table as text.
const range = table.getRange();
// Create an array of JSON objects that match the row structure.
let returnObjects: TableData[] = [];
if (table.getRowCount() > 0) {
returnObjects = returnObjectFromValues(range);
}
// Log the information and return it for a Power Automate flow.
console.log(JSON.stringify(returnObjects));
return returnObjects
}
function returnObjectFromValues(range: ExcelScript.Range): TableData[] {
let values = range.getTexts();
let objectArray : TableData[] = [];
let objectKeys: string[] = [];
for (let i = 0; i < values.length; i++) {
if (i === 0) {
objectKeys = values[i]
continue;
}
let object = {}
for (let j = 0; j < values[i].length; j++) {
// For the 4th column (0 index), extract the hyperlink and use that instead of text.
if (j === 4) {
object[objectKeys[j]] = range.getCell(i, j).getHyperlink().address;
} else {
object[objectKeys[j]] = values[i][j];
}
}
objectArray.push(object as TableData);
}
return objectArray;
}
interface TableData {
"Event ID": string
Date: string
Location: string
Capacity: string
"Search link": string
Speakers: string
}
And this is the output I am getting in Power Automate when I run the Office Script:
[
{
"Line": "",
"Id": "0",
"Description": "nov portion of rider insurance",
"Amount": "100",
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": "",
"PostingType": "Debit",
"AccountRef": "",
"value": "39",
"name": "Opening Bal Equity"
},
{
"Line": "",
"Id": "",
"Description": "nov portion of rider insurance",
"Amount": "100",
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": "",
"PostingType": "Credit",
"AccountRef": "",
"value": "44",
"name": "Notes Payable"
}
]
BUT, the schema I need looks like this (it is based on this API doc https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/journalentry):
{
"Line": [
{
"Id": "0",
"Description": "nov portion of rider insurance",
"Amount": 100.0,
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": {
"PostingType": "Debit",
"AccountRef": {
"value": "39",
"name": "Opening Bal Equity"
}
}
},
{
"Description": "nov portion of rider insurance",
"Amount": 100.0,
"DetailType": "JournalEntryLineDetail",
"JournalEntryLineDetail": {
"PostingType": "Credit",
"AccountRef": {
"value": "44",
"name": "Notes Payable"
}
}
}
]
}
There are a lot of differences and obviously, when I try to make the API call, I get a 400 'Bad request' error. Does anyone know how I must modify either the Script or the Excel table or do something different in Power Automate in order to get the specific schema I need?
Any help will be appreciated. Thanks!!
Solution 1:[1]
I think the core of what's going on is that your script is parsing everything to match a linear "TableData" interface given in the tutorial you followed before it sends it to the Stringify method, but your data doesn't match that interface, so it does the best it can and outputs each individual row into an object array. When Stringify gets called, it sees an array of plain objects, so it just converts everything to a string.
I think you want this to be a bit more structured, which means you'll want to hand-code the objects you're passing for each of your rows. Basically, what your JSON schema is telling you is that your data types should be something like this:
Interface AccountRefPart {
value: string
name: string
}
Interface JournalEntryLineDetailPart {
PostingType: string
AccountRef: AccountRefPart
}
Interface LinePart {
ID?: string
Description: string
Amount: number
DetailType: string
JournalEntryLineDetail: JournalEntryLineDetailPart
}
Interface TableData {
Line: LinePart[]
}
If you just want to pass a single Line element as a JSON (what the outer-most curly braces suggest), you'll want to stringify a single object of the TableData type, and you want to construct this object using the data from the rows of your table. (I can't actually see your table, but I trust that it has the information you need above.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Dharman |
