2022-07-26 19:24:43 +00:00
---
title: Legacy Frameworks
2023-01-10 00:31:37 +00:00
pagination_prev: demos/index
2023-02-28 11:40:44 +00:00
pagination_next: demos/grid/index
2023-01-09 05:08:30 +00:00
sidebar_position: 9
sidebar_custom_props:
skip: 1
2022-07-26 19:24:43 +00:00
---
import current from '/version.js';
2023-05-03 03:40:40 +00:00
import CodeBlock from '@theme/CodeBlock';
2022-07-26 19:24:43 +00:00
Over the years, many frameworks have been released. Some were popular years ago
but have waned in recent years. There are still many deployments using these
2022-08-19 06:42:18 +00:00
frameworks and it is oftentimes easier to continue maintenance than to rewrite
2022-07-26 19:24:43 +00:00
using modern web techniques.
SheetJS libraries strive to maintain broad browser and JS engine compatibility.
## Integration
2022-11-13 20:45:13 +00:00
["Standalone Browser Scripts" ](/docs/getting-started/installation/standalone )
section has instructions for obtaining or referencing the standalone scripts.
These are designed to be referenced with `<script>` tags.
2022-07-26 19:24:43 +00:00
2022-08-09 04:23:52 +00:00
## Internet Explorer
2023-08-17 20:30:13 +00:00
:::warning pass
2022-08-09 04:23:52 +00:00
Internet Explorer is unmaintained and users should consider modern browsers.
The SheetJS testing grid still includes IE and should work.
:::
The modern upload and download strategies are not available in older versions of
2022-11-13 20:45:13 +00:00
IE, but there are approaches using ActiveX or Flash.
2022-08-09 04:23:52 +00:00
< details > < summary > < b > Complete Example< / b > (click to show)< / summary >
This demo includes all of the support files for the Flash and ActiveX methods.
1) Download the standalone script and shim to a server that will host the demo:
< ul >
2023-04-27 09:12:19 +00:00
< li > < a href = {`https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`} > shim.min.js< / a > < / li >
< li > < a href = {`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`} > xlsx.full.min.js< / a > < / li >
2022-08-09 04:23:52 +00:00
< / ul >
2) [Download the demo ZIP ](pathname:///ie/SheetJSIESupport.zip ) to the server.
The ZIP includes the demo HTML file as well as the Downloadify support files.
Extract the contents to the same folder as the scripts from step 1
3) Start a HTTP server:
```bash
npx -y http-server .
```
4) Access the `index.html` from a machine with Internet Explorer.
< / details >
< details > < summary > < b > Other Live Demos< / b > (click to show)< / summary >
2023-08-17 20:30:13 +00:00
:::caution pass
2022-08-09 04:23:52 +00:00
The hosted solutions may not work in older versions of Windows. For testing,
demo pages should be downloaded and hosted using a simple HTTP server.
:::
2022-10-20 18:47:20 +00:00
< https: / / oss . sheetjs . com / sheetjs / ajax . html > uses XMLHttpRequest to download test
2022-08-25 08:22:28 +00:00
files and convert to CSV
2022-08-09 04:23:52 +00:00
< https: // oss . sheetjs . com / sheetjs /> demonstrates reading files with `FileReader` .
Older versions of IE do not support HTML5 File API but do support Base64.
2022-08-23 03:20:02 +00:00
On MacOS you can get the Base64 encoding with:
2022-08-09 04:23:52 +00:00
```bash
$ < target_file base64 | pbcopy
```
On Windows XP and up you can get the Base64 encoding using `certutil` :
```cmd
> certutil -encode target_file target_file.b64
```
(note: You have to open the file and remove the header and footer lines)
< / details >
### Upload Strategies
IE10 and IE11 support the standard HTML5 FileReader API:
```js
function handle_fr(e) {
var f = e.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
var wb = XLSX.read(e.target.result);
process_wb(wb); // DO SOMETHING WITH wb HERE
};
reader.readAsArrayBuffer(f);
}
input_dom_element.addEventListener('change', handle_fr, false);
```
`Blob#arrayBuffer` is not supported in IE!
2022-08-25 08:22:28 +00:00
**ActiveX Upload**
2022-08-09 04:23:52 +00:00
Through the `Scripting.FileSystemObject` object model, a script in the VBScript
2022-08-25 08:22:28 +00:00
scripting language can read from an arbitrary path on the file system. The shim
includes a special `IE_LoadFile` function to read binary data from files. This
2022-08-09 04:23:52 +00:00
should be called from a file input `onchange` event:
```js
var input_dom_element = document.getElementById("file");
function handle_ie() {
/* get data from selected file */
var path = input_dom_element.value;
var bstr = IE_LoadFile(path);
/* read workbook */
var wb = XLSX.read(bstr, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
}
input_dom_element.attachEvent('onchange', handle_ie);
```
### Download Strategies
As part of the File API implementation, IE10 and IE11 provide the `msSaveBlob`
and `msSaveOrOpenBlob` functions to save blobs to the client computer. This
approach is embedded in `XLSX.writeFile` and no additional shims are necessary.
**Flash-based Download**
2023-08-17 20:30:13 +00:00
It is possible to write to the file system using a SWF file. `Downloadify` [^1]
2022-08-09 04:23:52 +00:00
implements one solution. Since a genuine click is required, there is no way to
force a download. The safest data type is Base64:
```js
// highlight-next-line
Downloadify.create(element_id, {
/* Downloadify boilerplate */
swf: 'downloadify.swf',
downloadImage: 'download.png',
width: 100, height: 30,
transparent: false, append: false,
// highlight-start
/* Key parameters */
filename: "test.xlsx",
dataType: 'base64',
data: function() { return XLSX.write(wb, { bookType: "xlsx", type: 'base64' }); }
// highlight-end
// highlight-next-line
});
```
2022-08-25 08:22:28 +00:00
**ActiveX Download**
2022-08-09 04:23:52 +00:00
Through the `Scripting.FileSystemObject` object model, a script in the VBScript
scripting language can write to an arbitrary path on the filesystem. The shim
includes a special `IE_SaveFile` function to write binary strings to file. It
attempts to write to the Downloads folder or Documents folder or Desktop.
2023-08-17 20:30:13 +00:00
This approach does not require user interaction, but ActiveX must be enabled. It
2022-08-09 04:23:52 +00:00
is embedded as a strategy in `writeFile` and used only if the shim script is
included in the page and the relevant features are enabled on the target system.
2022-07-26 19:24:43 +00:00
## Frameworks
2022-08-30 22:12:52 +00:00
### Dojo Toolkit
_Live Demos_
- [Download and display data ](pathname:///dojo/read.html )
- [Fetch JSON and generate a workbook ](pathname:///dojo/write.html )
2023-08-17 20:30:13 +00:00
:::note pass
These demos have been tested with Dojo Toolkit `1.10.4` and `1.17.3` .
:::
:::warning pass
The official Google CDN is out of date. This is a known CDN bug.
The script < https: / / docs . sheetjs . com / dojo / dojo . js > was fetched from the official
2023-08-30 03:44:38 +00:00
`1.17.3` uncompressed release artifact[^2] on 2023-08-16.
2023-08-17 20:30:13 +00:00
:::
_Installation_
2022-08-30 22:12:52 +00:00
2022-10-30 05:45:37 +00:00
The ["AMD" instructions ](/docs/getting-started/installation/amd#dojo-toolkit )
2022-08-30 22:12:52 +00:00
includes details for use with `require` .
< details > < summary > < b > Integration in the demos< / b > (click to show)< / summary >
The demos use the async loading strategy with the SheetJS CDN:
2023-05-03 03:40:40 +00:00
< CodeBlock language = "html" > {`\
2022-08-30 22:12:52 +00:00
< script >
dojoConfig = {
packages: [
2023-05-03 03:40:40 +00:00
{ name: "xlsx", location: "https://cdn.sheetjs.com/xlsx-${current}/package/dist", main: "xlsx.full.min" }
2022-08-30 22:12:52 +00:00
]
}
< / script >
2023-08-17 20:30:13 +00:00
< script src = "dojo.js" data-dojo-config = "isDebug:1, async:1" > < / script >
2022-08-30 22:12:52 +00:00
< script >
require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
/* XLSX-related operations happen in the callback */
});
2023-05-03 03:40:40 +00:00
< / script > `}
< / CodeBlock >
2022-08-30 22:12:52 +00:00
< / details >
2022-10-30 05:45:37 +00:00
The ["Dojo" section in "Bundlers" ](/docs/demos/bundler#dojo ) includes a complete example
2023-07-26 20:18:07 +00:00
mirroring the [official export example ](/docs/getting-started/examples/export )
2022-08-30 22:12:52 +00:00
< details > < summary > < b > Details< / b > (click to show)< / summary >
_Reading Data_
When fetching spreadsheets with XHR, `handleAs: "arraybuffer"` yields an
`ArrayBuffer` which can be passed to `XLSX.read` :
```html
< div id = "tbl" > < / div >
< script >
require(["dojo/request/xhr", "xlsx"], function(xhr, _XLSX) {
xhr("https://sheetjs.com/pres.numbers", {
headers: { "X-Requested-With": null },
// highlight-next-line
handleAs: "arraybuffer"
}).then(function(ab) {
/* read ArrayBuffer */
// highlight-next-line
var wb = XLSX.read(ab);
/* display first worksheet data */
var ws = wb.Sheets[wb.SheetNames[0]];
document.getElementById("tbl").innerHTML = XLSX.utils.sheet_to_html(ws);
});
});
< / script >
```
:::note
The `X-Requested-With` header setting resolves some issues related to CORS.
:::
_Writing Data_
`XLSX.writeFile` works as expected:
```html
< script >
require(["xlsx"], function(_XLSX) {
var ws = XLSX.utils.aoa_to_sheet(["SheetJS".split(""), [5,4,3,3,7,9,5]]);
var wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
/* create an XLSX file and try to save to SheetJSDojo.xlsx */
// highlight-next-line
XLSX.writeFile(workbook, "SheetJSDojo.xlsx");
});
< / script >
```
< / details >
2022-07-26 19:24:43 +00:00
### KnockoutJS
2022-11-13 20:45:13 +00:00
KnockoutJS was a popular MVVM framework.
2022-07-26 19:24:43 +00:00
The [Live demo ](pathname:///knockout/knockout.html ) shows a view model that is
updated with file data and exported to spreadsheets.
2022-08-01 05:34:23 +00:00
< details > < summary > < b > Full Exposition< / b > (click to show)< / summary >
2022-07-26 19:24:43 +00:00
2022-08-01 05:34:23 +00:00
**State**
2022-07-26 19:24:43 +00:00
Arrays of arrays are the simplest data structure for representing worksheets.
```js
var aoa = [
[1, 2], // A1 = 1, B1 = 2
[3, 4] // A1 = 3, B1 = 4
];
```
`ko.observableArray` should be used to create the view model:
```js
function ViewModel() {
/* use an array of arrays */
this.aoa = ko.observableArray([ [1,2], [3,4] ]);
}
/* create model */
var model = new ViewModel();
ko.applyBindings(model);
```
`XLSX.utils.sheet_to_json` with `header: 1` generates data for the model:
```js
/* starting from a `wb` workbook object, pull first worksheet */
var ws = wb.Sheets[wb.SheetNames[0]];
/* convert the worksheet to an array of arrays */
var aoa = XLSX.utils.sheet_to_json(ws, {header:1});
/* update model */
model.aoa(aoa);
```
`XLSX.utils.aoa_to_sheet` generates worksheets from the model:
```js
var aoa = model.aoa();
var ws = XLSX.utils.aoa_to_sheet(aoa);
```
2022-08-01 05:34:23 +00:00
**Data Binding**
2022-07-26 19:24:43 +00:00
`data-bind="foreach: ..."` provides a simple approach for binding to `TABLE` :
```html
< table data-bind = "foreach: aoa" >
< tr data-bind = "foreach: $data" >
< td > < span data-bind = "text: $data" > < / span > < / td >
< / tr >
< / table >
```
Unfortunately the nested `"foreach: $data"` binding is read-only. A two-way
binding is possible using the `$parent` and `$index` binding context properties:
```html
< table data-bind = "foreach: aoa" >
< tr data-bind = "foreach: $data" >
< td > < input data-bind = "value: $parent[$index()]" / > < / td >
< / tr >
< / table >
```
2022-08-01 05:34:23 +00:00
2023-08-17 20:30:13 +00:00
< / details >
[^1]: Project hosted at < https: / / github . com / dcneiner / Downloadify >
[^2]: All Dojo Toolkit releases are available at < https: // download . dojotoolkit . org /> . The mirrored `dojo.js` corresponds to the `1.17.3` uncompressed script < http: // download . dojotoolkit . org / release-1 . 17 . 3 / dojo . js . uncompressed . js > .