forked from sheetjs/sheetjs
XLSX custprops strip ns [ci skip]
This commit is contained in:
parent
838ee58a49
commit
917a69e394
@ -5,7 +5,7 @@ function parse_cust_props(data/*:string*/, opts) {
|
||||
var m = data.match(custregex);
|
||||
if(m) for(var i = 0; i != m.length; ++i) {
|
||||
var x = m[i], y = parsexmltag(x);
|
||||
switch(y[0]) {
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<?xml': break;
|
||||
case '<Properties': break;
|
||||
case '<property': name = unescapexml(y.name); break;
|
||||
|
@ -18,57 +18,60 @@ can be installed with Bash on Windows or with `cygwin`.
|
||||
### Included Demos
|
||||
|
||||
**JavaScript APIs**
|
||||
- [`XMLHttpRequest and fetch`](https://docs.sheetjs.com/docs/getting-started/demos/network)
|
||||
- [`Clipboard Data`](https://docs.sheetjs.com/docs/getting-started/demos/clipboard)
|
||||
- [`Typed Arrays for Machine Learning`](https://docs.sheetjs.com/docs/getting-started/demos/ml)
|
||||
- [`LocalStorage and SessionStorage`](https://docs.sheetjs.com/docs/getting-started/demos/database#localstorage-and-sessionstorage)
|
||||
- [`Web SQL Database`](https://docs.sheetjs.com/docs/getting-started/demos/database#websql)
|
||||
- [`IndexedDB`](https://docs.sheetjs.com/docs/getting-started/demos/database#indexeddb)
|
||||
- [`XMLHttpRequest and fetch`](https://docs.sheetjs.com/docs/demos/network)
|
||||
- [`Clipboard Data`](https://docs.sheetjs.com/docs/demos/clipboard)
|
||||
- [`Typed Arrays for Machine Learning`](https://docs.sheetjs.com/docs/demos/ml)
|
||||
- [`LocalStorage and SessionStorage`](https://docs.sheetjs.com/docs/demos/database#localstorage-and-sessionstorage)
|
||||
- [`Web SQL Database`](https://docs.sheetjs.com/docs/demos/database#websql)
|
||||
- [`IndexedDB`](https://docs.sheetjs.com/docs/demos/database#indexeddb)
|
||||
|
||||
**Frameworks**
|
||||
- [`Angular.JS`](https://docs.sheetjs.com/docs/getting-started/demos/legacy#angularjs)
|
||||
- [`Angular.JS`](https://docs.sheetjs.com/docs/demos/legacy#angularjs)
|
||||
- [`Angular 2+ and Ionic`](angular2/)
|
||||
- [`Knockout`](https://docs.sheetjs.com/docs/getting-started/demos/legacy#knockoutjs)
|
||||
- [`React, React Native and NextJS`](react/)
|
||||
- [`VueJS, WeeX and NuxtJS`](vue/)
|
||||
- [`Knockout`](https://docs.sheetjs.com/docs/demos/legacy#knockoutjs)
|
||||
- [`React and NextJS`](react/)
|
||||
- [`VueJS`](vue/)
|
||||
|
||||
**Front-End UI Components**
|
||||
- [`canvas-datagrid`](https://docs.sheetjs.com/docs/getting-started/demos/grid#canvas-datagrid)
|
||||
- [`canvas-datagrid`](https://docs.sheetjs.com/docs/demos/grid#canvas-datagrid)
|
||||
- [`x-spreadsheet`](xspreadsheet/)
|
||||
- [`react-data-grid`](react/modify/)
|
||||
- [`vue3-table-light`](vue/modify/)
|
||||
- [`angular-ui-grid`](https://docs.sheetjs.com/docs/getting-started/demos/grid#angular-ui-grid)
|
||||
- [`angular-ui-grid`](https://docs.sheetjs.com/docs/demos/grid#angular-ui-grid)
|
||||
|
||||
**Platforms and Integrations**
|
||||
- [`Command-Line Tools`](https://docs.sheetjs.com/docs/getting-started/demos/cli)
|
||||
- [`Command-Line Tools`](https://docs.sheetjs.com/docs/demos/cli)
|
||||
- [`iOS and Android Mobile Applications`](https://docs.sheetjs.com/docs/demos/mobile)
|
||||
- [`NodeJS Server-Side Processing`](server/)
|
||||
- [`Electron`](https://docs.sheetjs.com/docs/getting-started/demos/desktop#electron)
|
||||
- [`NW.js`](https://docs.sheetjs.com/docs/getting-started/demos/desktop#nwjs)
|
||||
- [`Chrome / Chromium Extension`](https://docs.sheetjs.com/docs/getting-started/demos/chromium)
|
||||
- [`Google Sheets API`](https://docs.sheetjs.com/docs/getting-started/demos/gsheet)
|
||||
- [`ExtendScript for Adobe Apps`](https://docs.sheetjs.com/docs/getting-started/demos/extendscript)
|
||||
- [`NetSuite SuiteScript`](https://docs.sheetjs.com/docs/getting-started/demos/netsuite)
|
||||
- [`SalesForce Lightning Web Components`](https://docs.sheetjs.com/docs/getting-started/demos/salesforce)
|
||||
- [`Excel JavaScript API`](https://docs.sheetjs.com/docs/getting-started/demos/excel)
|
||||
- [`Headless Automation`](https://docs.sheetjs.com/docs/getting-started/demos/headless)
|
||||
- [`Swift JSC and Other JavaScript Engines`](https://docs.sheetjs.com/docs/getting-started/demos/engines)
|
||||
- [`Content Management and Static Sites`](https://docs.sheetjs.com/docs/demos/content)
|
||||
- [`Electron`](https://docs.sheetjs.com/docs/demos/desktop#electron)
|
||||
- [`NW.js`](https://docs.sheetjs.com/docs/demos/desktop#nwjs)
|
||||
- [`Tauri`](https://docs.sheetjs.com/docs/demos/desktop#tauri)
|
||||
- [`Chrome and Chromium Extensions`](https://docs.sheetjs.com/docs/demos/chromium)
|
||||
- [`Google Sheets API`](https://docs.sheetjs.com/docs/demos/gsheet)
|
||||
- [`ExtendScript for Adobe Apps`](https://docs.sheetjs.com/docs/demos/extendscript)
|
||||
- [`NetSuite SuiteScript`](https://docs.sheetjs.com/docs/demos/netsuite)
|
||||
- [`SalesForce Lightning Web Components`](https://docs.sheetjs.com/docs/demos/salesforce)
|
||||
- [`Excel JavaScript API`](https://docs.sheetjs.com/docs/demos/excel)
|
||||
- [`Headless Automation`](https://docs.sheetjs.com/docs/demos/headless)
|
||||
- [`Swift JSC and Other JavaScript Engines`](https://docs.sheetjs.com/docs/demos/engines)
|
||||
- [`"serverless" functions`](function/)
|
||||
- [`Databases and Structured Data Stores`](https://docs.sheetjs.com/docs/getting-started/demos/database)
|
||||
- [`NoSQL, K/V, and Unstructured Data Stores`](https://docs.sheetjs.com/docs/getting-started/demos/nosql)
|
||||
- [`Legacy Internet Explorer`](oldie/)
|
||||
- [`Databases and Structured Data Stores`](https://docs.sheetjs.com/docs/demos/database)
|
||||
- [`NoSQL and Unstructured Data Stores`](https://docs.sheetjs.com/docs/demos/nosql)
|
||||
- [`Legacy Internet Explorer`](https://docs.sheetjs.com/docs/demos/legacy#internet-explorer)
|
||||
|
||||
**Bundlers and Tooling**
|
||||
- [`browserify`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#browserify)
|
||||
- [`bun`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#bun)
|
||||
- [`esbuild`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#esbuild)
|
||||
- [`parcel`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#parcel)
|
||||
- [`requirejs`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#requirejs)
|
||||
- [`rollup`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#rollup)
|
||||
- [`snowpack`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#snowpack)
|
||||
- [`swc`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#swc)
|
||||
- [`systemjs`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#systemjs)
|
||||
- [`vite`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#vite)
|
||||
- [`webpack`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#webpack)
|
||||
- [`wmr`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#wmr)
|
||||
- [`browserify`](https://docs.sheetjs.com/docs/demos/bundler#browserify)
|
||||
- [`bun`](https://docs.sheetjs.com/docs/demos/bundler#bun)
|
||||
- [`esbuild`](https://docs.sheetjs.com/docs/demos/bundler#esbuild)
|
||||
- [`parcel`](https://docs.sheetjs.com/docs/demos/bundler#parcel)
|
||||
- [`requirejs`](https://docs.sheetjs.com/docs/demos/bundler#requirejs)
|
||||
- [`rollup`](https://docs.sheetjs.com/docs/demos/bundler#rollup)
|
||||
- [`snowpack`](https://docs.sheetjs.com/docs/demos/bundler#snowpack)
|
||||
- [`swc`](https://docs.sheetjs.com/docs/demos/bundler#swc)
|
||||
- [`systemjs`](https://docs.sheetjs.com/docs/demos/bundler#systemjs)
|
||||
- [`vite`](https://docs.sheetjs.com/docs/demos/bundler#vite)
|
||||
- [`webpack`](https://docs.sheetjs.com/docs/demos/bundler#webpack)
|
||||
- [`wmr`](https://docs.sheetjs.com/docs/demos/bundler#wmr)
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Other JS Engines and Deployments
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/engines)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/engines)
|
||||
includes more detailed instructions and more JS engines.
|
||||
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
The content has been reorganized;
|
||||
|
||||
- [The "Legacy Frameworks" section](https://docs.sheetjs.com/docs/getting-started/demos/legacy#angularjs)
|
||||
- [The "Legacy Frameworks" section](https://docs.sheetjs.com/docs/demos/legacy#angularjs)
|
||||
covers the AngularJS basics.
|
||||
- [The "Angular UI Grid" section](https://docs.sheetjs.com/docs/getting-started/demos/legacy#angularjs)
|
||||
- [The "Angular UI Grid" section](https://docs.sheetjs.com/docs/demos/legacy#angularjs)
|
||||
covers the integration with Angular UI Grid.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -32,14 +32,3 @@ ios browser: ionic
|
||||
android: ionic
|
||||
cd SheetJSIonic; ionic cordova prepare $@ </dev/null; ionic cordova emulate $@ </dev/null; cd -
|
||||
|
||||
|
||||
.PHONY: nativescript
|
||||
nativescript:
|
||||
bash ./nscript.sh
|
||||
|
||||
.PHONY: ns-ios ns-android
|
||||
ns-ios: nativescript
|
||||
cd SheetJSNS; ns run ios; cd -
|
||||
ns-android: nativescript
|
||||
cd SheetJSNS; ns run android; cd -
|
||||
|
||||
|
@ -101,24 +101,9 @@ $ npm install --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
|
||||
|
||||
The default angular-cli configuration requires no additional configuration.
|
||||
|
||||
Some deployments use the SystemJS loader, which does require configuration. The
|
||||
SystemJS example shows the required meta and map settings:
|
||||
|
||||
```js
|
||||
SystemJS.config({
|
||||
meta: {
|
||||
'xlsx': {
|
||||
exports: 'XLSX' // <-- tell SystemJS to expose the XLSX variable
|
||||
}
|
||||
},
|
||||
map: {
|
||||
'xlsx': 'xlsx.full.min.js', // <-- make sure xlsx.full.min.js is in same dir
|
||||
'fs': '', // <--|
|
||||
'crypto': '', // <--| suppress native node modules
|
||||
'stream': '' // <--|
|
||||
}
|
||||
});
|
||||
```
|
||||
Some deployments use the SystemJS loader, which does require configuration.
|
||||
[SystemJS](https://docs.sheetjs.com/docs/demos/bundler#systemjs)
|
||||
demo in the SheetJS CE docs describe the required settings.
|
||||
|
||||
## Ionic
|
||||
|
||||
@ -157,29 +142,7 @@ this.file.writeFile(url, filename, blob, {replace: true});
|
||||
|
||||
## NativeScript
|
||||
|
||||
Reproducing the full project is a little bit tricky. The included `nscript.sh`
|
||||
script performs the necessary installation steps and adds the necessary shims
|
||||
for `async` support. Due to incompatibilities with NativeScript and TypeScript
|
||||
definitions, apps should require the `xlsx.full.min.js` file directly:
|
||||
|
||||
```typescript
|
||||
const XLSX = require("./xlsx.full.min.js");
|
||||
```
|
||||
|
||||
The `ISO_8859_1` encoding from the text module specifies `"binary"` strings.
|
||||
`File#readText` and `File#writeText` reads and writes files:
|
||||
|
||||
```typescript
|
||||
/* read a workbook */
|
||||
const bstr: string = await file.readText(encoding.ISO_8859_1);
|
||||
const wb = XLSX.read(bstr, { type: "binary" });
|
||||
|
||||
/* write a workbook */
|
||||
const wbout: string = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
|
||||
await file.writeText(wbout, encoding.ISO_8859_1);
|
||||
```
|
||||
|
||||
Note: some versions of NativeScript do not properly support typed arrays or
|
||||
binary strings. See <https://github.com/NativeScript/NativeScript/issues/9586>
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/mobile#nativescript)
|
||||
is updated for NativeScript 8 and uses more idiomatic data patterns.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,10 +0,0 @@
|
||||
#!/bin/bash
|
||||
if [ ! -e SheetJSNS ]; then
|
||||
ns create SheetJSNS --ng
|
||||
cd SheetJSNS
|
||||
npm install --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
|
||||
cd ..
|
||||
fi
|
||||
|
||||
<../../dist/xlsx.full.min.js sed 's/require("fs")/null/g' > SheetJSNS/src/app/xlsx.full.min.js
|
||||
cp nscript.ts SheetJSNS/src/app/app.component.ts
|
@ -1,82 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { encoding } from '@nativescript/core/text';
|
||||
import { File, Folder, knownFolders, path } from '@nativescript/core/file-system';
|
||||
import { Dialogs } from '@nativescript/core';
|
||||
import { Page, GridLayout, WebView, DockLayout, Button } from '@nativescript/core';
|
||||
|
||||
import * as XLSX from './xlsx.full.min';
|
||||
|
||||
@Component({
|
||||
selector: 'ns-app',
|
||||
template: `
|
||||
<Page>
|
||||
<GridLayout rows="auto, *, auto">
|
||||
|
||||
<!-- data converted to HTML and rendered in web view -->
|
||||
<WebView row="1" src="{{html}}"></WebView>
|
||||
|
||||
<DockLayout row="2" dock="bottom" stretchLastChild="false">
|
||||
<Button text="Import File" (tap)="import()" style="padding: 10px"></Button>
|
||||
<Button text="Export File" (tap)="export()" style="padding: 10px"></Button>
|
||||
</DockLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
`
|
||||
})
|
||||
|
||||
export class AppComponent {
|
||||
html: string = "";
|
||||
constructor() {
|
||||
const ws = XLSX.utils.aoa_to_sheet([[1,2],[3,4]]);
|
||||
this.html = XLSX.utils.sheet_to_html(ws);
|
||||
};
|
||||
|
||||
/* Import button */
|
||||
async import() {
|
||||
const filename: string = "SheetJSNS.csv";
|
||||
|
||||
/* find appropriate path */
|
||||
const target: Folder = knownFolders.documents() || knownFolders.ios.sharedPublic();
|
||||
const url: string = path.normalize(target.path + "///" + filename);
|
||||
const file: File = File.fromPath(url);
|
||||
|
||||
try {
|
||||
/* get binary string */
|
||||
const bstr: string = await file.readText(encoding.ISO_8859_1);
|
||||
|
||||
/* read workbook */
|
||||
const wb = XLSX.read(bstr, { type: "binary" });
|
||||
|
||||
/* grab first sheet */
|
||||
const wsname: string = wb.SheetNames[0];
|
||||
const ws = wb.Sheets[wsname];
|
||||
|
||||
/* update table */
|
||||
this.html = XLSX.utils.sheet_to_html(ws);
|
||||
Dialogs.alert(`Attempting to read to ${filename} in ${url}`);
|
||||
} catch(e) {
|
||||
Dialogs.alert(e.message);
|
||||
}
|
||||
};
|
||||
|
||||
/* Export button */
|
||||
async export() {
|
||||
const wb = XLSX.read(this.html, { type: "string" });
|
||||
const filename: string = "SheetJSNS.csv";
|
||||
|
||||
/* generate binary string */
|
||||
const wbout: string = XLSX.write(wb, { bookType: 'csv', type: 'binary' });
|
||||
|
||||
/* find appropriate path */
|
||||
const target: Folder = knownFolders.documents() || knownFolders.ios.sharedPublic();
|
||||
const url: string = path.normalize(target.path + "///" + filename);
|
||||
const file: File = File.fromPath(url);
|
||||
|
||||
/* attempt to save binary string to file */
|
||||
await file.writeText(wbout, encoding.ISO_8859_1);
|
||||
Dialogs.alert(`Wrote to ${filename} in ${url}`);
|
||||
};
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
# Typed Arrays and Math
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/ml) includes
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/ml) includes
|
||||
interactive examples as well as strategies for CSV and JS Array interchange.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Browserify
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#browserify)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#browserify)
|
||||
includes a more concise example.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Chrome and Chromium
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/chromium)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/chromium)
|
||||
includes more up-to-date details.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
This demo has been split up for clarity:
|
||||
|
||||
- <https://docs.sheetjs.com/docs/getting-started/demos/database> covers SQL and
|
||||
- <https://docs.sheetjs.com/docs/demos/database> covers SQL and
|
||||
structured data (including CRUD operations)
|
||||
|
||||
- https://docs.sheetjs.com/docs/getting-started/demos/nosql covers unstructured
|
||||
- https://docs.sheetjs.com/docs/demos/nosql covers unstructured
|
||||
data including "NoSQL" data stores.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# canvas-datagrid
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/grid#canvas-datagrid)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/grid#canvas-datagrid)
|
||||
includes a live example and improved explanations.
|
||||
|
||||
|
||||
|
@ -8,6 +8,6 @@ Demos have been integrated in the [documentation](https://docs.sheetjs.com) :
|
||||
- <https://docs.sheetjs.com/docs/example> writing JS data to a spreadsheet
|
||||
- <https://docs.sheetjs.com/docs/solutions/input> input strategies
|
||||
- <https://docs.sheetjs.com/docs/solutions/output> output strategies
|
||||
- <https://docs.sheetjs.com/docs/getting-started/demos/cli#deno> `deno compile`
|
||||
- <https://docs.sheetjs.com/docs/demos/cli#deno> `deno compile`
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Electron
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/desktop#electron)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/desktop#electron)
|
||||
includes an improved example and detailed explanations.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Adobe ExtendScript
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/extendscript)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/extendscript)
|
||||
has a more focused Photoshop example as well as notes about other extensibility
|
||||
frameworks shipping with newer versions of Creative Cloud apps.
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
.PHONY: microcule
|
||||
microcule: mcstream.js
|
||||
microcule $<
|
||||
|
||||
.PHONY: aws
|
||||
aws: lambda-proxy
|
||||
|
||||
|
@ -43,32 +43,6 @@ var workbook = XLSX.readFile("path/to/file.xlsb");
|
||||
XLSX.writeFile(workbook, "output/path/file.csv");
|
||||
```
|
||||
|
||||
The `mcstream.js` demo uses the `microcule` framework to show a simple body
|
||||
converter. It accepts raw data from a POST connection, parses as a workbook,
|
||||
and streams back the first worksheet as CSV:
|
||||
|
||||
<details>
|
||||
<summary><b>Code Sketch</b> (click to show)</summary>
|
||||
|
||||
```js
|
||||
const XLSX = require('xlsx');
|
||||
|
||||
module.exports = (hook) => {
|
||||
/* process_RS from the main README under "Streaming Read" section */
|
||||
process_RS(hook.req, (wb) => {
|
||||
hook.res.writeHead(200, { 'Content-Type': 'text/csv' });
|
||||
/* get first worksheet */
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
/* generate CSV stream and pipe to response */
|
||||
const stream = XLSX.stream.to_csv(ws);
|
||||
stream.pipe(hook.res);
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
#### Report Generation
|
||||
|
||||
For an existing platform that already generates JSON or CSV or HTML output, the
|
||||
|
@ -1,22 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* eslint-env node */
|
||||
// cat file.xlsx | curl --header 'content-type: application/octet-stream' --data-binary @- "http://localhost:3000/"
|
||||
const XLSX = require('xlsx');
|
||||
|
||||
const process_RS = (stream, cb) => {
|
||||
var buffers = [];
|
||||
stream.on('data', function(data) { buffers.push(data); });
|
||||
stream.on('end', function() {
|
||||
var buffer = Buffer.concat(buffers);
|
||||
var workbook = XLSX.read(buffer, {type:"buffer"});
|
||||
cb(workbook);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = (hook) => {
|
||||
process_RS(hook.req, (wb) => {
|
||||
hook.res.writeHead(200, { 'Content-Type': 'text/csv' });
|
||||
const stream = XLSX.stream.to_csv(wb.Sheets[wb.SheetNames[0]]);
|
||||
stream.pipe(hook.res);
|
||||
});
|
||||
};
|
@ -3,7 +3,7 @@
|
||||
The old demo used a deprecated version of the Google Sheets API to export data
|
||||
from Google Sheets Documents.
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/gsheet) uses
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/gsheet) uses
|
||||
the new Google Sheets API to read and write data.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Headless Browsers
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/headless)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/headless)
|
||||
has a more focused table export example as well as a demo script for Chromium
|
||||
automation with Puppeteer and multi-browser automation with Playwright.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Knockout
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/legacy#knockoutjs)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/legacy#knockoutjs)
|
||||
includes a live example and improved explanations.
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# NW.js
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/desktop#nwjs)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/desktop#nwjs)
|
||||
includes an improved example and detailed explanations.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,156 +1,6 @@
|
||||
# Internet Explorer
|
||||
|
||||
The modern upload and download strategies are not available in older versions of
|
||||
IE, but there are approaches using older technologies like ActiveX and Flash.
|
||||
|
||||
<details>
|
||||
<summary><b>Live Demos</b> (click to show)</summary>
|
||||
|
||||
<http://oss.sheetjs.com/sheetjs/ajax.html> uses XMLHttpRequest to download test
|
||||
files and convert to CSV.
|
||||
|
||||
<https://oss.sheetjs.com/sheetjs/> demonstrates reading files with `FileReader`.
|
||||
|
||||
Older versions of IE do not support HTML5 File API but do support Base64.
|
||||
|
||||
On OSX you can get the Base64 encoding with:
|
||||
|
||||
```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 FileReader
|
||||
|
||||
IE10 and IE11 support the standard HTML5 FileReader API:
|
||||
|
||||
```js
|
||||
function handle_fr(e) {
|
||||
var files = e.target.files, f = files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
var data = new Uint8Array(e.target.result);
|
||||
var wb = XLSX.read(data, {type: 'array'});
|
||||
process_wb(wb);
|
||||
};
|
||||
reader.readAsArrayBuffer(f);
|
||||
}
|
||||
input_dom_element.addEventListener('change', handle_fr, false);
|
||||
```
|
||||
|
||||
#### ActiveX-based Upload
|
||||
|
||||
Through the `Scripting.FileSystemObject` object model, a script in the VBScript
|
||||
scripting language can read from an arbitrary path on the filesystem. The shim
|
||||
includes a special `IE_LoadFile` function to read binary strings from file. This
|
||||
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
|
||||
|
||||
#### IE10 and IE11 File API
|
||||
|
||||
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
|
||||
|
||||
It is possible to write to the file system using a SWF. `Downloadify` library
|
||||
implements one solution. Since a genuine click is required, there is no way to
|
||||
force a download. The demo generates a button for each desired output format.
|
||||
|
||||
#### ActiveX-based Download
|
||||
|
||||
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.
|
||||
|
||||
This approach can be triggered, but it requires the user to enable ActiveX. It
|
||||
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.
|
||||
|
||||
|
||||
## Demo
|
||||
|
||||
#### Download
|
||||
|
||||
The included demo starts from an array of arrays, generating an editable HTML
|
||||
table with `aoa_to_sheet` and adding it to the page:
|
||||
|
||||
```js
|
||||
var ws = XLSX.utils.aoa_to_sheet(aoa);
|
||||
var html_string = XLSX.utils.sheet_to_html(ws, { id: "table", editable: true });
|
||||
document.getElementById("container").innerHTML = html_string;
|
||||
```
|
||||
|
||||
The included download buttons use `table_to_book` to construct a new workbook
|
||||
based on the table and `writeFile` to force a download:
|
||||
|
||||
|
||||
```js
|
||||
var elt = document.getElementById('table');
|
||||
var wb = XLSX.utils.table_to_book(elt, { sheet: "Sheet JS" });
|
||||
XLSX.writeFile(wb, filename);
|
||||
```
|
||||
|
||||
The shim is included in the HTML page, unlocking the ActiveX pathway if enabled
|
||||
in browser settings.
|
||||
|
||||
The corresponding SWF buttons are displayed in environments where Flash is
|
||||
available and `Downloadify` is supported. The easiest solution involves writing
|
||||
to a Base64 string and passing to the library:
|
||||
|
||||
```js
|
||||
Downloadify.create(element_id, {
|
||||
/* the demo includes the other options required by Downloadify */
|
||||
filename: "test.xlsx",
|
||||
data: function() { return XLSX.write(wb, {bookType:"xlsx", type:'base64'}); },
|
||||
dataType: 'base64'
|
||||
});
|
||||
```
|
||||
|
||||
#### Upload
|
||||
|
||||
The demo also includes an HTML file input element for updating the data table:
|
||||
|
||||
```js
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
var html_string = XLSX.utils.sheet_to_html(ws, { id: "table", editable: true });
|
||||
document.getElementById("container").innerHTML = html_string;
|
||||
```
|
||||
|
||||
The specific strategy is determined based on the presence of `IE_LoadFile`:
|
||||
|
||||
```js
|
||||
var handler = typeof IE_LoadFile !== 'undefined' ? handle_ie : handle_fr;
|
||||
if(input_dom_element.attachEvent) input_dom_element.attachEvent('onchange', handler);
|
||||
else input_dom_element.addEventListener('change', handler, false);
|
||||
```
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/legacy#internet-explorer)
|
||||
includes a live example and easier integration bundle.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
1
demos/oldie/base64.min.js
vendored
1
demos/oldie/base64.min.js
vendored
@ -1 +0,0 @@
|
||||
!function(){function t(t){this.message=t}var r="undefined"!=typeof exports?exports:self,e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=new Error,t.prototype.name="InvalidCharacterError",r.btoa||(r.btoa=function(r){for(var o,n,a=String(r),i=0,c=e,d="";a.charAt(0|i)||(c="=",i%1);d+=c.charAt(63&o>>8-i%1*8)){if(n=a.charCodeAt(i+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return d}),r.atob||(r.atob=function(r){var o=String(r).replace(/=+$/,"");if(o.length%4==1)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,a,i=0,c=0,d="";a=o.charAt(c++);~a&&(n=i%4?64*n+a:a,i++%4)?d+=String.fromCharCode(255&n>>(-2*i&6)):0)a=e.indexOf(a);return d})}();
|
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB |
3
demos/oldie/downloadify.min.js
vendored
3
demos/oldie/downloadify.min.js
vendored
@ -1,3 +0,0 @@
|
||||
/* Downloadify 0.2 (c) 2009 by Douglas Neiner. Licensed under the MIT license */
|
||||
/* See http://github.com/dcneiner/Downloadify for license and more info */
|
||||
(function(){Downloadify=window.Downloadify={queue:{},uid:new Date().getTime(),getTextForSave:function(a){var b=Downloadify.queue[a];if(b)return b.getData();return""},getFileNameForSave:function(a){var b=Downloadify.queue[a];if(b)return b.getFilename();return""},getDataTypeForSave:function(a){var b=Downloadify.queue[a];if(b)return b.getDataType();return""},saveComplete:function(a){var b=Downloadify.queue[a];if(b)b.complete();return true},saveCancel:function(a){var b=Downloadify.queue[a];if(b)b.cancel();return true},saveError:function(a){var b=Downloadify.queue[a];if(b)b.error();return true},addToQueue:function(a){Downloadify.queue[a.queue_name]=a},getUID:function(a){if(a.id=="")a.id='downloadify_'+Downloadify.uid++;return a.id}};Downloadify.create=function(a,b){var c=(typeof(a)=="string"?document.getElementById(a):a);return new Downloadify.Container(c,b)};Downloadify.Container=function(d,e){var f=this;f.el=d;f.enabled=true;f.dataCallback=null;f.filenameCallback=null;f.data=null;f.filename=null;var g=function(){f.options=e;if(!f.options.append)f.el.innerHTML="";f.flashContainer=document.createElement('span');f.el.appendChild(f.flashContainer);f.queue_name=Downloadify.getUID(f.flashContainer);if(typeof(f.options.filename)==="function")f.filenameCallback=f.options.filename;else if(f.options.filename)f.filename=f.options.filename;if(typeof(f.options.data)==="function")f.dataCallback=f.options.data;else if(f.options.data)f.data=f.options.data;var a={queue_name:f.queue_name,width:f.options.width,height:f.options.height};var b={allowScriptAccess:'always'};var c={id:f.flashContainer.id,name:f.flashContainer.id};if(f.options.enabled===false)f.enabled=false;if(f.options.transparent===true)b.wmode="transparent";if(f.options.downloadImage)a.downloadImage=f.options.downloadImage;swfobject.embedSWF(f.options.swf,f.flashContainer.id,f.options.width,f.options.height,"10",null,a,b,c);Downloadify.addToQueue(f)};f.enable=function(){var a=document.getElementById(f.flashContainer.id);a.setEnabled(true);f.enabled=true};f.disable=function(){var a=document.getElementById(f.flashContainer.id);a.setEnabled(false);f.enabled=false};f.getData=function(){if(!f.enabled)return"";if(f.dataCallback)return f.dataCallback();else if(f.data)return f.data;else return""};f.getFilename=function(){if(f.filenameCallback)return f.filenameCallback();else if(f.filename)return f.filename;else return""};f.getDataType=function(){if(f.options.dataType)return f.options.dataType;return"string"};f.complete=function(){if(typeof(f.options.onComplete)==="function")f.options.onComplete()};f.cancel=function(){if(typeof(f.options.onCancel)==="function")f.options.onCancel()};f.error=function(){if(typeof(f.options.onError)==="function")f.options.onError()};g()};Downloadify.defaultOptions={swf:'media/downloadify.swf',downloadImage:'images/download.png',width:100,height:30,transparent:true,append:false,dataType:"string"}})();if(typeof(jQuery)!="undefined"){(function($){$.fn.downloadify=function(b){return this.each(function(){b=$.extend({},Downloadify.defaultOptions,b);var a=Downloadify.create(this,b);$(this).data('Downloadify',a)})}})(jQuery)};if(typeof(MooTools)!='undefined'){Element.implement({downloadify:function(a){a=$merge(Downloadify.defaultOptions,a);return this.store('Downloadify',Downloadify.create(this,a))}})};
|
Binary file not shown.
@ -1,152 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- (C) 2013-present SheetJS http://sheetjs.com -->
|
||||
<!-- vim: set ts=2: -->
|
||||
<html>
|
||||
<head>
|
||||
<title>SheetJS JS-XLSX In-Browser HTML Table Demo</title>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
.xport, .btn {
|
||||
display: inline;
|
||||
text-align:center;
|
||||
}
|
||||
a { text-decoration: none }
|
||||
#data-table, #data-table th, #data-table td { border: 1px solid black }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- SheetJS js-xlsx library -->
|
||||
<script type="text/javascript" src="shim.min.js"></script>
|
||||
<script type="text/javascript" src="xlsx.full.min.js"></script>
|
||||
|
||||
<!-- Downloadify Flash fallback for IE 9 and below if ActiveX is unavailable -->
|
||||
<!--[if lte IE 9]>
|
||||
<script type="text/javascript" src="swfobject.js"></script>
|
||||
<script type="text/javascript" src="downloadify.min.js"></script>
|
||||
<script type="text/javascript" src="base64.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script>
|
||||
function doit(type, fn, dl) {
|
||||
var elt = document.getElementById('data-table');
|
||||
var wb = XLSX.utils.table_to_book(elt, {sheet:"Sheet JS"});
|
||||
return dl ?
|
||||
XLSX.write(wb, {bookType:type, bookSST:true, type: 'base64'}) :
|
||||
XLSX.writeFile(wb, fn || ('test.' + (type || 'xlsx')));
|
||||
}
|
||||
</script>
|
||||
<pre>
|
||||
<h3><a href="//sheetjs.com/">SheetJS</a> JS-XLSX In-Browser HTML Table Demo</h3>
|
||||
<b>Compatibility notes:</b>
|
||||
- Editable table leverages the HTML5 contenteditable feature, supported in most browsers.
|
||||
- IE6-9 requires ActiveX to upload files and ActiveX or Flash to download files.
|
||||
- iOS Safari file download may not work. <a href="https://github.com/eligrey/FileSaver.js/issues/12">This is a known issue</a>.
|
||||
|
||||
<b>Update Spreadsheet:</b> (submit file to update table; file parsed in browser)
|
||||
<input type="file" id="file" />
|
||||
|
||||
<b>Editable Data Table:</b> (click a cell to edit it)
|
||||
</pre>
|
||||
<div id="container"></div>
|
||||
<script type="text/javascript">
|
||||
/* initial table */
|
||||
var aoa = [
|
||||
["This", "is", "a", "Test"],
|
||||
["வணக்கம்", "สวัสดี", "你好", "가지마"],
|
||||
[1, 2, 3, 4],
|
||||
["Click", "to", "edit", "cells"]
|
||||
];
|
||||
var ws = XLSX.utils.aoa_to_sheet(aoa);
|
||||
var html_string = XLSX.utils.sheet_to_html(ws, { id: "data-table", editable: true });
|
||||
document.getElementById("container").innerHTML = html_string;
|
||||
</script>
|
||||
<br />
|
||||
<pre><b>Export it!</b></pre>
|
||||
<table id="xport">
|
||||
<tr><td><pre>XLSX Excel 2007+ XML</pre></td><td>
|
||||
<p id="xportxlsx" class="xport"><input type="submit" value="Export to XLSX!" onclick="doit('xlsx');"></p>
|
||||
<p id="xlsxbtn" class="btn">Flash required for actually downloading the generated file.</p>
|
||||
</td></tr>
|
||||
<tr><td><pre>XLSB Excel 2007+ Binary</pre></td><td>
|
||||
<p id="xportxlsb" class="xport"><input type="submit" value="Export to XLSB!" onclick="doit('xlsb');"></p>
|
||||
<p id="xlsbbtn" class="btn">Flash required for actually downloading the generated file.</p>
|
||||
</td></tr>
|
||||
<tr><td><pre>XLS Excel 97-2004 Binary</pre></td><td>
|
||||
<p id="xportbiff8" class="xport"><input type="submit" value="Export to XLS!" onclick="doit('biff8', 'test.xls');"></p>
|
||||
<p id="biff8btn" class="btn">Flash required for actually downloading the generated file.</p>
|
||||
</td></tr>
|
||||
<tr><td><pre>ODS</pre></td><td>
|
||||
<p id="xportods" class="xport"><input type="submit" value="Export to ODS!" onclick="doit('ods');"></p>
|
||||
<p id="odsbtn" class="btn">Flash required for actually downloading the generated file.</p>
|
||||
</td></tr>
|
||||
<tr><td><pre>Flat ODS</pre></td><td>
|
||||
<p id="xportfods" class="xport"><input type="submit" value="Export to FODS!" onclick="doit('fods', 'test.fods');"></p>
|
||||
<p id="fodsbtn" class="btn">Flash required for actually downloading the generated file.</p>
|
||||
</td></tr>
|
||||
</table>
|
||||
<pre><b>Powered by the <a href="//sheetjs.com/opensource">community version of js-xlsx</a></b></pre>
|
||||
<script type="text/javascript">
|
||||
var input_dom_element = document.getElementById("file");
|
||||
function process_wb(wb) {
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
var html_string = XLSX.utils.sheet_to_html(ws, { id: "data-table", editable: true });
|
||||
document.getElementById("container").innerHTML = html_string;
|
||||
}
|
||||
function handle_ie() {
|
||||
var path = input_dom_element.value;
|
||||
var data = IE_LoadFile(path);
|
||||
var wb = XLSX.read(data, {type: 'binary'});
|
||||
process_wb(wb);
|
||||
}
|
||||
function handle_fr(e) {
|
||||
var files = e.target.files, f = files[0];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
var data = e.target.result;
|
||||
data = new Uint8Array(data);
|
||||
var wb = XLSX.read(data, {type: 'array'});
|
||||
process_wb(wb);
|
||||
};
|
||||
reader.readAsArrayBuffer(f);
|
||||
}
|
||||
var handler = typeof IE_LoadFile !== 'undefined' ? handle_ie : handle_fr;
|
||||
if(input_dom_element.attachEvent) input_dom_element.attachEvent('onchange', handler);
|
||||
else input_dom_element.addEventListener('change', handler, false);
|
||||
|
||||
function tableau(pid, iid, fmt, ofile) {
|
||||
if(typeof Downloadify !== 'undefined') Downloadify.create(pid,{
|
||||
swf: 'downloadify.swf',
|
||||
downloadImage: 'download.png',
|
||||
width: 100,
|
||||
height: 30,
|
||||
filename: ofile, data: function() { return doit(fmt, ofile, true); },
|
||||
transparent: false,
|
||||
append: false,
|
||||
dataType: 'base64',
|
||||
onComplete: function(){ alert('Your File Has Been Saved!'); },
|
||||
onCancel: function(){ alert('You have cancelled the saving of this file.'); },
|
||||
onError: function(){ alert('You must put something in the File Contents or there will be nothing to save!'); }
|
||||
}); else document.getElementById(pid).innerHTML = "";
|
||||
}
|
||||
tableau('biff8btn', 'xportbiff8', 'biff8', 'test.xls');
|
||||
tableau('odsbtn', 'xportods', 'ods', 'test.ods');
|
||||
tableau('fodsbtn', 'xportfods', 'fods', 'test.fods');
|
||||
tableau('xlsbbtn', 'xportxlsb', 'xlsb', 'test.xlsb');
|
||||
tableau('xlsxbtn', 'xportxlsx', 'xlsx', 'test.xlsx');
|
||||
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
|
||||
_gaq.push(['_setDomainName', 'sheetjs.com']);
|
||||
_gaq.push(['_setAllowLinker', true]);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1
demos/oldie/shim.min.js
vendored
1
demos/oldie/shim.min.js
vendored
@ -1 +0,0 @@
|
||||
../../dist/shim.min.js
|
File diff suppressed because one or more lines are too long
1
demos/oldie/xlsx.full.min.js
vendored
1
demos/oldie/xlsx.full.min.js
vendored
@ -1 +0,0 @@
|
||||
../../dist/xlsx.full.min.js
|
@ -1,6 +1,6 @@
|
||||
# Parcel
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#parcel)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#parcel)
|
||||
includes a more concise example.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -74,33 +74,8 @@ function make_cols(refstr/*:string*/) {
|
||||
|
||||
## React Native
|
||||
|
||||
<img src="screen.png" width="400px"/>
|
||||
|
||||
Reproducing the full project is straightforward:
|
||||
|
||||
```bash
|
||||
$ make native # build the project
|
||||
$ make ios # build and run the iOS demo
|
||||
$ make android # build and run the android demo
|
||||
```
|
||||
|
||||
The app will prompt before reading and after writing data. The printed location
|
||||
depends on the environment:
|
||||
|
||||
- android: path in the device filesystem
|
||||
- iOS simulator: local path to file
|
||||
- iOS device: a path accessible from iTunes App Documents view
|
||||
|
||||
Components used in the demo:
|
||||
- [`react-native-table-component`](https://npm.im/react-native-table-component)
|
||||
- [`react-native-file-access`](https://npm.im/react-native-file-access)
|
||||
|
||||
React Native does not provide a native component for reading and writing files.
|
||||
The sample script `react-native.js` uses `react-native-file-access` and has
|
||||
notes for integrations with `react-native-fetch-blob` and `react-native-fs`.
|
||||
|
||||
Note: for real app deployments, the `UIFileSharingEnabled` flag must be manually
|
||||
set in the iOS project `Info.plist` file.
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/mobile#react-native) uses
|
||||
up-to-date file I/O and file picker libraries.
|
||||
|
||||
## Server-Rendered React Components with Next.js
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
# xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
|
||||
# Create starter project
|
||||
if [ ! -e SheetJS ]; then react-native init SheetJS --version="0.67.2"; fi
|
||||
|
||||
# Install dependencies
|
||||
cd SheetJS; npm i -S https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz react-native-table-component; cd -
|
||||
|
||||
cd SheetJS; npm i -S react-native-file-access@2.x; cd -
|
||||
# cd SheetJS; npm i -S react-native-fs; cd -
|
||||
# cd SheetJS; npm i -S react-native-fetch-blob; cd -
|
||||
|
||||
# Copy demo assets
|
||||
if [ ! -e SheetJS/logo.png ]; then
|
||||
curl -O http://oss.sheetjs.com/assets/img/logo.png
|
||||
mv logo.png SheetJS/logo.png
|
||||
fi
|
||||
if [ -e SheetJS/index.ios.js ]; then
|
||||
cp react-native.js SheetJS/index.ios.js
|
||||
cp react-native.js SheetJS/index.android.js
|
||||
else
|
||||
cp react-native.js SheetJS/index.js
|
||||
fi
|
||||
|
||||
# Link
|
||||
cd SheetJS; RNFB_ANDROID_PERMISSIONS=true react-native link; cd -
|
179
demos/react/react-native.js
vendored
179
demos/react/react-native.js
vendored
@ -1,179 +0,0 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
import * as XLSX from 'xlsx';
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View,
|
||||
Button,
|
||||
Alert,
|
||||
Image,
|
||||
ScrollView,
|
||||
TouchableWithoutFeedback
|
||||
} from 'react-native';
|
||||
import { Table, Row, Rows, TableWrapper } from 'react-native-table-component';
|
||||
|
||||
// react-native-file-access
|
||||
var Base64 = function() {
|
||||
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
return {
|
||||
encode: function(input) {
|
||||
var o = "";
|
||||
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
||||
for (var i = 0; i < input.length; ) {
|
||||
c1 = input.charCodeAt(i++);
|
||||
e1 = c1 >> 2;
|
||||
c2 = input.charCodeAt(i++);
|
||||
e2 = (c1 & 3) << 4 | c2 >> 4;
|
||||
c3 = input.charCodeAt(i++);
|
||||
e3 = (c2 & 15) << 2 | c3 >> 6;
|
||||
e4 = c3 & 63;
|
||||
if (isNaN(c2)) {
|
||||
e3 = e4 = 64;
|
||||
} else if (isNaN(c3)) {
|
||||
e4 = 64;
|
||||
}
|
||||
o += map.charAt(e1) + map.charAt(e2) + map.charAt(e3) + map.charAt(e4);
|
||||
}
|
||||
return o;
|
||||
},
|
||||
decode: function(input) {
|
||||
var o = "";
|
||||
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
||||
input = input.replace(/[^\w\+\/\=]/g, "");
|
||||
for (var i = 0; i < input.length; ) {
|
||||
e1 = map.indexOf(input.charAt(i++));
|
||||
e2 = map.indexOf(input.charAt(i++));
|
||||
c1 = e1 << 2 | e2 >> 4;
|
||||
o += String.fromCharCode(c1);
|
||||
e3 = map.indexOf(input.charAt(i++));
|
||||
c2 = (e2 & 15) << 4 | e3 >> 2;
|
||||
if (e3 !== 64) {
|
||||
o += String.fromCharCode(c2);
|
||||
}
|
||||
e4 = map.indexOf(input.charAt(i++));
|
||||
c3 = (e3 & 3) << 6 | e4;
|
||||
if (e4 !== 64) {
|
||||
o += String.fromCharCode(c3);
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
import { Dirs, FileSystem } from 'react-native-file-access';
|
||||
const DDP = Dirs.DocumentDir + "/";
|
||||
const readFile = (path, enc) => FileSystem.readFile(path, "base64");
|
||||
const writeFile = (path, data, enc) => FileSystem.writeFile(path, data, "base64");
|
||||
const input = res => Base64.decode(res);
|
||||
const output = str => Base64.encode(str);
|
||||
|
||||
// react-native-fs
|
||||
/*
|
||||
import { writeFile, readFile, DocumentDirectoryPath } from 'react-native-fs';
|
||||
const DDP = DocumentDirectoryPath + "/";
|
||||
const input = res => res;
|
||||
const output = str => str;
|
||||
*/
|
||||
// react-native-fetch-blob
|
||||
/*
|
||||
import RNFetchBlob from 'react-native-fetch-blob';
|
||||
const { writeFile, readFile, dirs:{ DocumentDir } } = RNFetchBlob.fs;
|
||||
const DDP = DocumentDir + "/";
|
||||
const input = res => res.map(x => String.fromCharCode(x)).join("");
|
||||
const output = str => str.split("").map(x => x.charCodeAt(0));
|
||||
*/
|
||||
|
||||
const make_cols = refstr => Array.from({length: XLSX.utils.decode_range(refstr).e.c + 1}, (x,i) => XLSX.utils.encode_col(i));
|
||||
const make_width = refstr => Array.from({length: XLSX.utils.decode_range(refstr).e.c + 1}, () => 60);
|
||||
|
||||
export default class SheetJS extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: [[2,3,4],[3,4,5]],
|
||||
widthArr: [60, 60, 60],
|
||||
cols: make_cols("A1:C2")
|
||||
};
|
||||
this.importFile = this.importFile.bind(this);
|
||||
this.exportFile = this.exportFile.bind(this);
|
||||
};
|
||||
importFile() {
|
||||
Alert.alert("Rename file to sheetjs.xlsx", "Copy to " + DDP, [
|
||||
{text: 'Cancel', onPress: () => {}, style: 'cancel' },
|
||||
{text: 'Import', onPress: () => {
|
||||
readFile(DDP + "sheetjs.xlsx", 'ascii').then((res) => {
|
||||
/* parse file */
|
||||
const wb = XLSX.read(input(res), {type:'binary'});
|
||||
|
||||
/* convert first worksheet to AOA */
|
||||
const wsname = wb.SheetNames[0];
|
||||
const ws = wb.Sheets[wsname];
|
||||
const data = XLSX.utils.sheet_to_json(ws, {header:1});
|
||||
|
||||
/* update state */
|
||||
this.setState({ data: data, cols: make_cols(ws['!ref']), widthArr: make_width(ws['!ref']) });
|
||||
}).catch((err) => { Alert.alert("importFile Error", "Error " + err.message); });
|
||||
}}
|
||||
]);
|
||||
}
|
||||
exportFile() {
|
||||
/* convert AOA back to worksheet */
|
||||
const ws = XLSX.utils.aoa_to_sheet(this.state.data);
|
||||
|
||||
/* build new workbook */
|
||||
const wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
|
||||
|
||||
/* write file */
|
||||
const wbout = XLSX.write(wb, {type:'binary', bookType:"xlsx"});
|
||||
const file = DDP + "sheetjsw.xlsx";
|
||||
writeFile(file, output(wbout), 'ascii').then((res) =>{
|
||||
Alert.alert("exportFile success", "Exported to " + file);
|
||||
}).catch((err) => { Alert.alert("exportFile Error", "Error " + err.message); });
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ScrollView contentContainerStyle={styles.container} vertical={true}>
|
||||
<Text style={styles.welcome}> </Text>
|
||||
<Text style={styles.welcome}>SheetJS React Native Demo</Text>
|
||||
<Text style={styles.instructions}>Import Data</Text>
|
||||
<Button onPress={this.importFile} title="Import data from a spreadsheet" color="#841584" />
|
||||
<Text style={styles.instructions}>Export Data</Text>
|
||||
<Button disabled={!this.state.data.length} onPress={this.exportFile} title="Export data to XLSX" color="#841584" />
|
||||
|
||||
<Text style={styles.instructions}>Current Data</Text>
|
||||
|
||||
<ScrollView style={styles.table} horizontal={true} >
|
||||
<Table style={styles.table}>
|
||||
<TableWrapper>
|
||||
<Row data={this.state.cols} style={styles.thead} textStyle={styles.text} widthArr={this.state.widthArr}/>
|
||||
</TableWrapper>
|
||||
<TouchableWithoutFeedback>
|
||||
<ScrollView vertical={true}>
|
||||
<TableWrapper>
|
||||
<Rows data={this.state.data} style={styles.tr} textStyle={styles.text} widthArr={this.state.widthArr}/>
|
||||
</TableWrapper>
|
||||
</ScrollView>
|
||||
</TouchableWithoutFeedback>
|
||||
</Table>
|
||||
</ScrollView>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF' },
|
||||
welcome: { fontSize: 20, textAlign: 'center', margin: 10 },
|
||||
instructions: { textAlign: 'center', color: '#333333', marginBottom: 5 },
|
||||
thead: { height: 40, backgroundColor: '#f1f8ff' },
|
||||
tr: { height: 30 },
|
||||
text: { marginLeft: 5 },
|
||||
table: { width: "100%" }
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('SheetJS', () => SheetJS);
|
Binary file not shown.
Before Width: | Height: | Size: 68 KiB |
@ -1,6 +1,6 @@
|
||||
# RequireJS
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#requirejs)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#requirejs)
|
||||
includes a live example and improved explanations.
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Rollup
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#rollup)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#rollup)
|
||||
includes a simple example and improved explanations.
|
||||
|
||||
|
||||
|
2
demos/systemjs/.gitignore
vendored
2
demos/systemjs/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
systemjs/
|
||||
xlsx.full.min.js
|
@ -1,6 +1,6 @@
|
||||
# SystemJS Demos
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#systemjs)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#systemjs)
|
||||
includes a live example and improved explanations.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
2
demos/vue/.gitignore
vendored
2
demos/vue/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
SheetJS
|
||||
.nuxt
|
@ -1,16 +1,3 @@
|
||||
.PHONY: vue
|
||||
vue: ## Simple server for vue
|
||||
python -mSimpleHTTPServer
|
||||
|
||||
.PHONY: nuxt
|
||||
nuxt: ## nuxt.js demo
|
||||
npm i https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz @nuxt/content
|
||||
npx nuxt
|
||||
|
||||
.PHONY: weex
|
||||
weex: ## Build weex project
|
||||
bash ./weex.sh
|
||||
|
||||
.PHONY: ios
|
||||
ios: weex ## weex ios sim
|
||||
cd SheetJS; weexpack run ios; cd -
|
||||
python -mSimpleHTTPServer || python3 -mhttp.server
|
||||
|
@ -70,57 +70,14 @@ function make_cols(refstr/*:string*/) {
|
||||
}
|
||||
```
|
||||
|
||||
## WeeX
|
||||
## Mobile Apps
|
||||
|
||||
<img src="screen.png" width="400px"/>
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/mobile#quasar) uses the
|
||||
Quasar Framework in a VueJS + Vite project to generate a native iOS app.
|
||||
|
||||
Reproducing the full project is a little bit tricky. The included `weex.sh`
|
||||
script performs the necessary installation steps.
|
||||
## Nuxt Content
|
||||
|
||||
WeeX is a framework for building real mobile apps, akin to React Native. The
|
||||
ecosystem is not quite as mature as React Native, missing basic features like
|
||||
document access. As a result, this demo uses the `stream.fetch` API to upload
|
||||
Base64-encoded documents to <https://hastebin.com> and download a precomputed
|
||||
[Base64-encoded workbook](http://sheetjs.com/sheetjs.xlsx.b64).
|
||||
|
||||
Using NodeJS it is straightforward to convert to/from Base64:
|
||||
|
||||
```js
|
||||
/* convert sheetjs.xlsx -> sheetjs.xlsx.b64 */
|
||||
var buf = fs.readFileSync("sheetjs.xlsx");
|
||||
fs.writeFileSync("sheetjs.xlsx.b64", buf.toString("base64"));
|
||||
|
||||
/* convert sheetjs.xls.b64 -> sheetjs.xls */
|
||||
var str = fs.readFileSync("sheetjs.xls.b64").toString();
|
||||
fs.writeFileSync("sheetjs.xls", new Buffer(str, "base64"));
|
||||
```
|
||||
|
||||
## Other Demos
|
||||
|
||||
### Nuxt Content
|
||||
|
||||
`@nuxt/content` parser can be extended to support spreadsheet hot reload:
|
||||
|
||||
```js
|
||||
// nuxt.config.js
|
||||
import { readFile, utils } from 'xlsx';
|
||||
|
||||
const parseXLSX = (file, { path }) => {
|
||||
const wb = readFile(path);
|
||||
const o = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])}));
|
||||
return { data: o };
|
||||
}
|
||||
|
||||
export default {
|
||||
content: {
|
||||
extendParser: {
|
||||
".numbers": parseXLSX,
|
||||
".xlsx": parseXLSX,
|
||||
".xls": parseXLSX
|
||||
// ... other extensions
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/content#nuxtjs) includes a
|
||||
complete example starting from `create-nuxt-app`.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
Binary file not shown.
@ -25,7 +25,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<pre>
|
||||
<b><a href="http://sheetjs.com">SheetJS + VueJS2 demo</a></b>
|
||||
<b><a href="http://sheetjs.com">SheetJS + VueJS3 demo</a></b>
|
||||
|
||||
The core library can be used as-is in Vue applications.
|
||||
The <a href="https://github.com/sheetjs/js-xlsx">Community Edition README</a> details some common use cases.
|
||||
|
@ -1,66 +0,0 @@
|
||||
<!-- xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com -->
|
||||
<template>
|
||||
<div class="container">
|
||||
<image :src="logoUrl" class="logo"></image>
|
||||
<text class="welcome">SheetJS WeeX Demo {{version}}</text>
|
||||
<text class="instructions">Import Data</text>
|
||||
<text :style="{ color: '#841584' }" @click="importFile">Download spreadsheet</text>
|
||||
<text class="instructions">Export Data</text>
|
||||
<text :style="{ color: data.length ? '#841584' : '#CDCDCD', disabled: !data.length }" @click="exportFile">Upload XLSX</text>
|
||||
<text style="instructions">Current Data</text>
|
||||
<scroller class="scroller">
|
||||
<div class="row" v-for="(row, ridx) in data" :key="ridx">
|
||||
<text>ROW {{ridx + 1}}</text>
|
||||
<text v-for="(cell, cidx) in row" :key="cidx">CELL {{get_label(ridx, cidx)}}:{{cell}}</text>
|
||||
</div>
|
||||
</scroller>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.container { height: 100%; flex: 1; justify-content: center; align-items: center; background-color: '#F5FCFF'; }
|
||||
.logo { width: 256px; height: 256px; }
|
||||
.welcome { font-size: 40; text-align: 'center'; margin: 10; }
|
||||
.instructions { padding-top: 20px; color:#888; font-size: 24px;}
|
||||
.scroller { height: 500px; border-width: 3px; width: 700px; }
|
||||
.loading { justify-content: center; }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import * as XLSX from 'xlsx';
|
||||
const modal = weex.requireModule('modal');
|
||||
const stream = weex.requireModule('stream');
|
||||
export default {
|
||||
data: {
|
||||
data: [[1,2,3],[4,5,6]],
|
||||
logoUrl: 'http://oss.sheetjs.com/assets/img/logo.png',
|
||||
version: XLSX.version,
|
||||
fileUrl: 'http://sheetjs.com/sheetjs.xlsx.b64',
|
||||
binUrl: 'https://hastebin.com/documents'
|
||||
},
|
||||
methods: {
|
||||
importFile: function (e) {
|
||||
modal.toast({ message: 'getting ' + this.fileUrl, duration: 1 });
|
||||
var self = this;
|
||||
stream.fetch({method:'GET', type:'text', url:this.fileUrl}, function(res){
|
||||
const wb = XLSX.read(res.data, {type:'base64'});
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
self.data = XLSX.utils.sheet_to_json(ws, {header:1});
|
||||
});
|
||||
},
|
||||
exportFile: function (e) {
|
||||
var self = this;
|
||||
const ws = XLSX.utils.aoa_to_sheet(this.data);
|
||||
const wb = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
|
||||
const wbout = XLSX.write(wb, {type:"base64", bookType:"xlsx"});
|
||||
const body = wbout;
|
||||
stream.fetch({method:'POST', type:'json', url:this.binUrl, body:body}, function(res) {
|
||||
modal.toast({ message: 'KEY: ' + res.data.key, duration: 10 });
|
||||
self.version = res.data.key;
|
||||
});
|
||||
},
|
||||
get_label: function(r, c) { return XLSX.utils.encode_cell({r:r, c:c})}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,20 +0,0 @@
|
||||
// nuxt.config.js
|
||||
import { readFile, utils } from 'xlsx';
|
||||
|
||||
const parseXLSX = (file, { path }) => {
|
||||
const wb = readFile(path);
|
||||
const o = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])}));
|
||||
return { data: o };
|
||||
}
|
||||
|
||||
export default {
|
||||
modules: [ '@nuxt/content' ],
|
||||
content: {
|
||||
extendParser: {
|
||||
".numbers": parseXLSX,
|
||||
".xlsx": parseXLSX,
|
||||
".xls": parseXLSX
|
||||
// ...
|
||||
}
|
||||
},
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@nuxt/content": "1.15.1",
|
||||
"nuxt": "2.15.8",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz"
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
<!-- xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com -->
|
||||
<template>
|
||||
<div>
|
||||
<div v-for="item in data.data" v-bind:key="item.name">
|
||||
<h2>{{ item.name }}</h2>
|
||||
<table>
|
||||
<tr v-for="row in item.data" v-bind:key="row.Index">
|
||||
<td>{{ row.Name }}</td>
|
||||
<td>{{ row.Index }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
async asyncData ({$content}) {
|
||||
return {
|
||||
data: await $content('sheetjs').fetch()
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
Binary file not shown.
Before Width: | Height: | Size: 97 KiB |
@ -1 +0,0 @@
|
||||
../shim.js
|
1
demos/vue/static/xlsx.full.min.js
vendored
1
demos/vue/static/xlsx.full.min.js
vendored
@ -1 +0,0 @@
|
||||
../xlsx.full.min.js
|
@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! -e SheetJS ]; then
|
||||
weexpack create SheetJS
|
||||
cd SheetJS
|
||||
npm install
|
||||
weexpack platform add ios
|
||||
# see https://github.com/weexteam/weex-pack/issues/133#issuecomment-295806132
|
||||
sed -i.bak 's/ATSDK-Weex/ATSDK/g' platforms/ios/Podfile
|
||||
cd -
|
||||
fi
|
||||
cp native.vue SheetJS/src/index.vue
|
||||
if [ ! -e SheetJS/web/bootstrap.min.css ]; then
|
||||
curl -O https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css
|
||||
mv bootstrap.min.css SheetJS/web/
|
||||
fi
|
@ -1,6 +1,6 @@
|
||||
# Webpack
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#webpack)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/bundler#webpack)
|
||||
reflects the new default behavior to use the ESM build.
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# XMLHttpRequest and fetch
|
||||
|
||||
[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/network)
|
||||
[The new demo](https://docs.sheetjs.com/docs/demos/network)
|
||||
includes interactive demos and improved explanations.
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user