Created
June 9, 2021 05:58
-
-
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.
This file contains 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: 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