deno and node ESM tests

This commit is contained in:
SheetJS 2022-02-13 04:35:34 -05:00
parent 46360a180a
commit fbdd43a3f4
26 changed files with 5131 additions and 58 deletions

39
.github/workflows/deno.yml vendored Normal file

@ -0,0 +1,39 @@
name: 'Tests: deno 1.x'
on: [pull_request, push]
jobs:
# small test
misc:
runs-on: ubuntu-latest
env:
FMTS: misc
steps:
- uses: actions/checkout@v2
- uses: denoland/setup-deno@main
with:
deno-version: v1.x
- uses: ljharb/actions/node/install@main
with:
node-version: '16.'
- run: sudo curl -Lo /usr/bin/rooster https://github.com/SheetJS/rooster/releases/download/v0.2.0/rooster-v0.2.0-linux-amd64
- run: sudo chmod a+x /usr/bin/rooster
- run: make init
- run: 'cd test_files; make all; cd -'
- run: deno test --allow-env --allow-read --allow-write test.ts
# full test
full:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: denoland/setup-deno@main
with:
deno-version: v1.x
- uses: ljharb/actions/node/install@main
with:
node-version: '16.'
- run: sudo curl -Lo /usr/bin/rooster https://github.com/SheetJS/rooster/releases/download/v0.2.0/rooster-v0.2.0-linux-amd64
- run: sudo chmod a+x /usr/bin/rooster
- run: make init
- run: 'cd test_files; make all; cd -'
- run: deno test --allow-env --allow-read --allow-write test.ts

@ -4,6 +4,11 @@ This log is intended to keep track of backwards-incompatible changes, including
but not limited to API changes and file location changes. Minor behavioral
changes may not be included if they are not expected to break existing code.
## v0.18.1
* Removed Node ESM build script and folded into standard ESM build
* Removed undocumented aliases including `make_formulae` and `get_formulae`
## v0.18.0
* Browser scripts only expose `XLSX` variable

@ -128,6 +128,14 @@ pkg: bin/xlsx.njs xlsx.js ## Build pkg standalone executable
test mocha: test.js ## Run test suite
mocha -R spec -t 30000
.PHONY: test-esm
test-esm: test.mjs ## Run Node ESM test suite
npx mocha -r esm -R spec -t 30000 $<
.PHONY: test-deno
test-deno: test.ts ## Run Deno test suite
deno test --allow-env --allow-read --allow-write $<
#* To run tests for one format, make test_<fmt>
#* To run the core test suite, make test_misc
TESTFMT=$(patsubst %,test_%,$(FMT))
@ -135,6 +143,16 @@ TESTFMT=$(patsubst %,test_%,$(FMT))
$(TESTFMT): test_%:
FMTS=$* make test
TESTESMFMT=$(patsubst %,test-esm_%,$(FMT))
.PHONY: $(TESTESMFMT)
$(TESTESMFMT): test-esm_%:
FMTS=$* make test-esm
TESTDENOFMT=$(patsubst %,test-deno_%,$(FMT))
.PHONY: $(TESTESMFMT)
$(TESTDENOFMT): test-deno_%:
FMTS=$* make test-deno
.PHONY: travis
travis: ## Run test suite with minimal output
mocha -R dot -t 30000

