Apparently there is a 5MB limit when making requests in Excel Online (see: https://github.com/OfficeDev/office-js-docs-reference/issues/354).
We are using the Office JavaScript API to write large amounts of data into an Excel worksheet, using the following code:
// Example rows - in our actual code this comes from an API
const rows = [
["Date", "Product", "Sales", "Customers"],
["13/03/2020", "Chocolate biscuits", 598.00, 93],
// ... and many more
]
sheet.getRangeByIndexes(0, 0, numRows, numColumns).values = rows;
Exceeding the aforementioned limit will cause this error to be thrown: RichApi.Error: An internal error has occurred.
The number of rows and columns is unknown at build time; the size of the data depends on queries run by users of an add-in.
Is there any reliable way of ensuring our request does not exceed the limit?
I attempted tracking the size of the JSON serialised value arrays, and allowing some overhead factor:
Excel.run(async context => {
const sheet = context.workbook.worksheets.add();
// 50% of 5MB: allow 50% of overhead
const THRESHOLD = 0.5 * (5 * 1000 * 1000);
let bytes = 0;
// Example rows - in our actual code this comes from an API
const numColumns = 4;
const rows = [
["Date", "Product", "Sales", "Customers"],
["13/03/2020", "Chocolate biscuits", 598.00, 93],
// ... and many more
];
for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
const row = rows[rowIndex];
sheet.getRangeByIndexes(rowIndex, 0, 1, numColumns).values = [row];
bytes += JSON.stringify([row]).length;
if (bytes >= THRESHOLD) {
await context.sync();
bytes = 0;
}
}
return context.sync();
}
Even allowing a 50% overhead, the call to context.sync()
was still throwing RichApi.Error: An internal error has occurred.
with some data. Perhaps I could set this to something really low (like 10%) but that would be quite inefficient in most cases. I am hoping there's a more reliable way of computing the payload size, or a way of interrogating the Office API to check the size of the pending request.