This commit is contained in:
SheetJS 2022-08-18 22:26:17 -04:00
parent 2d5f8ebce4
commit 913538b2ed
50 changed files with 2096 additions and 41 deletions

@ -13,8 +13,7 @@ import current from '/version.js';
:::caution Bun support is considered experimental.
Great open source software grows with user tests and reports. Any issues should
be reported to the [SheetJS project](https://github.com/SheetJS/sheetjs/issues)
for further diagnosis.
be reported to the Bun project for further diagnosis.
:::

@ -570,7 +570,7 @@ can be adapted to generate SQL statements for a variety of databases, including:
**PostgreSQL**
The `pg` connector library was tested against the `generate_sql` output as-is.
The `pg` connector library was tested against the `generate_sql` output as-is.
The `rows` property of a query result is an array of objects that plays nice
with `json_to_sheet`:

@ -27,6 +27,12 @@ suitable for a number of libraries. When more advanced shapes are needed,
it is easier to munge the output of an array of arrays.
### Tabulator
[Tabulator](http://tabulator.info/docs/5.3/download#xlsx) includes deep support
through a special Export button. It handles the SheetJS-related operations.
### x-spreadsheet
With a familiar UI, [`x-spreadsheet`](https://myliang.github.io/x-spreadsheet/)

@ -74,7 +74,7 @@ Similarly, file input elements automatically map to standard Web APIs.
For example, assuming a file input element on the page:
```html
<input type="file" name="xlfile" id="xlf" />
<input type="file" name="xlfile" id="xlf" />
```
The event handler would process the event as if it were a web event:
@ -235,7 +235,7 @@ File input elements automatically map to standard Web APIs.
For example, assuming a file input element on the page:
```html
<input type="file" name="xlfile" id="xlf" />
<input type="file" name="xlfile" id="xlf" />
```
The event handler would process the event as if it were a web event:

@ -1367,3 +1367,68 @@ id,content
```
</details>
## Ionic
:::warning Telemetry
Before starting this demo, manually disable telemetry. On Linux and macOS:
```bash
rm -rf ~/.ionic/
mkdir ~/.ionic
cat <<EOF > ~/.ionic/config.json
{
"version": "6.20.1",
"telemetry": false,
"npmClient": "npm"
}
EOF
npx @capacitor/cli telemetry off
```
To verify telemetry was disabled:
```bash
npx @ionic/cli config get -g telemetry
npx @capacitor/cli telemetry
```
:::
### Cordova
:::caution
The latest version of Ionic uses CapacitorJS. These notes are for older apps
using Cordova
:::
`Array<Array<any>>` neatly maps to a table with `ngFor`:
```html
<ion-grid>
<ion-row *ngFor="let row of data">
<ion-col *ngFor="let val of row">
{{val}}
</ion-col>
</ion-row>
</ion-grid>
```
`@ionic-native/file` reads and writes files on devices. `readAsArrayBuffer`
returns `ArrayBuffer` objects suitable for `array` type, and `array` type can
be converted to blobs that can be exported with `writeFile`:
```ts
/* read a workbook */
const ab: ArrayBuffer = await this.file.readAsArrayBuffer(url, filename);
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'array'});
/* write a workbook */
const wbout: ArrayBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
let blob = new Blob([wbout], {type: 'application/octet-stream'});
this.file.writeFile(url, filename, blob, {replace: true});
```

@ -0,0 +1,496 @@
---
sidebar_position: 23
title: Angular
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
[Angular](https://angular.io/) is a JS library for building user interfaces.
This demo tries to cover common Angular data flow ideas and strategies. Angular
and TypeScript familiarity is assumed.
**SheetJS plays nice with each version of Angular**.
Other demos cover general Angular deployments, including:
- [iOS and Android applications powered by NativeScript](./mobile#nativescript)
- [iOS and Android applications powered by ionic](./mobile#nativescript)
:::warning
Angular dev tooling uses native NodeJS modules. There are a number of issues
when trying to run Angular projects with different NodeJS versions. These
issues should be directed to the Angular project.
:::
## Installation
[The "Frameworks" section](../getting-started/installation/frameworks) covers
installation with pnpm and other package managers.
The library can be imported directly from JS or TS code with:
```js
import { read, utils, writeFile } from 'xlsx';
```
## Internal State
The various SheetJS APIs work with various data shapes. The preferred state
depends on the application.
### Array of Objects
Typically, some users will create a spreadsheet with source data that should be
loaded into the site. This sheet will have known columns. For example, our
[presidents sheet](https://sheetjs.com/pres.xlsx) has "Name" / "Index" columns:
![`pres.xlsx` data](pathname:///pres.png)
This naturally maps to an array of typed objects, as in the TS example below:
```ts
import { read, utils } from 'xlsx';
interface President {
Name: string;
Index: number;
}
const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
const wb = read(f);
const data = utils.sheet_to_json<President>(wb.Sheets[wb.SheetNames[0]]);
console.log(data);
```
`data` will be an array of objects:
```js
[
{ Name: "Bill Clinton", Index: 42 },
{ Name: "GeorgeW Bush", Index: 43 },
{ Name: "Barack Obama", Index: 44 },
{ Name: "Donald Trump", Index: 45 },
{ Name: "Joseph Biden", Index: 46 }
]
```
A component will typically loop over the data uaing `*ngFor`. The following
example generates a TABLE with a row for each President:
```ts title="src/app/app.component.ts"
import { Component } from '@angular/core';
import { read, utils } from 'xlsx';
interface President { Name: string; Index: number };
@Component({
selector: 'app-root',
template: `
<div class="content" role="main"><table>
<thead><th>Name</th><th>Index</th></thead>
<tbody>
// highlight-start
<tr *ngFor="let row of rows">
<td>{{row.Name}}</td>
<td>{{row.Index}}</td>
</tr>
// highlight-end
</tbody>
</table></div>
`
})
export class AppComponent {
// highlight-next-line
rows: President[] = [ { Name: "SheetJS", Index: 0 }];
ngOnInit(): void { (async() => {
/* Download from https://sheetjs.com/pres.numbers */
const f = await fetch("https://sheetjs.com/pres.numbers");
const ab = await f.arrayBuffer();
/* parse workbook */
// highlight-next-line
const wb = read(ab);
/* update data */
// highlight-next-line
this.rows = utils.sheet_to_json<President>(wb.Sheets[wb.SheetNames[0]]);
})(); }
}
```
### HTML
The main disadvantage of the Array of Objects approach is the specific nature
of the columns. For more general use, passing around an Array of Arrays works.
However, this does not handle merge cells well!
The `sheet_to_html` function generates HTML that is aware of merges and other
worksheet features. The generated HTML does not contain any `<script>` tags,
and should therefore be safe to pass to an `innerHTML`-bound variable, but the
`DomSanitizer` approach is strongly recommended:
```ts title="src/app/app.component.ts"
import { Component } from '@angular/core';
// highlight-next-line
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { read, utils } from 'xlsx';
@Component({
selector: 'app-root',
// highlight-next-line
template: `<div class="content" role="main" [innerHTML]="html"></div>`
})
export class AppComponent {
// highlight-start
constructor(private sanitizer: DomSanitizer) {}
html: SafeHtml = "";
// highlight-end
ngOnInit(): void { (async() => {
/* Download from https://sheetjs.com/pres.numbers */
const f = await fetch("https://sheetjs.com/pres.numbers");
const ab = await f.arrayBuffer();
/* parse workbook */
const wb = read(ab);
/* update data */
// highlight-start
const h = utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
this.html = this.sanitizer.bypassSecurityTrustHtml(h);
// highlight-end
})(); }
}
```
### Rows and Columns
Some data grids and UI components split worksheet state in two parts: an array
of column attribute objects and an array of row objects. The former is used to
generate column headings and for indexing into the row objects.
The safest approach is to use an array of arrays for state and to generate
column objects that map to A1-style column headers.
`ngx-datatable` uses `prop` as the key and `name` for the column label:
```js
/* rows are generated with a simple array of arrays */
this.rows = utils.sheet_to_json(worksheet, { header: 1 });
/* column objects are generated based on the worksheet range */
const range = utils.decode_range(ws["!ref"]||"A1");
this.columns = Array.from({ length: range.e.c + 1 }, (_, i) => ({
/* for an array of arrays, the keys are "0", "1", "2", ... */
prop: String(i),
/* column labels: encode_col translates 0 -> "A", 1 -> "B", 2 -> "C", ... */
name: XLSX.utils.encode_col(i)
}));
```
## Older Versions
:::warning
This demo is included for legacy deployments. There are incompatibilities with
different NodeJS and other ecosystem versions. Issues should be raised with
Google and the Angular team.
**The newest versions of NodeJS will not work with older Angular projects!**
:::
:::caution
The Angular tooling provides no easy way to switch between versions!
[This is a known Angular problem](https://github.com/angular/angular-cli/issues/9047)
To work around this, [`SheetJSAngular.zip`](pathname:///angular/SheetJSAngular.zip)
is a skeleton project designed to play nice with each Angular version.
:::
### Strategies
#### Internal State
This demo uses an array of arrays as the internal state:
```ts
export class SheetJSComponent {
data: any[][] = [ [1, 2], [3, 4] ];
// ...
}
```
Nested `ngFor` in a template can loop across the rows and cells:
```html
<table class="sjs-table">
<tr *ngFor="let row of data">
<td *ngFor="let val of row">{{val}}</td>
</tr>
</table>
```
#### Reading Data
For legacy deployments, the best ingress is a standard HTML INPUT file element:
```html
<input type="file" (change)="onFileChange($event)" multiple="false" />
```
In the component, the event is a standard file event. Using a `FileReader` has
broad support compared to the modern `Blob#arrayBuffer` approach:
```ts
onFileChange(evt: any) {
/* wire up file reader */
const target: DataTransfer = <DataTransfer>(evt.target);
if (target.files.length !== 1) throw new Error('Cannot use multiple files');
const reader: FileReader = new FileReader();
reader.onload = (e: any) => {
/* read workbook */
const ab: ArrayBuffer = e.target.result;
// highlight-next-line
const wb: WorkBook = read(ab);
/* grab first sheet */
const wsname: string = wb.SheetNames[0];
const ws: WorkSheet = wb.Sheets[wsname];
/* save data */
// highlight-next-line
this.data = <AOA>(utils.sheet_to_json(ws, {header: 1}));
};
reader.readAsArrayBuffer(target.files[0]);
}
```
#### Writing Data
The demo uses an HTML5 button in the template:
```html
<button (click)="export()">Export!</button>
```
In the component, `aoa_to_sheet` is used to generate the worksheet:
```ts
export(): void {
/* generate worksheet */
const ws: WorkSheet = utils.aoa_to_sheet(this.data);
/* generate workbook and add the worksheet */
const wb: WorkBook = utils.book_new();
utils.book_append_sheet(wb, ws, 'Sheet1');
/* save to file */
writeFile(wb, "SheetJS.xlsx");
}
```
### SystemJS
The default angular-cli configuration requires no additional configuration.
Some deployments use the SystemJS loader, which does require configuration.
[The SystemJS demo](./bundler#systemjs) describe the required settings.
### Legacy Demo
0) Download and unzip [`SheetJSAngular.zip`](pathname:///angular/SheetJSAngular.zip):
```bash
curl -LO https://docs.sheetjs.com/angular/SheetJSAngular.zip
unzip SheetJSAngular.zip
cd SheetJSAngular
```
1) Download the files for the desired Angular version:
<Tabs>
<TabItem value="2" label="2">
- [`package.json.ng2`](pathname:///angular/versions/package.json-ng2) save to `package.json`
- [`polyfills.ts-ng2`](pathname:///angular/versions/polyfills.ts-ng2) save to `src/polyfills.ts`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng2
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng2
```
</TabItem>
<TabItem value="4" label="4">
- [`package.json.ng4`](pathname:///angular/versions/package.json-ng4) save to `package.json`
- [`polyfills.ts-ng4`](pathname:///angular/versions/polyfills.ts-ng4) save to `src/polyfills.ts`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng4
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng4
```
</TabItem>
<TabItem value="5" label="5">
- [`package.json.ng5`](pathname:///angular/versions/package.json-ng5) save to `package.json`
- [`polyfills.ts-ng5`](pathname:///angular/versions/polyfills.ts-ng5) save to `src/polyfills.ts`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng5
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng5
```
</TabItem>
<TabItem value="6" label="6">
- [`package.json.ng6`](pathname:///angular/versions/package.json-ng6) save to `package.json`
- [`polyfills.ts-ng6`](pathname:///angular/versions/polyfills.ts-ng6) save to `src/polyfills.ts`
- [`angular.json-ng6`](pathname:///angular/versions/angular.json-ng6) save to `angular.json`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng6
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng6
curl -o angular.json -L https://docs.sheetjs.com/angular/versions/angular.json-ng6
```
</TabItem>
<TabItem value="7" label="7">
- [`package.json.ng7`](pathname:///angular/versions/package.json-ng7) save to `package.json`
- [`polyfills.ts-ng7`](pathname:///angular/versions/polyfills.ts-ng7) save to `src/polyfills.ts`
- [`angular.json-ng7`](pathname:///angular/versions/angular.json-ng7) save to `angular.json`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng7
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng7
curl -o angular.json -L https://docs.sheetjs.com/angular/versions/angular.json-ng7
```
</TabItem>
<TabItem value="8" label="8">
- [`package.json.ng8`](pathname:///angular/versions/package.json-ng8) save to `package.json`
- [`polyfills.ts-ng8`](pathname:///angular/versions/polyfills.ts-ng8) save to `src/polyfills.ts`
- [`angular.json-ng8`](pathname:///angular/versions/angular.json-ng8) save to `angular.json`
- [`tsconfig.app.json-ng8`](pathname:///angular/versions/tsconfig.app.json-ng8) save to `tsconfig.app.json`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng8
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng8
curl -o angular.json -L https://docs.sheetjs.com/angular/versions/angular.json-ng8
curl -o tsconfig.app.json -L https://docs.sheetjs.com/angular/versions/tsconfig.app.json-ng8
```
</TabItem>
<TabItem value="9" label="9">
- [`package.json.ng9`](pathname:///angular/versions/package.json-ng9) save to `package.json`
- [`polyfills.ts-ng9`](pathname:///angular/versions/polyfills.ts-ng9) save to `src/polyfills.ts`
- [`angular.json-ng9`](pathname:///angular/versions/angular.json-ng9) save to `angular.json`
- [`tsconfig.app.json-ng9`](pathname:///angular/versions/tsconfig.app.json-ng9) save to `tsconfig.app.json`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng9
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng9
curl -o angular.json -L https://docs.sheetjs.com/angular/versions/angular.json-ng9
curl -o tsconfig.app.json -L https://docs.sheetjs.com/angular/versions/tsconfig.app.json-ng9
```
</TabItem>
<TabItem value="10" label="10">
- [`package.json.ng10`](pathname:///angular/versions/package.json-ng10) save to `package.json`
- [`polyfills.ts-ng10`](pathname:///angular/versions/polyfills.ts-ng10) save to `src/polyfills.ts`
- [`angular.json-ng10`](pathname:///angular/versions/angular.json-ng10) save to `angular.json`
- [`tsconfig.app.json-ng10`](pathname:///angular/versions/tsconfig.app.json-ng10) save to `tsconfig.app.json`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng10
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng10
curl -o angular.json -L https://docs.sheetjs.com/angular/versions/angular.json-ng10
curl -o tsconfig.app.json -L https://docs.sheetjs.com/angular/versions/tsconfig.app.json-ng10
```
</TabItem>
<TabItem value="11" label="11">
- [`package.json.ng11`](pathname:///angular/versions/package.json-ng11) save to `package.json`
- [`polyfills.ts-ng11`](pathname:///angular/versions/polyfills.ts-ng11) save to `src/polyfills.ts`
- [`angular.json-ng11`](pathname:///angular/versions/angular.json-ng11) save to `angular.json`
- [`tsconfig.app.json-ng11`](pathname:///angular/versions/tsconfig.app.json-ng11) save to `tsconfig.app.json`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng11
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng11
curl -o angular.json -L https://docs.sheetjs.com/angular/versions/angular.json-ng11
curl -o tsconfig.app.json -L https://docs.sheetjs.com/angular/versions/tsconfig.app.json-ng11
```
</TabItem>
<TabItem value="12" label="12">
- [`package.json.ng12`](pathname:///angular/versions/package.json-ng12) save to `package.json`
- [`polyfills.ts-ng12`](pathname:///angular/versions/polyfills.ts-ng12) save to `src/polyfills.ts`
- [`angular.json-ng12`](pathname:///angular/versions/angular.json-ng12) save to `angular.json`
- [`tsconfig.app.json-ng12`](pathname:///angular/versions/tsconfig.app.json-ng12) save to `tsconfig.app.json`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng12
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng12
curl -o angular.json -L https://docs.sheetjs.com/angular/versions/angular.json-ng12
curl -o tsconfig.app.json -L https://docs.sheetjs.com/angular/versions/tsconfig.app.json-ng12
```
</TabItem>
<TabItem value="13" label="13">
- [`package.json.ng13`](pathname:///angular/versions/package.json-ng13) save to `package.json`
- [`polyfills.ts-ng13`](pathname:///angular/versions/polyfills.ts-ng13) save to `src/polyfills.ts`
- [`angular.json-ng13`](pathname:///angular/versions/angular.json-ng13) save to `angular.json`
- [`tsconfig.app.json-ng13`](pathname:///angular/versions/tsconfig.app.json-ng13) save to `tsconfig.app.json`
```bash
curl -o package.json -L https://docs.sheetjs.com/angular/versions/package.json-ng13
curl -o src/polyfills.ts -L https://docs.sheetjs.com/angular/versions/polyfills.ts-ng13
curl -o angular.json -L https://docs.sheetjs.com/angular/versions/angular.json-ng13
curl -o tsconfig.app.json -L https://docs.sheetjs.com/angular/versions/tsconfig.app.json-ng13
```
</TabItem>
</Tabs>
2) install project and dependencies:
```bash
npm i
npm i -S https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
```
3) start a local server with
```bash
npm run serve
```
The traditional site URL is http://localhost:4200/ . Open the page with a web
browser and open the console. In the "Elements" tab, the `app-root` element
will have an `ng-version` attribute.
4) build the app with
```bash
npm run build
```

@ -18,7 +18,7 @@ The demo projects include small runnable examples and short explainers.
### Frameworks
- [`Angular 2+ and Ionic`](https://github.com/SheetJS/SheetJS/tree/master/demos/angular2/)
- [`Angular 2+ and Ionic`](./angular)
- [`React`](./react)
- [`VueJS`](./vue)
- [`Angular.JS`](./legacy#angularjs)

@ -295,7 +295,7 @@ input_dom_element.addEventListener("change", handleFile, false);
</TabItem>
</Tabs>
The [`oldie` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) shows an IE-compatible fallback scenario.
The [`oldie` demo](../demos/legacy#internet-explorer) shows an IE-compatible fallback scenario.
</TabItem>
<TabItem value="nodejs" label="NodeJS">
@ -663,7 +663,7 @@ console.log(wb.SheetNames);`}</code></pre>
</TabItem>
</Tabs>
More detailed examples are covered in the [included demos](https://github.com/SheetJS/SheetJS/tree/master/demos/)
More detailed examples are covered in the [included demos](../demos/)
## Processing JSON and JS Data
@ -728,9 +728,7 @@ the optional `opts` argument in more detail.
[`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive
data grid for previewing and modifying structured data in the web browser. The
[demo](https://github.com/sheetjs/sheetjs/tree/master/demos/xspreadsheet)
includes a sample script with the `xtos` function for converting from
x-spreadsheet to a workbook. Live Demo: <https://oss.sheetjs.com/sheetjs/x-spreadsheet>
[demo](../demos/grid#x-spreadsheet) includes more detailed examples.
["Typed Arrays and ML"](../demos/ml) covers strategies for
creating worksheets from ML library exports (datasets stored in Typed Arrays).
@ -738,7 +736,7 @@ creating worksheets from ML library exports (datasets stored in Typed Arrays).
<details>
<summary><b>Records from a database query (SQL or no-SQL)</b> (click to show)</summary>
The [`database` demo](https://github.com/sheetjs/sheetjs/tree/master/demos/database/) includes examples of working with
The [`database` demo](../demos/database/) includes examples of working with
databases and query results.
</details>
@ -833,8 +831,8 @@ var workbook = XLSX.read(htmlstr, {type:"string"});
<details>
<summary><b>Chrome/Chromium Extension</b> (click to show)</summary>
The [`chrome` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/chrome/) shows a complete example and details the
required permissions and other settings.
The [`chrome` demo](../demos/chromium/) shows a complete example and details the required
permissions and other settings.
In an extension, it is recommended to generate the workbook in a content script
and pass the object back to the extension:

@ -165,7 +165,7 @@ Downloadify.create(id,{
});
```
The [`oldie` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/oldie/) shows an IE-compatible fallback scenario.
The [`oldie` demo](../demos/legacy#internet-explorer) shows an IE-compatible fallback scenario.
</details>
@ -549,9 +549,7 @@ With the `header: 1` option, the function exports an array of arrays of values.
[`x-spreadsheet`](https://github.com/myliang/x-spreadsheet) is an interactive
data grid for previewing and modifying structured data in the web browser. The
[demo](https://github.com/SheetJS/SheetJS/tree/master/demos/xspreadsheet)
includes a sample script with the `stox` function for converting from
a workbook to x-spreadsheet. Live Demo: <https://oss.sheetjs.com/sheetjs/x-spreadsheet>
[demo](../demos/grid#x-spreadsheet) includes a sample script and live demo.
</TabItem>
<TabItem value="react" label="React">
@ -594,9 +592,8 @@ export default function App() {
</TabItem>
<TabItem value="vue" label="VueJS">
[`vue3-table-lite`](https://linmasahiro.github.io/vue3-table-lite/dist/) is a
simple VueJS 3 data table. It is featured in the
[VueJS demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue/modify/).
[`vue3-table-lite`](https://vue3-lite-table.vercel.app/) is a simple VueJS 3
data table. It is featured in the [dedicated demo](../demos/grid#vue3-table-lite).
</TabItem>
</Tabs>
@ -609,8 +606,7 @@ generating typed arrays and tensors from worksheet data.
<details>
<summary><b>Populating a database (SQL or no-SQL)</b> (click to show)</summary>
The [`database` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/database/)
includes examples of working with databases and query results.
The [`database` demo](../demos/database/) includes examples of working with databases and query results.
</details>
@ -706,7 +702,7 @@ function Tabeller(props) {
}
```
The [`react` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/react) includes more React examples.
The [`react` demo](../demos/react) includes more React examples.
</TabItem>
<TabItem value="vue" label="VueJS">
@ -740,7 +736,7 @@ const S5SComponent = {
};
```
The [`vuejs` demo](https://github.com/SheetJS/SheetJS/tree/master/demos/vue) includes more React examples.
The [`vuejs` demo](../demos/vue) includes more React examples.
</TabItem>
</Tabs>

Binary file not shown.

@ -0,0 +1,125 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sheetjs": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sheetjs",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "sheetjs:build"
},
"configurations": {
"production": {
"browserTarget": "sheetjs:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sheetjs:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "sheetjs:serve"
},
"configurations": {
"production": {
"devServerTarget": "sheetjs:serve:production"
}
}
}
}
}
},
"defaultProject": "sheetjs"
}

@ -0,0 +1,124 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sheetjs": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sheetjs",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "sheetjs:build"
},
"configurations": {
"production": {
"browserTarget": "sheetjs:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sheetjs:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "sheetjs:serve"
},
"configurations": {
"production": {
"devServerTarget": "sheetjs:serve:production"
}
}
}
}
}
},
"defaultProject": "sheetjs"
}

@ -0,0 +1,106 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sheetjs": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:application": {
"strict": true
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sheetjs",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "2mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "sheetjs:build:production"
},
"development": {
"browserTarget": "sheetjs:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sheetjs:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
}
}
}
},
"defaultProject": "sheetjs"
}

@ -0,0 +1,106 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sheetjs": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:application": {
"strict": true
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sheetjs",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "2mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "sheetjs:build:production"
},
"development": {
"browserTarget": "sheetjs:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sheetjs:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
}
}
}
},
"defaultProject": "sheetjs"
}

@ -0,0 +1,127 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sheetjs": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sheetjs",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "sheetjs:build"
},
"configurations": {
"production": {
"browserTarget": "sheetjs:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sheetjs:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.css"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"sheetjs-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "sheetjs:serve"
},
"configurations": {
"production": {
"devServerTarget": "sheetjs:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "sheetjs"
}

@ -0,0 +1,136 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sheetjs": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sheetjs",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": [],
"es5BrowserSupport": true
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "sheetjs:build"
},
"configurations": {
"production": {
"browserTarget": "sheetjs:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sheetjs:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"src/styles.css"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"sheetjs-e2e": {
"root": "e2e/",
"projectType": "application",
"prefix": "",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "sheetjs:serve"
},
"configurations": {
"production": {
"devServerTarget": "sheetjs:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "sheetjs"
}

@ -0,0 +1,126 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sheetjs": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sheetjs",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "sheetjs:build"
},
"configurations": {
"production": {
"browserTarget": "sheetjs:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sheetjs:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "sheetjs:serve"
},
"configurations": {
"production": {
"devServerTarget": "sheetjs:serve:production"
}
}
}
}
}
},
"defaultProject": "sheetjs"
}

@ -0,0 +1,125 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sheetjs": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sheetjs",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,