@ -177,10 +177,15 @@ $ bower install js-xlsx
**Deno**
The [`sheetjs`](https://deno.land/x/sheetjs) package is available on deno:
The [`sheetjs`](https://deno.land/x/sheetjs) package is hosted by Deno:
```ts
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
/* load the codepage support library for extended support with older formats */
import * as cptable from 'https://deno.land/x/sheetjs/dist/cpexcel.full.mjs';
XLSX.set_cptable(cptable);
```
**NodeJS**
@ -211,7 +216,7 @@ import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs';
XLSX.set_cptable(cpexcel);
```
**PhotoShop and InDesign**
**Photoshop and InDesign**
`dist/xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign
that is included in the `npm` package. It can be directly referenced with a
@ -538,9 +543,11 @@ The [`demos` directory](demos/) includes sample projects for:
- [`webpack 2.x`](demos/webpack/)
**Platforms and Integrations**
- [`deno`](demos/deno/)
- [`electron application`](demos/electron/)
- [`nw.js application`](demos/nwjs/)
- [`Chrome / Chromium extensions`](demos/chrome/)
- [`Download a Google Sheet locally`](demos/google-sheet/)
- [`Adobe ExtendScript`](demos/extendscript/)
- [`Headless Browsers`](demos/headless/)
- [`canvas-datagrid`](demos/datagrid/)
@ -609,6 +616,23 @@ const workbook = read(buf);
</details>
<details>
<summary><b>Local file in a Deno application</b> (click to show)</summary>
`readFile` uses `Deno.readFileSync` under the hood:
```js
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
const workbook = XLSX.readFile("test.xlsx");
```
Applications reading files must be invoked with the `--allow-read` flag. The
[`deno` demo](demos/deno/) has more examples
</details>
<details>
<summary><b>User-submitted file in a web page ("Drag-and-Drop")</b> (click to show)</summary>
@ -1467,6 +1491,23 @@ const workbook = writeFileSync("out.xlsb", buf);
</details>
<details>
<summary><b>Local file in a Deno application</b> (click to show)</summary>
`writeFile` uses `Deno.writeFileSync` under the hood:
```js
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
XLSX.writeFile(workbook, "test.xlsx");
```
Applications writing files must be invoked with the `--allow-write` flag. The
[`deno` demo](demos/deno/) has more examples
</details>
<details>
<summary><b>Local file in a PhotoShop or InDesign plugin</b> (click to show)</summary>

@ -66,7 +66,7 @@ function utf8decode(content/*:string*/) {
o[widx++] = (128|(c&63));
} else if(c >= 0xD800 && c < 0xE000) {
c = (c&1023)+64;
var d = str.charCodeAt(++ridx)&1023;
var d = content.charCodeAt(++ridx)&1023;
o[widx++] = (240|((c>>8)&7));
o[widx++] = (128|((c>>2)&63));
o[widx++] = (128|((d>>6)&15)|((c&3)<<4));

@ -63,7 +63,7 @@ if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
}
/* from js-xls */
if(typeof cptable !== 'undefined') {
function cpdoit() {
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)).replace(chr0, ''); };
__utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(65001, b.slice(s,e)); };
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_ansi, b.slice(i+4, i+4+len-1)) : "";};
@ -72,6 +72,7 @@ if(typeof cptable !== 'undefined') {
__lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
__8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
}
if(typeof cptable !== 'undefined') cpdoit();
var __readUInt8 = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx]; };
var __readUInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx+1]*(1<<8))+b[idx]; };

@ -585,19 +585,19 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
break;
case 'header' /*case 'Header'*/:
if(!cursheet['!margins']) default_margins(cursheet['!margins']={}, 'xlml');
cursheet['!margins'].header = parsexmltag(Rn[0]).Margin;
if(!isNaN(+parsexmltag(Rn[0]).Margin)) cursheet['!margins'].header = +parsexmltag(Rn[0]).Margin;
break;
case 'footer' /*case 'Footer'*/:
if(!cursheet['!margins']) default_margins(cursheet['!margins']={}, 'xlml');
cursheet['!margins'].footer = parsexmltag(Rn[0]).Margin;
if(!isNaN(+parsexmltag(Rn[0]).Margin)) cursheet['!margins'].footer = +parsexmltag(Rn[0]).Margin;
break;
case 'pagemargins' /*case 'PageMargins'*/:
var pagemargins = parsexmltag(Rn[0]);
if(!cursheet['!margins']) default_margins(cursheet['!margins']={},'xlml');
if(pagemargins.Top) cursheet['!margins'].top = pagemargins.Top;
if(pagemargins.Left) cursheet['!margins'].left = pagemargins.Left;
if(pagemargins.Right) cursheet['!margins'].right = pagemargins.Right;
if(pagemargins.Bottom) cursheet['!margins'].bottom = pagemargins.Bottom;
if(!isNaN(+pagemargins.Top)) cursheet['!margins'].top = +pagemargins.Top;
if(!isNaN(+pagemargins.Left)) cursheet['!margins'].left = +pagemargins.Left;
if(!isNaN(+pagemargins.Right)) cursheet['!margins'].right = +pagemargins.Right;
if(!isNaN(+pagemargins.Bottom)) cursheet['!margins'].bottom = +pagemargins.Bottom;
break;
case 'displayrighttoleft' /*case 'DisplayRightToLeft'*/:
if(!Workbook.Views) Workbook.Views = [];

@ -67,6 +67,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
reset_cp();
var o = opts||{};
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
if(typeof Uint8Array !== 'undefined' && data instanceof Uint8Array && !o.type) o.type = typeof Deno !== "undefined" ? "buffer" : "array";
var d = data, n = [0,0,0,0], str = false;
if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
_ssfopts = {};

@ -48,7 +48,12 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
default: throw new Error("Unrecognized type " + o.type);
}
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
if(typeof Deno !== "undefined" && typeof out == "string") out = new Uint8Array(s2ab(out));
if(typeof Deno !== "undefined") {
if(typeof out == "string") {
if(o.type == "binary" || o.type == "base64") return out;
out = new Uint8Array(s2ab(out));
}
}
/*jshint -W083 */
if(o.password && typeof encrypt_agile !== 'undefined') return write_cfb_ctr(encrypt_agile(out, o.password), o); // eslint-disable-line no-undef
/*jshint +W083 */
@ -72,6 +77,7 @@ function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
if(has_buf) return Buffer_from(o, 'utf8');
else if(typeof TextEncoder !== "undefined") return new TextEncoder().encode(o);
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
}

@ -252,10 +252,6 @@ var utils/*:any*/ = {
decode_cell: decode_cell,
decode_range: decode_range,
format_cell: format_cell,
get_formulae: sheet_to_formulae,
make_csv: sheet_to_csv,
make_json: sheet_to_json,
make_formulae: sheet_to_formulae,
sheet_add_aoa: sheet_add_aoa,
sheet_add_json: sheet_add_json,
sheet_add_dom: sheet_add_dom,

@ -40,6 +40,7 @@ can be installed with Bash on Windows or with `cygwin`.
- [`webpack 2.x`](webpack/)
**Platforms and Integrations**
- [`deno`](deno/)
- [`electron application`](electron/)
- [`nw.js application`](nwjs/)
- [`Chrome / Chromium extensions`](chrome/)

1
demos/deno/.gitignore vendored Normal file

@ -0,0 +1 @@
sheet2csv

@ -1,8 +1,13 @@
TESTS= x mjs jspm
UNSTABLE= node
.PHONY: test
test: $(UNSTABLE) $(TESTS)
.PHONY: sheet2csv
sheet2csv: sheet2csv.ts
deno compile -r --allow-read $<
$(TESTS): %: %.ts doit.ts
deno run --allow-read --allow-write $<

@ -37,12 +37,26 @@ Deno.writeFileSync("test.xlsb", u8);
## Demos
**Complete Example**
`sheet2csv.ts` is a complete command-line tool for generating CSV text from
workbooks. Building the application is incredibly straightforward:
```bash
$ deno compile -r --allow-read sheet2csv.ts # build the sheet2csv binary
$ ./sheet2csv test.xlsx # print the first worksheet as CSV
$ ./sheet2csv test.xlsx s5s # print worksheet "s5s" as CSV
```
**Module Import Scenarios**
All demos attempt to read a file and write a new file. [`doit.ts`](./doit.ts)
accepts the `XLSX` module as an argument.
- `x` imports the ESM build without the codepage library:
```ts
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs';
```

21
demos/deno/sheet2csv.ts Normal file

@ -0,0 +1,21 @@
/*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs';
import * as cptable from 'https://deno.land/x/sheetjs/dist/cpexcel.full.mjs';
XLSX.set_cptable(cptable);
const filename = Deno.args[0];
if(!filename) {
console.error("usage: sheet2csv <filename> [sheetname]");
Deno.exit(1);
}
const workbook = XLSX.readFile(filename);
const sheetname = Deno.args[1] || workbook.SheetNames[0];
if(!workbook.Sheets[sheetname]) {
console.error(`error: workbook missing sheet ${sheetname}`);
Deno.exit(1);
}
console.log(XLSX.utils.sheet_to_csv(workbook.Sheets[sheetname]));

@ -61,10 +61,15 @@ $ bower install js-xlsx
**Deno**
The [`sheetjs`](https://deno.land/x/sheetjs) package is available on deno:
The [`sheetjs`](https://deno.land/x/sheetjs) package is hosted by Deno:
```ts
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
/* load the codepage support library for extended support with older formats */
import * as cptable from 'https://deno.land/x/sheetjs/dist/cpexcel.full.mjs';
XLSX.set_cptable(cptable);
```
**NodeJS**
@ -95,7 +100,7 @@ import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs';
XLSX.set_cptable(cpexcel);
```
**PhotoShop and InDesign**
**Photoshop and InDesign**
`dist/xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign
that is included in the `npm` package. It can be directly referenced with a

@ -25,9 +25,11 @@ The [`demos` directory](demos/) includes sample projects for:
- [`webpack 2.x`](demos/webpack/)
**Platforms and Integrations**
- [`deno`](demos/deno/)
- [`electron application`](demos/electron/)
- [`nw.js application`](demos/nwjs/)
- [`Chrome / Chromium extensions`](demos/chrome/)
- [`Download a Google Sheet locally`](demos/google-sheet/)
- [`Adobe ExtendScript`](demos/extendscript/)
- [`Headless Browsers`](demos/headless/)
- [`canvas-datagrid`](demos/datagrid/)

@ -56,6 +56,23 @@ const workbook = read(buf);
</details>
<details>
<summary><b>Local file in a Deno application</b> (click to show)</summary>
`readFile` uses `Deno.readFileSync` under the hood:
```js
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
const workbook = XLSX.readFile("test.xlsx");
```
Applications reading files must be invoked with the `--allow-read` flag. The
[`deno` demo](demos/deno/) has more examples
</details>
<details>
<summary><b>User-submitted file in a web page ("Drag-and-Drop")</b> (click to show)</summary>

@ -63,6 +63,23 @@ const workbook = writeFileSync("out.xlsb", buf);
</details>
<details>
<summary><b>Local file in a Deno application</b> (click to show)</summary>
`writeFile` uses `Deno.writeFileSync` under the hood:
```js
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
XLSX.writeFile(workbook, "test.xlsx");
```
Applications writing files must be invoked with the `--allow-write` flag. The
[`deno` demo](demos/deno/) has more examples
</details>
<details>
<summary><b>Local file in a PhotoShop or InDesign plugin</b> (click to show)</summary>

@ -71,5 +71,6 @@ function set_cptable(_cptable) {
_getansi = function _ga2(x/*:number*/)/*:string*/ {
return cptable.utils.decode(current_ansi, [x])[0];
};
cpdoit();
}
export { set_cptable };

@ -166,10 +166,15 @@ $ bower install js-xlsx
**Deno**
The [`sheetjs`](https://deno.land/x/sheetjs) package is available on deno:
The [`sheetjs`](https://deno.land/x/sheetjs) package is hosted by Deno:
```ts
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
/* load the codepage support library for extended support with older formats */
import * as cptable from 'https://deno.land/x/sheetjs/dist/cpexcel.full.mjs';
XLSX.set_cptable(cptable);
```
**NodeJS**
@ -200,7 +205,7 @@ import * as cpexcel from 'xlsx/dist/cpexcel.full.mjs';
XLSX.set_cptable(cpexcel);
```
**PhotoShop and InDesign**
**Photoshop and InDesign**
`dist/xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign
that is included in the `npm` package. It can be directly referenced with a
@ -521,9 +526,11 @@ The [`demos` directory](demos/) includes sample projects for:
- [`webpack 2.x`](demos/webpack/)
**Platforms and Integrations**
- [`deno`](demos/deno/)
- [`electron application`](demos/electron/)
- [`nw.js application`](demos/nwjs/)
- [`Chrome / Chromium extensions`](demos/chrome/)
- [`Download a Google Sheet locally`](demos/google-sheet/)
- [`Adobe ExtendScript`](demos/extendscript/)
- [`Headless Browsers`](demos/headless/)
- [`canvas-datagrid`](demos/datagrid/)
@ -590,6 +597,20 @@ const workbook = read(buf);
`readFile` uses `Deno.readFileSync` under the hood:
```js
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
const workbook = XLSX.readFile("test.xlsx");
```
Applications reading files must be invoked with the `--allow-read` flag. The
[`deno` demo](demos/deno/) has more examples
For modern websites targeting Chrome 76+, `File#arrayBuffer` is recommended:
```js
@ -1382,6 +1403,20 @@ const workbook = writeFileSync("out.xlsb", buf);
`writeFile` uses `Deno.writeFileSync` under the hood:
```js
// @deno-types="https://deno.land/x/sheetjs/types/index.d.ts"
import * as XLSX from 'https://deno.land/x/sheetjs/xlsx.mjs'
XLSX.writeFile(workbook, "test.xlsx");
```
Applications writing files must be invoked with the `--allow-write` flag. The
[`deno` demo](demos/deno/) has more examples
`writeFile` wraps the `File` logic in Photoshop and other ExtendScript targets.
The specified path should be an absolute path:

24
test.js

@ -27,7 +27,7 @@ var Buffer_from = /*::(*/function(){}/*:: :any)*/;
if(typeof Buffer !== 'undefined') {
var nbfs = !Buffer.from;
if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
if(!nbfs) try { Buffer.from("foo", "utf-8"); } catch(e) { nbfs = true; }
Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
// $FlowIgnore
if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); };
@ -248,7 +248,7 @@ function parsetest(x/*:string*/, wb/*:Workbook*/, full/*:boolean*/, ext/*:?strin
describe(x + ext + ' should generate CSV', function() {
wb.SheetNames.forEach(function(ws, i) {
it('#' + i + ' (' + ws + ')', function() {
X.utils.make_csv(wb.Sheets[ws]);
X.utils.sheet_to_csv(wb.Sheets[ws]);
});
});
});
@ -262,7 +262,7 @@ function parsetest(x/*:string*/, wb/*:Workbook*/, full/*:boolean*/, ext/*:?strin
describe(x + ext + ' should generate formulae', function() {
wb.SheetNames.forEach(function(ws, i) {
it('#' + i + ' (' + ws + ')', function() {
X.utils.get_formulae(wb.Sheets[ws]);
X.utils.sheet_to_formulae(wb.Sheets[ws]);
});
});
});
@ -289,7 +289,7 @@ function parsetest(x/*:string*/, wb/*:Workbook*/, full/*:boolean*/, ext/*:?strin
var name = getfile(dir, x, i, ".csv");
if(fs.existsSync(name)) it('#' + i + ' (' + ws + ')', function() {
var file = fs.readFileSync(name, 'utf-8');
var csv = X.utils.make_csv(wb.Sheets[ws]);
var csv = X.utils.sheet_to_csv(wb.Sheets[ws]);
assert.equal(fixcsv(csv), fixcsv(file), "CSV badness");
});
});
@ -299,14 +299,14 @@ function parsetest(x/*:string*/, wb/*:Workbook*/, full/*:boolean*/, ext/*:?strin
var rawjson = getfile(dir, x, i, ".rawjson");
if(fs.existsSync(rawjson)) it('#' + i + ' (' + ws + ')', function() {
var file = fs.readFileSync(rawjson, 'utf-8');
var json = X.utils.make_json(wb.Sheets[ws],{raw:true});
var json = X.utils.sheet_to_json(wb.Sheets[ws],{raw:true});
assert.equal(JSON.stringify(json), fixjson(file), "JSON badness");
});
var jsonf = getfile(dir, x, i, ".json");
if(fs.existsSync(jsonf)) it('#' + i + ' (' + ws + ')', function() {
var file = fs.readFileSync(jsonf, 'utf-8');
var json = X.utils.make_json(wb.Sheets[ws], {raw:false});
var json = X.utils.sheet_to_json(wb.Sheets[ws], {raw:false});
assert.equal(JSON.stringify(json), fixjson(file), "JSON badness");
});
});
@ -1760,7 +1760,7 @@ describe('json output', function() {
if(typeof before != 'undefined') before(bef);
else it('before', bef);
it('should use first-row headers and full sheet by default', function() {
var json = X.utils.sheet_to_json(ws, {raw: null});
var json = X.utils.sheet_to_json(ws, {raw: false});
assert.equal(json.length, data.length - 1);
assert.equal(json[0][1], "TRUE");
assert.equal(json[1][2], "bar");
@ -1769,7 +1769,7 @@ describe('json output', function() {
assert.throws(function() { seeker(json, [1,2,3], "baz"); });
});
it('should create array of arrays if header == 1', function() {
var json = X.utils.sheet_to_json(ws, {header:1, raw:""});
var json = X.utils.sheet_to_json(ws, {header:1, raw:false});
assert.equal(json.length, data.length);
assert.equal(json[1][0], "TRUE");
assert.equal(json[2][1], "bar");
@ -2322,9 +2322,9 @@ describe('corner cases', function() {
get_cell(ws,"A1").f = ""; get_cell(ws,"A1").w = "";
delete get_cell(ws,"C3").w; delete get_cell(ws,"C3").z; get_cell(ws,"C3").XF = {ifmt:14};
get_cell(ws,"A4").t = "e";
X.utils.get_formulae(ws);
X.utils.make_csv(ws);
X.utils.make_json(ws);
X.utils.sheet_to_formulae(ws);
X.utils.sheet_to_csv(ws);
X.utils.sheet_to_json(ws);
ws['!cols'] = [ {wch:6}, {wch:7}, {wch:10}, {wch:20} ];
var wb = {SheetNames:['sheetjs'], Sheets:{sheetjs:ws}};
@ -2336,7 +2336,7 @@ describe('corner cases', function() {
X.write(wb, {type: "binary", bookType: 'biff5'});
X.write(wb, {type: "binary", bookType: 'biff8'});
get_cell(ws,"A2").t = "f";
assert.throws(function() { X.utils.make_json(ws); });
assert.throws(function() { X.utils.sheet_to_json(ws); });
});
it('SSF', function() {
X.SSF.format("General", "dafuq");

2487
test.mjs generated Normal file

File diff suppressed because it is too large Load Diff

2336
test.ts Normal file

File diff suppressed because it is too large Load Diff

7
types/index.d.ts vendored

@ -209,7 +209,12 @@ export interface ParsingOptions extends CommonOptions {
/** If true, plaintext parsing will not parse values */
raw?: boolean;
/** If true, preserve _xlfn. prefixes in formula function names */
xlfn?: boolean;
dense?: boolean;
PRN?: boolean;
}
export interface SheetOption {
@ -548,7 +553,7 @@ export type ExcelDataType = 'b' | 'n' | 'e' | 's' | 'd' | 'z';
* Type of generated workbook
* @default 'xlsx'
*/
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'xla' | 'biff8' | 'biff5' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'rtf' | 'prn' | 'eth';
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'xla' | 'biff8' | 'biff5' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'slk' | 'html' | 'dif' | 'rtf' | 'prn' | 'eth' | 'dbf';
/** Comment element */
export interface Comment {

71
xlsx.mjs generated

@ -77,6 +77,7 @@ function set_cptable(_cptable) {
_getansi = function _ga2(x/*:number*/)/*:string*/ {
return cptable.utils.decode(current_ansi, [x])[0];
};
cpdoit();
}
export { set_cptable };
var DENSE = null;
@ -196,7 +197,7 @@ function utf8decode(content/*:string*/) {
o[widx++] = (128|(c&63));
} else if(c >= 0xD800 && c < 0xE000) {
c = (c&1023)+64;
var d = str.charCodeAt(++ridx)&1023;
var d = content.charCodeAt(++ridx)&1023;
o[widx++] = (240|((c>>8)&7));
o[widx++] = (128|((c>>2)&63));
o[widx++] = (128|((d>>6)&15)|((c&3)<<4));
@ -2799,7 +2800,9 @@ return exports;
})();
if(typeof require !== 'undefined' && typeof module !== 'undefined' && typeof DO_NOT_EXPORT_CFB === 'undefined') { module.exports = CFB; }
const _fs = void 0;
let _fs = void 0;
function set_fs(fs) { _fs = fs; }
export { set_fs };
/* normalize data for blob ctor */
function blobify(data) {
@ -3036,11 +3039,11 @@ function split_regex(str/*:string*/, re, def/*:string*/)/*:Array<string>*/ {
}
function getdatastr(data)/*:?string*/ {
if(!data) return null;
if(data.content && data.type) return cc2str(data.content, true);
if(data.data) return debom(data.data);
if(data.asNodeBuffer && has_buf) return debom(data.asNodeBuffer().toString('binary'));
if(data.asBinary) return debom(data.asBinary());
if(data._data && data._data.getContent) return debom(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
if(data.content && data.type) return debom(cc2str(data.content));
return null;
}
@ -3089,6 +3092,12 @@ function getzipstr(zip, file/*:string*/, safe/*:?boolean*/)/*:?string*/ {
try { return getzipstr(zip, file); } catch(e) { return null; }
}
function getzipbin(zip, file/*:string*/, safe/*:?boolean*/)/*:any*/ {
if(!safe) return getdatabin(getzipfile(zip, file));
if(!file) return null;
try { return getzipbin(zip, file); } catch(e) { return null; }
}
function zipentries(zip) {
var k = zip.FullPaths || keys(zip.files), o = [];
for(var i = 0; i < k.length; ++i) if(k[i].slice(-1) != '/') o.push(k[i].replace(/^Root Entry[\/]/, ""));
@ -3096,23 +3105,29 @@ function zipentries(zip) {
}
function zip_add_file(zip, path, content) {
if(zip.FullPaths) CFB.utils.cfb_add(zip, path, typeof content == "string" ? (has_buf ? Buffer_from(content) : s2a(utf8write(content))) : content);
if(zip.FullPaths) {
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);
/* TODO: investigate performance in Edge 13 */
//else if(typeof TextEncoder !== "undefined") res = new TextEncoder().encode(content);
else res = utf8decode(content);
return CFB.utils.cfb_add(zip, path, res);
}
CFB.utils.cfb_add(zip, path, content);
}
else zip.file(path, content);
}
function zip_new() {
return CFB.utils.cfb_new();
}
function zip_new() { return CFB.utils.cfb_new(); }
function zip_read(d, o) {
var zip;
switch(o.type) {
case "base64": zip = CFB.read(d, { type: "base64" }); break;
case "binary": zip = CFB.read(d, { type: "binary" }); break;
case "buffer": case "array": zip = CFB.read(d, { type: "buffer" }); break;
default: throw new Error("Unrecognized type " + o.type);
case "base64": return CFB.read(d, { type: "base64" });
case "binary": return CFB.read(d, { type: "binary" });
case "buffer": case "array": return CFB.read(d, { type: "buffer" });
}
return zip;
throw new Error("Unrecognized type " + o.type);
}
function resolve_path(path/*:string*/, base/*:string*/)/*:string*/ {
@ -3460,7 +3475,7 @@ if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
}
/* from js-xls */
if(typeof cptable !== 'undefined') {
function cpdoit() {
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)).replace(chr0, ''); };
__utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(65001, b.slice(s,e)); };
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_ansi, b.slice(i+4, i+4+len-1)) : "";};
@ -3469,6 +3484,7 @@ if(typeof cptable !== 'undefined') {
__lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
__8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
}
if(typeof cptable !== 'undefined') cpdoit();
var __readUInt8 = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx]; };
var __readUInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx+1]*(1<<8))+b[idx]; };
@ -16988,19 +17004,19 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
break;
case 'header' /*case 'Header'*/:
if(!cursheet['!margins']) default_margins(cursheet['!margins']={}, 'xlml');
cursheet['!margins'].header = parsexmltag(Rn[0]).Margin;
if(!isNaN(+parsexmltag(Rn[0]).Margin)) cursheet['!margins'].header = +parsexmltag(Rn[0]).Margin;
break;
case 'footer' /*case 'Footer'*/:
if(!cursheet['!margins']) default_margins(cursheet['!margins']={}, 'xlml');
cursheet['!margins'].footer = parsexmltag(Rn[0]).Margin;
if(!isNaN(+parsexmltag(Rn[0]).Margin)) cursheet['!margins'].footer = +parsexmltag(Rn[0]).Margin;
break;
case 'pagemargins' /*case 'PageMargins'*/:
var pagemargins = parsexmltag(Rn[0]);
if(!cursheet['!margins']) default_margins(cursheet['!margins']={},'xlml');
if(pagemargins.Top) cursheet['!margins'].top = pagemargins.Top;
if(pagemargins.Left) cursheet['!margins'].left = pagemargins.Left;
if(pagemargins.Right) cursheet['!margins'].right = pagemargins.Right;
if(pagemargins.Bottom) cursheet['!margins'].bottom = pagemargins.Bottom;
if(!isNaN(+pagemargins.Top)) cursheet['!margins'].top = +pagemargins.Top;
if(!isNaN(+pagemargins.Left)) cursheet['!margins'].left = +pagemargins.Left;
if(!isNaN(+pagemargins.Right)) cursheet['!margins'].right = +pagemargins.Right;
if(!isNaN(+pagemargins.Bottom)) cursheet['!margins'].bottom = +pagemargins.Bottom;
break;
case 'displayrighttoleft' /*case 'DisplayRightToLeft'*/:
if(!Workbook.Views) Workbook.Views = [];
@ -22619,6 +22635,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
reset_cp();
var o = opts||{};
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
if(typeof Uint8Array !== 'undefined' && data instanceof Uint8Array && !o.type) o.type = typeof Deno !== "undefined" ? "buffer" : "array";
var d = data, n = [0,0,0,0], str = false;
if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
_ssfopts = {};
@ -22715,8 +22732,13 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
case "file": oopts.type = has_buf ? "nodebuffer" : "string"; break;
default: throw new Error("Unrecognized type " + o.type);
}
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type}) : z.generate(oopts);
if(typeof Deno !== "undefined" && typeof out == "string") out = new Uint8Array(s2ab(out));
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
if(typeof Deno !== "undefined") {
if(typeof out == "string") {
if(o.type == "binary" || o.type == "base64") return out;
out = new Uint8Array(s2ab(out));
}
}
/*jshint -W083 */
if(o.password && typeof encrypt_agile !== 'undefined') return write_cfb_ctr(encrypt_agile(out, o.password), o); // eslint-disable-line no-undef
/*jshint +W083 */
@ -22740,6 +22762,7 @@ function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/
case "file": return write_dl(opts.file, o, 'utf8');
case "buffer": {
if(has_buf) return Buffer_from(o, 'utf8');
else if(typeof TextEncoder !== "undefined") return new TextEncoder().encode(o);
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
}
}
@ -23098,10 +23121,6 @@ var utils/*:any*/ = {
decode_cell: decode_cell,
decode_range: decode_range,
format_cell: format_cell,
get_formulae: sheet_to_formulae,
make_csv: sheet_to_csv,
make_json: sheet_to_json,
make_formulae: sheet_to_formulae,
sheet_add_aoa: sheet_add_aoa,
sheet_add_json: sheet_add_json,
sheet_add_dom: sheet_add_dom,