XLS Unicode Property Lists [ci skip]
This commit is contained in:
parent
a376a6c78c
commit
b98a40235f
@ -41,6 +41,18 @@ function parse_VtStringBase(blob, stringType, pad) {
|
||||
function parse_VtString(blob, t/*:number*/, pad/*:?boolean*/) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); }
|
||||
function parse_VtUnalignedString(blob, t/*:number*/) { if(!t) throw new Error("VtUnalignedString must have positive length"); return parse_VtStringBase(blob, t, 0); }
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.1.7 VtVecLpwstrValue */
|
||||
function parse_VtVecLpwstrValue(blob)/*:Array<string>*/ {
|
||||
var length = blob.read_shift(4);
|
||||
var ret/*:Array<string>*/ = [];
|
||||
for(var i = 0; i != length; ++i) {
|
||||
var start = blob.l;
|
||||
ret[i] = blob.read_shift(0, 'lpwstr').replace(chr0,'');
|
||||
if((blob.l - start) & 0x02) blob.l += 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
|
||||
function parse_VtVecUnalignedLpstrValue(blob)/*:Array<string>*/ {
|
||||
var length = blob.read_shift(4);
|
||||
@ -49,14 +61,12 @@ function parse_VtVecUnalignedLpstrValue(blob)/*:Array<string>*/ {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.1.10 VtVecUnalignedLpstr */
|
||||
function parse_VtVecUnalignedLpstr(blob)/*:Array<string>*/ {
|
||||
return parse_VtVecUnalignedLpstrValue(blob);
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.1.13 VtHeadingPair */
|
||||
function parse_VtHeadingPair(blob) {
|
||||
var start = blob.l;
|
||||
var headingString = parse_TypedPropertyValue(blob, VT_USTR);
|
||||
if(blob[blob.l] == 0x00 && blob[blob.l+1] == 0x00 && ((blob.l - start) & 0x02)) blob.l += 2;
|
||||
var headerParts = parse_TypedPropertyValue(blob, VT_I4);
|
||||
return [headingString, headerParts];
|
||||
}
|
||||
@ -65,16 +75,10 @@ function parse_VtHeadingPair(blob) {
|
||||
function parse_VtVecHeadingPairValue(blob) {
|
||||
var cElements = blob.read_shift(4);
|
||||
var out = [];
|
||||
for(var i = 0; i != cElements / 2; ++i) out.push(parse_VtHeadingPair(blob));
|
||||
for(var i = 0; i < cElements / 2; ++i) out.push(parse_VtHeadingPair(blob));
|
||||
return out;
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.1.15 VtVecHeadingPair */
|
||||
function parse_VtVecHeadingPair(blob) {
|
||||
// NOTE: When invoked, wType & padding were already consumed
|
||||
return parse_VtVecHeadingPairValue(blob);
|
||||
}
|
||||
|
||||
/* [MS-OLEPS] 2.18.1 Dictionary (uses 2.17, 2.16) */
|
||||
function parse_dictionary(blob,CodePage) {
|
||||
var cnt = blob.read_shift(4);
|
||||
@ -113,7 +117,7 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
|
||||
var t = blob.read_shift(2), ret, opts = _opts||{};
|
||||
blob.l += 2;
|
||||
if(type !== VT_VARIANT)
|
||||
if(t !== type && VT_CUSTOM.indexOf(type)===-1) throw new Error('Expected type ' + type + ' saw ' + t);
|
||||
if(t !== type && VT_CUSTOM.indexOf(type)===-1 && !((type & 0xFFFE) == 0x101E && (t & 0xFFFE) == 0x101E)) throw new Error('Expected type ' + type + ' saw ' + t);
|
||||
switch(type === VT_VARIANT ? t : type) {
|
||||
case 0x02 /*VT_I2*/: ret = blob.read_shift(2, 'i'); if(!opts.raw) blob.l += 2; return ret;
|
||||
case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
|
||||
@ -126,8 +130,10 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
|
||||
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
|
||||
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw).replace(chr0,'');
|
||||
case 0x51 /*VT_USTR*/: return parse_VtUnalignedString(blob, t/*, 4*/).replace(chr0,'');
|
||||
case 0x100C /*VT_VECTOR|VT_VARIANT*/: return parse_VtVecHeadingPair(blob);
|
||||
case 0x101E /*VT_LPSTR*/: return parse_VtVecUnalignedLpstr(blob);
|
||||
case 0x100C /*VT_VECTOR|VT_VARIANT*/: return parse_VtVecHeadingPairValue(blob);
|
||||
case 0x101E /*VT_VECTOR|VT_LPSTR*/:
|
||||
case 0x101F /*VT_VECTOR|VT_LPWSTR*/:
|
||||
return t == 0x101F ? parse_VtVecLpwstrValue(blob) : parse_VtVecUnalignedLpstrValue(blob);
|
||||
default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ can be installed with Bash on Windows or with `cygwin`.
|
||||
|
||||
**Frameworks and APIs**
|
||||
- [`angularjs`](angular/)
|
||||
- [`angular 2 / 4 / 5 / 6 and ionic`](angular2/)
|
||||
- [`angular and ionic`](angular2/)
|
||||
- [`knockout`](knockout/)
|
||||
- [`meteor`](meteor/)
|
||||
- [`react and react-native`](react/)
|
||||
|
1
demos/altjs/.gitignore
vendored
1
demos/altjs/.gitignore
vendored
@ -7,3 +7,4 @@ rhino
|
||||
shim.min.js
|
||||
xlsx.*.js
|
||||
payload.js
|
||||
goja
|
||||
|
@ -27,7 +27,6 @@ swift: base ## swift demo
|
||||
|
||||
.PHONY: goja
|
||||
goja: base ## goja demo
|
||||
if [ ! -e xlsx.core.min.js ]; then cp ../../dist/xlsx.core.min.js .; fi
|
||||
go build goja.go
|
||||
for ext in xlsx xlsb biff8.xls xml.xls; do ./goja sheetjs.$$ext; done
|
||||
|
||||
|
@ -51,7 +51,7 @@ Binary strings can be passed back and forth using `String.Encoding.isoLatin1`:
|
||||
/* parse sheetjs.xls */
|
||||
let file_path = shared_dir.appendingPathComponent("sheetjs.xls");
|
||||
let data: String! = try String(contentsOf: file_path, encoding: String.Encoding.isoLatin1);
|
||||
context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)!);
|
||||
context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol));
|
||||
src = "var wb = XLSX.read(payload, {type:'binary'});";
|
||||
context.evaluateScript(src);
|
||||
|
||||
@ -108,14 +108,15 @@ target builds a very simple payload with the data.
|
||||
## Duktape
|
||||
|
||||
[Duktape](http://duktape.org/) is an embeddable JS engine written in C. The
|
||||
amalgamation makes integration extremely simple! It supports `Buffer` natively:
|
||||
amalgamation makes integration extremely simple! It supports `Buffer` natively
|
||||
but should be sliced before processing:
|
||||
|
||||
```C
|
||||
/* parse a C char array as a workbook object */
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, buf, len);
|
||||
duk_put_global_string(ctx, "buf");
|
||||
duk_eval_string_noresult("workbook = XLSX.read(buf, {type:'buffer'});");
|
||||
duk_eval_string_noresult("workbook = XLSX.read(buf.slice(0, buf.length), {type:'buffer'});");
|
||||
|
||||
/* write a workbook object to a C char array */
|
||||
duk_eval_string(ctx, "XLSX.write(workbook, {type:'array', bookType:'xlsx'})");
|
||||
@ -157,9 +158,8 @@ wh.write(out, 0, ab.byteLength); wh.close();
|
||||
|
||||
## Goja
|
||||
|
||||
Goja is a pure Go implementation of ECMAScript 5. As of this writing, there are
|
||||
some issues with processing Unicode data, but the `xlsx.core.min.js` script can
|
||||
be processed. `[]byte` should be transformed to a binary string in the engine:
|
||||
Goja is a pure Go implementation of ECMAScript 5. `[]byte` should be converted
|
||||
to a binary string in the engine:
|
||||
|
||||
```go
|
||||
/* read file */
|
||||
|
@ -9,7 +9,7 @@ enum SJSError: Error {
|
||||
|
||||
class SJSWorksheet {
|
||||
var context: JSContext!;
|
||||
var wb: JSValue!; var ws: JSValue!;
|
||||
var wb: JSValue; var ws: JSValue;
|
||||
var idx: Int32;
|
||||
|
||||
func toCSV() throws -> String {
|
||||
@ -26,7 +26,7 @@ class SJSWorksheet {
|
||||
|
||||
class SJSWorkbook {
|
||||
var context: JSContext!;
|
||||
var wb: JSValue!; var SheetNames: JSValue!; var Sheets: JSValue!;
|
||||
var wb: JSValue; var SheetNames: JSValue; var Sheets: JSValue;
|
||||
|
||||
func getSheetAtIndex(idx: Int32) throws -> SJSWorksheet {
|
||||
let SheetName: String = SheetNames.atIndex(Int(idx)).toString();
|
||||
@ -37,8 +37,8 @@ class SJSWorkbook {
|
||||
func writeBStr(bookType: String = "xlsx") throws -> String {
|
||||
let XLSX: JSValue! = context.objectForKeyedSubscript("XLSX");
|
||||
context.evaluateScript(String(format: "var writeopts = {type:'binary', bookType:'%@'}", bookType));
|
||||
let writeopts: JSValue! = context.objectForKeyedSubscript("writeopts");
|
||||
let writefunc: JSValue! = XLSX.objectForKeyedSubscript("write");
|
||||
let writeopts: JSValue = context.objectForKeyedSubscript("writeopts");
|
||||
let writefunc: JSValue = XLSX.objectForKeyedSubscript("write");
|
||||
return writefunc.call(withArguments: [wb, writeopts]).toString();
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ class SheetJSCore {
|
||||
var context: JSContext!
|
||||
do {
|
||||
context = JSContext();
|
||||
context.exceptionHandler = { ctx, X in if let e = X { print(e.toString()); }; };
|
||||
context.exceptionHandler = { _, X in if let e = X { print(e.toString()!); }; };
|
||||
context.evaluateScript("var global = (function(){ return this; }).call(null);");
|
||||
context.evaluateScript("if(typeof wbs == 'undefined') wbs = [];");
|
||||
let src = try String(contentsOfFile: "xlsx.full.min.js");
|
||||
@ -79,7 +79,7 @@ class SheetJSCore {
|
||||
}
|
||||
|
||||
func readBStr(data: String) throws -> SJSWorkbook {
|
||||
context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol)!);
|
||||
context.setObject(data, forKeyedSubscript: "payload" as (NSCopying & NSObjectProtocol));
|
||||
context.evaluateScript("var wb = XLSX.read(payload, {type:'binary'});");
|
||||
let wb: JSValue! = context.objectForKeyedSubscript("wb");
|
||||
if wb == nil { throw SJSError.badJSWorkbook; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
DUKTAPE_VER=2.2.0
|
||||
DUKTAPE_VER=2.6.0
|
||||
if [ ! -e duktape-$DUKTAPE_VER ]; then
|
||||
if [ ! -e duktape-$DUKTAPE_VER.tar ]; then
|
||||
if [ ! -e duktape-$DUKTAPE_VER.tar.xz ]; then
|
||||
|
@ -39,7 +39,7 @@ func main() {
|
||||
|
||||
/* load library */
|
||||
safe_run_file(vm, "shim.min.js")
|
||||
safe_run_file(vm, "xlsx.core.min.js")
|
||||
safe_run_file(vm, "xlsx.full.min.js")
|
||||
|
||||
/* get version string */
|
||||
v := eval_string(vm, "XLSX.version")
|
||||
|
@ -10,6 +10,8 @@ into web pages with script tags:
|
||||
Strictly speaking, there should be no need for an Angular demo! You can proceed
|
||||
as you would with any other browser-friendly library.
|
||||
|
||||
This demo uses AngularJS 1.5.0.
|
||||
|
||||
|
||||
## Array of Objects
|
||||
|
||||
@ -87,13 +89,13 @@ function SheetJSImportDirective() {
|
||||
|
||||
reader.onload = function (e) {
|
||||
/* read workbook */
|
||||
var bstr = e.target.result;
|
||||
var workbook = XLSX.read(bstr, {type:'binary'});
|
||||
var ab = e.target.result;
|
||||
var workbook = XLSX.read(ab);
|
||||
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
};
|
||||
|
||||
reader.readAsBinaryString(changeEvent.target.files[0]);
|
||||
reader.readAsArrayBuffer(changeEvent.target.files[0]);
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -133,7 +135,7 @@ directive for a HTML File Input control. It also includes a sample service for
|
||||
export which adds an item to the export menu.
|
||||
|
||||
The demo `SheetJSImportDirective` follows the prescription from the README for
|
||||
File input controls using `readAsBinaryString`, converting to a suitable
|
||||
File input controls using `readAsArrayBuffer`, converting to a suitable
|
||||
representation and updating the scope.
|
||||
|
||||
`SheetJSExportService` exposes export functions for `XLSB` and `XLSX`. Other
|
||||
|
8
demos/angular/SheetJS-angular.js
vendored
8
demos/angular/SheetJS-angular.js
vendored
@ -60,8 +60,8 @@ function SheetJSImportDirective() {
|
||||
|
||||
reader.onload = function(e) {
|
||||
/* read workbook */
|
||||
var bstr = e.target.result;
|
||||
var wb = XLSX.read(bstr, {type:'binary'});
|
||||
var ab = e.target.result;
|
||||
var wb = XLSX.read(ab);
|
||||
|
||||
/* grab first sheet */
|
||||
var wsname = wb.SheetNames[0];
|
||||
@ -78,7 +78,7 @@ function SheetJSImportDirective() {
|
||||
data[r-1] = {};
|
||||
for(i = 0; i < aoa[r].length; ++i) {
|
||||
if(aoa[r][i] == null) continue;
|
||||
data[r-1][aoa[0][i]] = aoa[r][i]
|
||||
data[r-1][aoa[0][i]] = aoa[r][i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ function SheetJSImportDirective() {
|
||||
});
|
||||
};
|
||||
|
||||
reader.readAsBinaryString(changeEvent.target.files[0]);
|
||||
reader.readAsArrayBuffer(changeEvent.target.files[0]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -10,8 +10,8 @@
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
|
||||
|
||||
<!-- ui-grid -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.0/ui-grid.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.0/ui-grid.css"/>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.11.0/ui-grid.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.11.0/ui-grid.css"/>
|
||||
|
||||
<!-- SheetJS js-xlsx library -->
|
||||
<script src="shim.js"></script>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<title>SheetJS + AngularJS</title>
|
||||
<!-- Angular -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
|
||||
|
||||
<!-- SheetJS js-xlsx library -->
|
||||
<script src="shim.js"></script>
|
||||
|
6
demos/angular2/.eslintrc
Normal file
6
demos/angular2/.eslintrc
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"extends": [
|
||||
"eslint:recommended"
|
||||
]
|
||||
}
|
1
demos/angular2/.gitattributes
vendored
Normal file
1
demos/angular2/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.*-ng* linguist-generated=true binary
|
3
demos/angular2/.gitignore
vendored
3
demos/angular2/.gitignore
vendored
@ -2,3 +2,6 @@ dist
|
||||
hooks
|
||||
SheetJSIonic
|
||||
SheetJSNS
|
||||
angular.json
|
||||
tsconfig.app.json
|
||||
src/polyfills.ts
|
||||
|
@ -1,22 +1,30 @@
|
||||
.PHONY: all
|
||||
all: angular5
|
||||
|
||||
.PHONY: angular2 angular4 angular5
|
||||
angular2 angular4 angular5:
|
||||
cp package.json-$@ package.json
|
||||
.PHONY: ng2 ng4 ng5 ng6 ng7 ng8 ng9 ng10 ng11 ng12
|
||||
ng2 ng4 ng5 ng6 ng7 ng8 ng9 ng10 ng11 ng12:
|
||||
rm -f angular.json tsconfig.app.json src/polyfills.ts
|
||||
cp versions/package.json-$@ package.json
|
||||
if [ -e versions/angular.json-$@ ]; then cp versions/angular.json-$@ angular.json; fi
|
||||
if [ -e versions/tsconfig.app.json-$@ ]; then cp versions/tsconfig.app.json-$@ tsconfig.app.json; fi
|
||||
if [ -e versions/polyfills.ts-$@ ]; then cp versions/polyfills.ts-$@ src/polyfills.ts; fi
|
||||
rm -rf node_modules
|
||||
npm install
|
||||
if [ ! -e node_modules ]; then mkdir node_modules; fi
|
||||
if [ ! -e node_modules/xlsx ]; then cd node_modules; ln -s ../../../ xlsx; cd -; fi
|
||||
npm run build
|
||||
|
||||
.PHONY: all
|
||||
all:
|
||||
for i in 2 4 5 6 7 8 9 10 11 12; do make ng$$i; done
|
||||
|
||||
.PHONY: ionic
|
||||
ionic:
|
||||
bash ./ionic.sh
|
||||
|
||||
.PHONY: ios android browser
|
||||
ios android browser: ionic
|
||||
ios browser: ionic
|
||||
cd SheetJSIonic; ionic cordova emulate $@ </dev/null; cd -
|
||||
android: ionic
|
||||
cd SheetJSIonic; ionic cordova prepare $@ </dev/null; ionic cordova emulate $@ </dev/null; cd -
|
||||
|
||||
|
||||
.PHONY: nativescript
|
||||
nativescript:
|
||||
@ -24,7 +32,7 @@ nativescript:
|
||||
|
||||
.PHONY: ns-ios ns-android
|
||||
ns-ios: nativescript
|
||||
cd SheetJSNS; tns run ios; cd -
|
||||
cd SheetJSNS; ns run ios; cd -
|
||||
ns-android: nativescript
|
||||
cd SheetJSNS; tns run android; cd -
|
||||
cd SheetJSNS; ns run android; cd -
|
||||
|
||||
|
@ -54,8 +54,8 @@ XLSX.writeFile(wb, 'SheetJS.xlsx');
|
||||
const reader: FileReader = new FileReader();
|
||||
reader.onload = (e: any) => {
|
||||
/* read workbook */
|
||||
const bstr: string = e.target.result;
|
||||
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
|
||||
const ab: ArrayBuffer = e.target.result;
|
||||
const wb: XLSX.WorkBook = XLSX.read(ab);
|
||||
|
||||
/* grab first sheet */
|
||||
const wsname: string = wb.SheetNames[0];
|
||||
@ -64,7 +64,7 @@ XLSX.writeFile(wb, 'SheetJS.xlsx');
|
||||
/* save data */
|
||||
this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
|
||||
};
|
||||
reader.readAsBinaryString(target.files[0]);
|
||||
reader.readAsArrayBuffer(target.files[0]);
|
||||
}
|
||||
```
|
||||
|
||||
@ -73,17 +73,20 @@ XLSX.writeFile(wb, 'SheetJS.xlsx');
|
||||
Modules that work with Angular 2 largely work as-is with Angular 4+. Switching
|
||||
between versions is mostly a matter of installing the correct version of the
|
||||
core and associated modules. This demo includes `package.json-angular#` files
|
||||
for Angular 2, Angular 4, and Angular 5
|
||||
for every major version of Angular up to 12.
|
||||
|
||||
To test a particular Angular version, overwrite `package.json`:
|
||||
|
||||
```bash
|
||||
# switch to Angular 2
|
||||
$ cp package.json-angular2 package.json
|
||||
$ cp package.json-ng2 package.json
|
||||
$ npm install
|
||||
$ ng serve
|
||||
```
|
||||
|
||||
Note: when running the demos, Angular 2 requires Node <= 14. This is due to a
|
||||
tooling issue with `ng` and does not affect browser use.
|
||||
|
||||
## XLSX Symbolic Link
|
||||
|
||||
In this tree, `node_modules/xlsx` is a link pointing back to the root. This
|
||||
@ -137,14 +140,14 @@ script performs the necessary installation steps.
|
||||
```
|
||||
|
||||
|
||||
`@ionic-native/file` reads and writes files on devices. `readAsBinaryString`
|
||||
returns strings that can be parsed with the `binary` type, and `array` type can
|
||||
`@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`:
|
||||
|
||||
```typescript
|
||||
/* read a workbook */
|
||||
const bstr: string = await this.file.readAsBinaryString(url, filename);
|
||||
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
|
||||
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' });
|
||||
@ -164,16 +167,19 @@ const XLSX = require("./xlsx.full.min.js");
|
||||
```
|
||||
|
||||
The `ISO_8859_1` encoding from the text module specifies `"binary"` strings.
|
||||
`fs.File#readText` and `fs.File#writeText` reads and writes files:
|
||||
`File#readText` and `File#writeText` reads and writes files:
|
||||
|
||||
```typescript
|
||||
/* read a workbook */
|
||||
const bstr: string = await file.readText(textModule.encoding.ISO_8859_1);
|
||||
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, textModule.encoding.ISO_8859_1);
|
||||
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>
|
||||
|
||||
[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
|
||||
|
22
demos/angular2/ionic-app.module.ts
Normal file
22
demos/angular2/ionic-app.module.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/* NOTE: this file exists because `File` must be added as a provider */
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { RouteReuseStrategy } from '@angular/router';
|
||||
|
||||
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
|
||||
import { File } from '@ionic-native/file/ngx';
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
entryComponents: [],
|
||||
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
|
||||
providers: [File, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
@ -1,17 +1,16 @@
|
||||
#!/bin/bash
|
||||
if [ ! -e SheetJSIonic ]; then
|
||||
ionic start SheetJSIonic blank --cordova --no-git --no-link </dev/null
|
||||
ionic start SheetJSIonic blank --type angular --cordova --quiet --no-git --no-link --confirm </dev/null
|
||||
cd SheetJSIonic
|
||||
ionic cordova platform add browser </dev/null
|
||||
ionic cordova platform add ios </dev/null
|
||||
ionic cordova platform add browser --confirm </dev/null
|
||||
ionic cordova platform add ios --confirm </dev/null
|
||||
ionic cordova platform add android --confirm </dev/null
|
||||
ionic cordova plugin add cordova-plugin-file </dev/null
|
||||
npm install --save @ionic-native/core
|
||||
npm install --save @ionic-native/file
|
||||
npm install --save xlsx
|
||||
|
||||
cp src/app/app.module.ts{,.bak}
|
||||
cat src/app/app.module.ts.bak | awk 'BEGIN{p=0} !/import/ && !p { ++p; print "import { File } from '"'"'@ionic-native/file'"'"';"; } 1; /providers: \[/ {print " File,"}' > src/app/app.module.ts
|
||||
cp ../ionic-app.module.ts src/app/app.module.ts
|
||||
cd -
|
||||
fi
|
||||
|
||||
cp ionic.ts SheetJSIonic/src/pages/home/home.ts
|
||||
rm -f SheetJSIonic/src/pages/home/home.html
|
||||
cp ionic.ts SheetJSIonic/src/app/home/home.page.ts
|
||||
|
@ -1,19 +1,30 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { File } from '@ionic-native/file/ngx';
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
import { File } from '@ionic-native/file';
|
||||
|
||||
type AOA = any[][];
|
||||
|
||||
@Component({
|
||||
selector: 'page-home',
|
||||
selector: 'app-home',
|
||||
//templateUrl: 'home.page.html',
|
||||
styleUrls: ['home.page.scss'],
|
||||
template: `
|
||||
<ion-header><ion-navbar><ion-title>SheetJS Ionic Demo</ion-title></ion-navbar></ion-header>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>SheetJS Ionic Demo</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content [fullscreen]="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title>SheetJS Demo</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content padding>
|
||||
<ion-grid>
|
||||
<ion-row *ngFor="let row of data">
|
||||
<ion-col *ngFor="let val of row">
|
||||
@ -23,7 +34,7 @@ type AOA = any[][];
|
||||
</ion-grid>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer>
|
||||
<ion-footer padding>
|
||||
<input type="file" (change)="onFileChange($event)" multiple="false" />
|
||||
<button ion-button color="secondary" (click)="import()">Import Data</button>
|
||||
<button ion-button color="secondary" (click)="export()">Export Data</button>
|
||||
@ -33,18 +44,18 @@ type AOA = any[][];
|
||||
|
||||
export class HomePage {
|
||||
data: any[][] = [[1,2,3],[4,5,6]];
|
||||
constructor(public file: File) {};
|
||||
constructor(public file: File) {}
|
||||
|
||||
read(bstr: string) {
|
||||
read(ab: ArrayBuffer) {
|
||||
/* read workbook */
|
||||
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
|
||||
const wb: XLSX.WorkBook = XLSX.read(new Uint8Array(ab), {type: 'array'});
|
||||
|
||||
/* grab first sheet */
|
||||
const wsname: string = wb.SheetNames[0];
|
||||
const ws: XLSX.WorkSheet = wb.Sheets[wsname];
|
||||
|
||||
/* save data */
|
||||
this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
|
||||
this.data = (XLSX.utils.sheet_to_json(ws, {header: 1}) as AOA);
|
||||
};
|
||||
|
||||
write(): XLSX.WorkBook {
|
||||
@ -61,14 +72,14 @@ export class HomePage {
|
||||
/* File Input element for browser */
|
||||
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 target: DataTransfer = (evt.target as DataTransfer);
|
||||
if (target.files.length !== 1) { throw new Error('Cannot use multiple files'); }
|
||||
const reader: FileReader = new FileReader();
|
||||
reader.onload = (e: any) => {
|
||||
const bstr: string = e.target.result;
|
||||
this.read(bstr);
|
||||
const ab: ArrayBuffer = e.target.result;
|
||||
this.read(ab);
|
||||
};
|
||||
reader.readAsBinaryString(target.files[0]);
|
||||
reader.readAsArrayBuffer(target.files[0]);
|
||||
};
|
||||
|
||||
/* Import button for mobile */
|
||||
@ -77,23 +88,22 @@ export class HomePage {
|
||||
const target: string = this.file.documentsDirectory || this.file.externalDataDirectory || this.file.dataDirectory || '';
|
||||
const dentry = await this.file.resolveDirectoryUrl(target);
|
||||
const url: string = dentry.nativeURL || '';
|
||||
alert(`Attempting to read SheetJSIonic.xlsx from ${url}`)
|
||||
const bstr: string = await this.file.readAsBinaryString(url, "SheetJSIonic.xlsx");
|
||||
this.read(bstr);
|
||||
alert(`Attempting to read SheetJSIonic.xlsx from ${url}`);
|
||||
const ab: ArrayBuffer = await this.file.readAsArrayBuffer(url, 'SheetJSIonic.xlsx');
|
||||
this.read(ab);
|
||||
} catch(e) {
|
||||
const m: string = e.message;
|
||||
alert(m.match(/It was determined/) ? "Use File Input control" : `Error: ${m}`);
|
||||
alert(m.match(/It was determined/) ? 'Use File Input control' : `Error: ${m}`);
|
||||
}
|
||||
};
|
||||
|
||||
/* Export button */
|
||||
async export() {
|
||||
const wb: XLSX.WorkBook = this.write();
|
||||
const filename: string = "SheetJSIonic.xlsx";
|
||||
const filename = 'SheetJSIonic.xlsx';
|
||||
try {
|
||||
/* generate Blob */
|
||||
const wbout: ArrayBuffer = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
|
||||
const blob: Blob = new Blob([wbout], {type: 'application/octet-stream'});
|
||||
|
||||
/* find appropriate path for mobile */
|
||||
const target: string = this.file.documentsDirectory || this.file.externalDataDirectory || this.file.dataDirectory || '';
|
||||
@ -101,14 +111,15 @@ export class HomePage {
|
||||
const url: string = dentry.nativeURL || '';
|
||||
|
||||
/* attempt to save blob to file */
|
||||
await this.file.writeFile(url, filename, blob, {replace: true});
|
||||
await this.file.writeFile(url, filename, wbout, {replace: true});
|
||||
alert(`Wrote to SheetJSIonic.xlsx in ${url}`);
|
||||
} catch(e) {
|
||||
if(e.message.match(/It was determined/)) {
|
||||
/* in the browser, use writeFile */
|
||||
XLSX.writeFile(wb, filename);
|
||||
} else {
|
||||
alert(`Error: ${e.message}`);
|
||||
}
|
||||
else alert(`Error: ${e.message}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,15 +1,10 @@
|
||||
#!/bin/bash
|
||||
if [ ! -e SheetJSNS ]; then
|
||||
tns create SheetJSNS --template nativescript-template-ng-tutorial
|
||||
ns create SheetJSNS --ng
|
||||
cd SheetJSNS
|
||||
tns plugin add nativescript-nodeify
|
||||
npm install xlsx
|
||||
cd app
|
||||
npm install xlsx
|
||||
cd ../..
|
||||
cd ..
|
||||
fi
|
||||
|
||||
cp ../../dist/xlsx.full.min.js SheetJSNS/
|
||||
cp ../../dist/xlsx.full.min.js SheetJSNS/app/
|
||||
cp nsmain.ts SheetJSNS/app/main.ts
|
||||
cp nscript.ts SheetJSNS/app/app.component.ts
|
||||
<../../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,21 +1,19 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
|
||||
import { Component } from "@angular/core";
|
||||
import * as dockModule from "tns-core-modules/ui/layouts/dock-layout";
|
||||
import * as buttonModule from "tns-core-modules/ui/button";
|
||||
import * as textModule from "tns-core-modules/text";
|
||||
import * as dialogs from "ui/dialogs";
|
||||
import * as fs from "tns-core-modules/file-system";
|
||||
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';
|
||||
|
||||
/* NativeScript does not support import syntax for npm modules */
|
||||
const XLSX = require("./xlsx.full.min.js");
|
||||
import * as XLSX from './xlsx.full.min';
|
||||
|
||||
@Component({
|
||||
selector: "my-app",
|
||||
selector: 'ns-app',
|
||||
template: `
|
||||
<Page>
|
||||
<GridLayout rows="auto, *, auto">
|
||||
<ActionBar row="0" title="SheetJS NativeScript Demo" class="action-bar"></ActionBar>
|
||||
|
||||
<!-- data converted to HTML and rendered in web view -->
|
||||
<WebView row="1" src="{{html}}"></WebView>
|
||||
@ -25,6 +23,7 @@ const XLSX = require("./xlsx.full.min.js");
|
||||
<Button text="Export File" (tap)="export()" style="padding: 10px"></Button>
|
||||
</DockLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
`
|
||||
})
|
||||
|
||||
@ -37,16 +36,16 @@ export class AppComponent {
|
||||
|
||||
/* Import button */
|
||||
async import() {
|
||||
const filename: string = "SheetJSNS.xlsx";
|
||||
const filename: string = "SheetJSNS.csv";
|
||||
|
||||
/* find appropriate path */
|
||||
const target: fs.Folder = fs.knownFolders.documents() || fs.knownFolders.ios.sharedPublic();
|
||||
const url: string = fs.path.normalize(target.path + "///" + filename);
|
||||
const file: fs.File = fs.File.fromPath(url);
|
||||
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(textModule.encoding.ISO_8859_1);
|
||||
const bstr: string = await file.readText(encoding.ISO_8859_1);
|
||||
|
||||
/* read workbook */
|
||||
const wb = XLSX.read(bstr, { type: "binary" });
|
||||
@ -57,27 +56,27 @@ export class AppComponent {
|
||||
|
||||
/* update table */
|
||||
this.html = XLSX.utils.sheet_to_html(ws);
|
||||
dialogs.alert(`Attempting to read to SheetJSNS.xlsx in ${url}`);
|
||||
Dialogs.alert(`Attempting to read to ${filename} in ${url}`);
|
||||
} catch(e) {
|
||||
dialogs.alert(e.message);
|
||||
Dialogs.alert(e.message);
|
||||
}
|
||||
};
|
||||
|
||||
/* Export button */
|
||||
async export() {
|
||||
const wb = XLSX.read(this.html, { type: "string" });
|
||||
const filename: string = "SheetJSNS.xlsx";
|
||||
const filename: string = "SheetJSNS.csv";
|
||||
|
||||
/* generate binary string */
|
||||
const wbout: string = XLSX.write(wb, { bookType: 'xlsx', type: 'binary' });
|
||||
const wbout: string = XLSX.write(wb, { bookType: 'csv', type: 'binary' });
|
||||
|
||||
/* find appropriate path */
|
||||
const target: fs.Folder = fs.knownFolders.documents() || fs.knownFolders.ios.sharedPublic();
|
||||
const url: string = fs.path.normalize(target.path + "///" + filename);
|
||||
const file: fs.File = fs.File.fromPath(url);
|
||||
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, textModule.encoding.ISO_8859_1);
|
||||
dialogs.alert(`Wrote to SheetJSNS.xlsx in ${url}`);
|
||||
await file.writeText(wbout, encoding.ISO_8859_1);
|
||||
Dialogs.alert(`Wrote to ${filename} in ${url}`);
|
||||
};
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
import { platformNativeScriptDynamic } from "nativescript-angular/platform";
|
||||
import { AppModule } from "./app.module";
|
||||
|
||||
/*! ****************************************************************************
|
||||
Code based on @Microsoft/tslib
|
||||
|
||||
Original license header:
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
// tslint:disable
|
||||
if (!('__awaiter' in global)) {
|
||||
global['__awaiter'] = function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
if (!('__generator' in global)) {
|
||||
global['__generator'] = function (thisArg, body) {
|
||||
var _: any = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [0, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
platformNativeScriptDynamic().bootstrapModule(AppModule);
|
@ -9,6 +9,7 @@ type AOA = any[][];
|
||||
@Component({
|
||||
selector: 'sheetjs',
|
||||
template: `
|
||||
<pre><b>Version: {{ver}}</b></pre>
|
||||
<input type="file" (change)="onFileChange($event)" multiple="false" />
|
||||
<table class="sjs-table">
|
||||
<tr *ngFor="let row of data">
|
||||
@ -25,6 +26,7 @@ export class SheetJSComponent {
|
||||
data: AOA = [ [1, 2], [3, 4] ];
|
||||
wopts: XLSX.WritingOptions = { bookType: 'xlsx', type: 'array' };
|
||||
fileName: string = 'SheetJS.xlsx';
|
||||
ver: string = XLSX.version;
|
||||
|
||||
onFileChange(evt: any) {
|
||||
/* wire up file reader */
|
||||
@ -33,8 +35,8 @@ export class SheetJSComponent {
|
||||
const reader: FileReader = new FileReader();
|
||||
reader.onload = (e: any) => {
|
||||
/* read workbook */
|
||||
const bstr: string = e.target.result;
|
||||
const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'});
|
||||
const ab: ArrayBuffer = e.target.result;
|
||||
const wb: XLSX.WorkBook = XLSX.read(ab);
|
||||
|
||||
/* grab first sheet */
|
||||
const wsname: string = wb.SheetNames[0];
|
||||
@ -43,7 +45,7 @@ export class SheetJSComponent {
|
||||
/* save data */
|
||||
this.data = <AOA>(XLSX.utils.sheet_to_json(ws, {header: 1}));
|
||||
};
|
||||
reader.readAsBinaryString(target.files[0]);
|
||||
reader.readAsArrayBuffer(target.files[0]);
|
||||
}
|
||||
|
||||
export(): void {
|
||||
|
3
demos/angular2/src/environments/environment.prod.ts
Normal file
3
demos/angular2/src/environments/environment.prod.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const environment = {
|
||||
production: true
|
||||
};
|
3
demos/angular2/src/environments/environment.ts
Normal file
3
demos/angular2/src/environments/environment.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const environment = {
|
||||
production: false
|
||||
};
|
1
demos/angular2/src/styles.css
Normal file
1
demos/angular2/src/styles.css
Normal file
@ -0,0 +1 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
125
demos/angular2/versions/angular.json-ng10
generated
Normal file
125
demos/angular2/versions/angular.json-ng10
generated
Normal file
@ -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"
|
||||
}
|
124
demos/angular2/versions/angular.json-ng11
generated
Normal file
124
demos/angular2/versions/angular.json-ng11
generated
Normal file
@ -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"
|
||||
}
|
106
demos/angular2/versions/angular.json-ng12
generated
Normal file
106
demos/angular2/versions/angular.json-ng12
generated
Normal file
@ -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"
|
||||
}
|
127
demos/angular2/versions/angular.json-ng6
generated
Normal file
127
demos/angular2/versions/angular.json-ng6
generated
Normal file
@ -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": {
|
||||