Skip to content

Instantly share code, notes, and snippets.

@ci010
Created June 9, 2021 05:58
Show Gist options
  • Save ci010/4dbea022a07f344c393095119e5e1e36 to your computer and use it in GitHub Desktop.
Save ci010/4dbea022a07f344c393095119e5e1e36 to your computer and use it in GitHub Desktop.
Uses slicing to get the byte array and base64-encoded string that represent the current document.
name: Get file using slicing
description: >-
Uses slicing to get the byte array and base64-encoded string that represent
the current document.
host: EXCEL
api_set: {}
script:
content: |
$("#setup").click(() => tryCatch(setup));
$("#get-file").click(() => tryCatch(getCurrentFile));
$("#new-workbook-from-file").click(() => tryCatch(newWorkbookFromFile));
let base64Content: string = ''
function getCurrentFile() {
const sliceSize = 4096; /*Bytes*/
// This snippet specifies a small slice size to show how the getFileAsync() method uses slices.
Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: sliceSize }, function(result) {
if (result.status === Office.AsyncResultStatus.Failed) {
return onError(result.error);
}
// Result.value is the File object.
getFileContents(result.value, onSuccess, onError);
});
function onError(error: Office.Error): void {
console.error(error);
}
function onSuccess(byteArray: number[]) {
// Now that all of the file content is stored in the "data" parameter,
// you can do something with it, such as print the file, store the file in a database, etc.
console.log("Received the full contents of the file.");
let base64string = base64js.fromByteArray(byteArray);
base64Content = base64string
$("#file-contents")
.val(base64string)
.show();
console.log(
'The base64-encoded string that represents the current document has been written to the text box. To validate the string, use the "Create workbook from string" button.'
);
}
}
function getFileContents(
file: Office.File,
onSuccess: (byteArray: number[]) => void,
onError: (error: Office.Error) => void
) {
let expectedSliceCount = file.sliceCount;
let fileSlices: Array<Array<number>> = [];
console.log("Current file size in bytes: " + file.size);
console.log("Number of file slices: " + file.sliceCount);
getFileContentsHelper();
function getFileContentsHelper() {
file.getSliceAsync(fileSlices.length, function(result) {
if (result.status === Office.AsyncResultStatus.Failed) {
file.closeAsync();
return onError(result.error);
}
// Got one slice, store it in a temporary array.
fileSlices.push(result.value.data);
if (fileSlices.length == expectedSliceCount) {
console.log("All slices have been received.");
file.closeAsync();
let array = [];
fileSlices.forEach((slice) => {
array = array.concat(slice);
});
onSuccess(array);
} else {
getFileContentsHelper();
}
});
}
}
async function newWorkbookFromFile() {
await Excel.createWorkbook(base64Content).catch(function(error) {
console.error(error);
});
}
async function setup() {
await Excel.run(async (context) => {
context.workbook.worksheets.getItemOrNullObject("Sample").delete();
const sheet = context.workbook.worksheets.add("Sample");
let expensesTable = sheet.tables.add("A1:E1", true);
expensesTable.name = "SalesTable";
expensesTable.getHeaderRowRange().values = [["Product", "Qtr1", "Qtr2", "Qtr3", "Qtr4"]];
expensesTable.rows.add(null, [
["Frames", 5000, 7000, 6544, 4377],
["Saddles", 400, 323, 276, 651],
["Brake levers", 12000, 8766, 8456, 9812],
["Chains", 1550, 1088, 692, 853],
["Mirrors", 225, 600, 923, 544],
["Spokes", 6005, 7634, 4589, 8765]
]);
sheet.getUsedRange().format.autofitColumns();
sheet.getUsedRange().format.autofitRows();
createChart(context);
sheet.activate();
await context.sync();
});
}
async function createChart(context: Excel.RequestContext) {
const sheet = context.workbook.worksheets.getItem("Sample");
const salesTable = sheet.tables.getItem("SalesTable");
const dataRange = salesTable.getDataBodyRange();
let chart = sheet.charts.add("ColumnClustered", dataRange, Excel.ChartSeriesBy.columns);
chart.setPosition("A15", "F30");
chart.title.text = "Quarterly sales chart";
chart.legend.position = "Right";
chart.legend.format.fill.setSolidColor("white");
chart.dataLabels.format.font.size = 15;
chart.dataLabels.format.font.color = "black";
let points = chart.series.getItemAt(0).points;
points.getItemAt(0).format.fill.setSolidColor("pink");
points.getItemAt(1).format.fill.setSolidColor("indigo");
}
/** Default helper for invoking an action and handling errors. */
async function tryCatch(callback) {
try {
await callback();
} catch (error) {
// Note: In a production add-in, you'd want to notify the user through your add-in's UI.
console.error(error);
}
}
declare namespace base64js {
/** Takes a byte array and returns a base64 string
* Imported from https://www.npmjs.com/package/base64-js package. */
function fromByteArray(array: number[]): string;
}
language: typescript
template:
content: |
<section class="ms-font-m">
<p>This sample shows how to get the base64-encoded string that represents the current document. It uses the getFileAsync() method to read the file in slices and then joins all slices back together to form the complete file.</p>
</section>
<section class="setup ms-font-m">
<h3>Set up</h3>
<button id="setup" class="ms-Button">
<span class="ms-Button-label">Add sample data</span>
</button>
</section>
<section class="samples ms-font-m">
<h3>Try it out</h3>
<button id="get-file" class="ms-Button">
<span class="ms-Button-label">Get file</span>
</button>
<br/>
<textarea id="file-contents">
</textarea>
</section>
<section class="samples ms-font-m">
<h3>Create a new workbook</h3>
<button id="new-workbook-from-file" class="ms-Button">
<span class="ms-Button-label">Create workbook from string</span>
</button>
<br/>
</section>
language: html
style:
content: |
section.samples {
margin-top: 20px;
}
section.samples .ms-Button, section.setup .ms-Button {
display: block;
margin-bottom: 5px;
margin-left: 20px;
min-width: 80px;
}
#file-contents {
display: none;
width: 100%;
height: 10em;
}
language: css
libraries: |-
https://appsforoffice.microsoft.com/lib/1/hosted/office.js
@types/office-js
office-ui-fabric-js@1.4.0/dist/css/fabric.min.css
office-ui-fabric-js@1.4.0/dist/css/fabric.components.min.css
core-js@2.4.1/client/core.min.js
@types/core-js
jquery@3.1.1
@types/jquery@3.3.1
https://unpkg.com/base64-js@1.2.1/base64js.min.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment