Function libraries (and advanced widgets like Code Sandbox) are a powerful functionality, but they do come with various security-related limitations. Among them is the requirement that libraries should be bundled in a specific way. In particular, exceljs.js might need a specific distribution to be used as a Function library - personally I didn’t manage to use the version from CDN or their github repo with success. This library can be used out of the box in Code Sandbox as described in the docs, and you can then refer to the global ExcelJS in your sandboxed javascript. Given though that you’re interested in using the library to format the data coming from an object set, I am going to recommend another solution - Functions on Objects, for which there is first-class Slate support.
One of the advantages of this approach is that you can manage external dependencies like exceljs in a friendly way, instead of needing to upload libraries manually. Please see the steps below for an end-to-end instruction!
-
First, create a typescript functions repository.
-
In package.json in the repository, add exceljs as a dependency (general docs on how to do it can be found here)
-
Install the library by hitting the Add and install library
in the Libraries tab on the left-hand side
- You can now use the library in your code! Example of usage below:
import { Function } from "@foundry/functions-api";
import * as ExcelJS from "exceljs";
export class MyFunctions {
private generateXls(): ExcelJS.Workbook {
const workbook = new ExcelJS.Workbook()
const worksheet = workbook.addWorksheet('People')
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 10 },
{ header: 'D.O.B.', key: 'DOB', width: 30 }
]
worksheet.addRow([10086, 'Ken1', 'YYYY-MM-DD'])
worksheet.addRow([10087, 'Ken2', 'YYYY-MM-DD'])
worksheet.addRow([10088, 'Ken3', 'YYYY-MM-DD'])
return workbook;
}
@Function()
public async generateExcelTextDataCustom(): Promise<string> {
var workbook = this.generateXls()
// We get a Buffer
var xls64 = await workbook.xlsx.writeBuffer()
// Get the data out of the buffer
const json = JSON.stringify(xls64)
return json;
}
}
- Now you’re ready to publish your new function!
- Once function is published, you can reference it in Platform tab in Slate - you can see on the screenshot below that the function produces precisely what we asked it to in our code repository.
- You have asked about combining the data from an Object Set with the excel formatting - Functions on Objects are great for such workflows. You can have your Function perform both - load the objects from the object set, extract any properties from these objects and format their values using ExcelJS. Please refer to documentation.
- As for the last step of downloading the data, we come to the idea of using Code Sandbox again! Below are the contents of the respective widget tabs set up to work with our Function
- In Javascript tab:
async function saveFile (fileName, xls64) {
console.log("[FoO] Step 1. Before Blob", xls64)
var curr_excel = new Blob([xls64], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
console.log("[FoO] Step 2. Blob", curr_excel)
var url = window.URL.createObjectURL(curr_excel, "data:attachment/text", "test.xlsx");
var content = document.getElementById("content");
content.setAttribute("href", url)
content.setAttribute("download", "test.xlsx")
}
SlateFunctions.watch("ff_foundry_function_1", (newValue, oldValue) => {
console.log("[FoO] Preprocess 1. From FoO : ", newValue)
var parsed_json = JSON.parse(newValue)
console.log("[FoO] Preprocess 2. Parsed JSON : ", parsed_json)
var uarray = new Uint8Array(parsed_json["data"]);
// var ubuffer = Buffer.from(value);
console.log("[FoO] Preprocess 3. Uint8Array : ", uarray)
saveFile('fileNameXXX', uarray);
})
- In HTML tab:
<h1 id="title">
<a id="content">
Right Click on me... (from Functions)
</a>
</h1>
- In Interaction tab, under State
{
"ff_foundry_function_1": "{{ff_foundry_function_1}}"
}
- Now when right-clicking on the link and opening it in a new tab, we get our Excel downloaded! Of course there’s a myriad of other ways to set up the usage of our Function, but hope this example is useful!