Compare commits

...

23 Commits

Author SHA1 Message Date
1517aa1bca make_csv_row: Always quote fields with CR or LF 2025-09-22 01:27:06 -04:00
b4bb01c731 XLSX shared formula shift nit
- hid ODS number format warning behind WTF (fixes #3324 h/t @gboysko)
2025-08-27 21:46:09 -04:00
4495a9253e XLSB new records (fixes #3286 h/t @travisskyles) 2025-04-30 13:21:01 -04:00
0e4eb976e1 export nits
- XLSX write dense mode null check (fixes #3261 h/t @mbornstein)
- Use `subarray` for Uint8Array/Buffer ops (h/t @hardonthebeat)
2025-02-22 15:18:51 -05:00
9c3853ba25 fix: missing break condition in make_json_row 2025-01-10 16:26:17 +05:30
318e2319ee ODS parse hyperlink tooltips 2024-11-10 21:27:04 -05:00
6c0f950f83 feat: Add Sheet Protection for XLS (BIFF8) (#3202)
Fixes #3201

Reviewed-on: sheetjs/sheetjs#3202
Co-authored-by: Lucas Picchi <lucas.picchi@exeo.com.ar>
Co-committed-by: Lucas Picchi <lucas.picchi@exeo.com.ar>
2024-10-26 20:37:20 +00:00
235ed7ccfb update CONTRIBUTING.md (fixes #3233 h/t @Akxe) 2024-10-21 09:43:40 -04:00
2d6c821261 Parse DIF-esque CSV (fixes #3230 h/t @lowkeyfish) 2024-10-02 01:04:56 -04:00
36debb0eaa RollupJS workaround (fixes #3219 h/t @lvzhenbo) 2024-09-19 19:45:18 -04:00
df48a059c3 Ignore negative sign for a symmetric rounding. 2024-09-18 17:31:02 -07:00
647cdb89f5 Add test files to .gitignore 2024-09-09 18:14:32 -03:00
6912bdb2d4 fix: Add DenseSheetData type (#3195) 2024-09-05 10:25:52 +08:00
5550b90704 fix: infinite loop due to hidden row in XLSX.stream.to_json (#3178)
**Title:**

Fix for Incorrect Row Indexing and Infinite Loop in stream.to_json Function

**Description:**

This pull request addresses two key issues in the `stream.to_json` function of the SheetJS library:

1. **Infinite Loop**: Previously, when a row was hidden, the function skipped processing the current row without incrementing the row counter `R`, resulting in an infinite loop during execution.

2. **Incorrect Row Indexing**: The row index was incorrectly accessed using a one-based index, whereas the actual row index was zero-based. This led to unintended hidden rows being included in the stream and skipping of subsequent non-hidden rows.

**Changes:**

- Modified the hidden row check to use the correct zero-based indexing
- Incremented `R` after identifying a hidden row to ensure the loop progresses to the next row.
- Ensured that the stream correctly processes all rows, skipping hidden rows without affecting subsequent rows.

**Testing:**

- Validated that the `stream.to_json` function no longer enters an infinite loop when encountering hidden rows.
- Confirmed that the correct rows are processed and pushed to the stream, with hidden rows being appropriately skipped.

**Impact:**

This fix enhances the reliability of the SheetJS library, ensuring accurate data streaming from spreadsheets without infinite loops or incorrect row handling.

**Checklist:**

- [x] Code changes have been tested locally.
- [x] The changes adhere to the project's coding standards and guidelines.

**Additional Information:**

These changes are crucial for maintaining the library's functionality in production environments, where precise data handling is essential.

**References:**

Closes #3176.

---

Reviewed-on: sheetjs/sheetjs#3178
Co-authored-by: deepak-negi-web <deepak-negi-web@noreply.git.sheetjs.com>
Co-committed-by: deepak-negi-web <deepak-negi-web@noreply.git.sheetjs.com>
2024-08-21 05:34:31 +00:00
9368a85b5f XLSX encoded entities (fixes #3177)
- HTML DOM ingress support formulae (`data-f`)
- Sheet Visibility for ODS / FODS (fixes #3162)
2024-08-19 12:43:37 -04:00
2669c7cf1c actually remove test_files submodule 2024-07-19 14:57:19 -04:00
b61eed74fc do not bail when XLS properies cannot be parsed 2024-07-17 14:23:02 -04:00
8a7cfd47bd version bump 0.20.3 2024-07-12 11:47:14 -04:00
f215b8f79f merge nits (fixes #3142 h/t @s-ashwin ) 2024-07-11 01:33:25 -04:00
5a36cb423d NaN and Infinity error export
- `read` handle `Int8Array` (to support Java engines)
- `sheet_to_formulae` option to suppress values
- handle unexpected `<charset/>` (fixes #3143 h/t @dearzubi)
2024-07-04 15:54:34 -04:00
5ef49e2b96 XLML Streaming Write
- CSV Export only quote leading ID (fixes #2959)
2024-05-31 03:16:53 -04:00
947a5178bd ssf format NaN and Infinity values 2024-04-27 19:49:12 -04:00
87a695747e docs: ✏️ Fixed broken links in contributing.md 2024-04-10 02:09:14 -07:00
78 changed files with 3844 additions and 823 deletions

2
.gitignore vendored

@ -39,3 +39,5 @@ tmp
*.sheetjs
*.exe
*.img
test_files.zip
test_files/

4
.gitmodules vendored

@ -1,4 +0,0 @@
[submodule "test_files"]
path = test_files
url = https://github.com/SheetJS/test_files
ignore = dirty

@ -4,6 +4,19 @@ 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.
* Sheet Visibility for ODS / FODS (h/t @edemaine)
* HTML DOM ingress support formulae (`data-f`)
* Proper handling of XLSX encoded entities (h/t @inreoh)
* Proper handling of invalid DIF sheets that match heuristics (h/t @lowkeyfish)
## v0.20.3
* Correct parsing of NUMBERS and ODS merge cells (h/t @s-ashwin)
* More precise treatment of infinite and NaN values
* XLML Streaming Write
* Parse `Int8Array` objects (for compatibility with JS engines in Java)
* CSV Export only quote leading ID (h/t @lako12)
## v0.20.2
* Reworked parsing methods to avoid slow regexes (CVE-2024-22363)

@ -1,70 +1,74 @@
# Contributing
The SheetJS Libraries should be free and clear to use in your projects. In
order to maintain that, every contributor must be vigilant.
SheetJS CE should be free and clear to use in your projects. To ensure that
remains true, each contributor must be vigilant and each contribution must be
carefully scrutinized from a technical and legal perspective.
There have been many projects in the past that have been very lax regarding
licensing, and we are of the opinion that those are ticking timebombs and that
no commercial product should depend on them.
Many commercial products and open source projects have been very lax regarding
licensing. They are ticking timebombs that no commercial product should use.
# Required Reading
## Required Reading
These are pretty short reads and emphasize the importance of proper licensing:
- https://github.com/kennethreitz/tablib/issues/114 (discussion of other tools)
- https://web.archive.org/web/20200916173942/https://github.com/jazzband/tablib/issues/114
- http://www.codinghorror.com/blog/2007/04/pick-a-license-any-license.html
- https://web.archive.org/web/20240909210554/https://github.com/stephen-hardy/xlsx.js/issues/8
# Raising Issues
## Raising Issues
Issues should generally be accompanied by test files. Since github does not
support attachments, the best method is to send files to <sheetjs@gmail.com>
(subject line should contain issue number or message) or to share using some
storage service. Unless expressly permitted, any attachments will not be
shared or included in a test suite (although I will ask :)
Issues should generally be accompanied by test files. It is strongly recommended
to use the [issue tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues).
If sending email to a gmail account is problematic, the <dev@sheetjs.com> email
inbox is self-hosted.
If they cannot be shared publicly, please send files to <oss@sheetjs.com>
(subject line should contain issue number or message) or share links to files
hosted on a storage service. Unless expressly permitted, attachments will not be
shared outside of SheetJS LLC or included in a test suite.
# Opening Pull Requests
If a NDA is required, please send an email to <oss@sheetjs.com> with subject
line "Non-Disclosure Agreemeant Request".
Before opening a pull request, [squash all commits into
one](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History). If the pull
request addresses documentation or demos, add `[ci skip]` in the body or title
of your commit message to skip Travis checks.
# Pre-Contribution Checklist
## Opening Pull Requests
Please raise an issue before opening pull requests. It is easy to solve a
specific problem without considering the full context or implications.
## Pre-Contribution Checklist
Before thinking about contributing, make sure that:
- You are not, nor have ever been, an employee of Microsoft Corporation.
- You have not signed any NDAs or Shared Source Agreements with Microsoft
Corporation or a subsidiary
Corporation or a subsidiary.
- You have not consulted any existing relevant codebase (if you have, please
take note of which codebases were consulted).
If you cannot attest to each of these items, the best approach is to raise an
issue. If it is a particularly high-priority issue, please drop an email to
<sheetjs@gmail.com> and it will be prioritized.
issue. If it is a particularly high-priority issue, please drop an email to
<support@sheetjs.com> and it will be prioritized.
# Intra-Contribution
## Intra-Contribution
Keep these in mind as you work:
- Your contributions are your original work. Take note of any resources you
consult in the process (and be extra careful not to use unlicensed code on
the internet.
- Your contributions are your original work. Take note of any resources you
consult in the process. Be extra careful not to use unlicensed code on the
Internet or code generated by a large language model or other AI tool.
- You are working on your own time. Unless they explicitly grant permission,
- You are working on your own time. Unless they explicitly grant permission,
your employer may be the ultimate owner of your IP
# Post-Contribution
Before contributions are merged, you will receive an email (at the address
associated with the git commit) and will be asked to confirm the aforementioned
items. Ensure that the email addresses associated with the commits are valid.
## Post-Contribution
Before certain contributions are merged, you will receive an email (at the
address associated with the git commit) and will be asked to confirm the
aforementioned items. Ensure that the email addresses associated with the
commits are valid.

@ -151,9 +151,13 @@ test-esm: test.mjs ## Run Node ESM test suite
test.ts: test.mts
node -pe 'var data = fs.readFileSync("'$<'", "utf8"); data.split("\n").map(function(l) { return l.replace(/^describe\((.*?)function\(\)/, "Deno.test($$1async function(t)").replace(/\b(?:it|describe)\((.*?)function\(\)/g, "await t.step($$1async function(t)").replace("assert.ok", "assert.assert"); }).join("\n")' > $@
# NOTE: `bun test test.mjs` does not actually run the tests, hence test.test.mjs
test.test.mjs: test.mjs
cp $< $@
.PHONY: test-bun
test-bun: testbun.mjs ## Run Bun test suite
bun $<
test-bun: test.test.mjs ## Run Bun test suite
bun test $<
.PHONY: test-deno
test-deno: test.ts ## Run Deno test suite

@ -31,9 +31,6 @@ encodings for XLS and other legacy spreadsheet formats
- [`dta`](packages/dta): Stata DTA file processor
- [`test_files`](https://github.com/sheetjs/test_files): Test files and various
plaintext baselines.
## License
Please consult the attached LICENSE file for details. All rights not explicitly

@ -2,6 +2,7 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* eslint-env node */
/* vim: set ts=2 ft=javascript: */
var n = "xlsx";
var X = require('../');
try { X = require('../xlsx.flow'); } catch(e) {}
@ -17,7 +18,7 @@ try { program = require('commander'); } catch(e) {
"For older versions of node, explicitly install `xlsx-cli` globally:",
" $ npm i -g xlsx-cli",
" $ xlsx-cli --help"
].forEach(function(m) { console.error(m); });
].forEach(function (m) { console.error(m); });
process.exit(1);
}
program
@ -65,9 +66,10 @@ program
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
.option('-n, --sheet-rows <num>', 'Number of rows to process (0=all rows)')
.option('--date-format <string>', 'output date format, for example yyyy-mm-dd')
.option('--codepage <cp>', 'default to specified codepage when ambiguous')
.option('--req <module>', 'require module before processing')
.option('--sst', 'generate shared string table for XLS* formats')
.option('-d, --no-dim', 'recalculate worksheet range')
.option('--compress', 'use compression when writing XLSX/M/B and ODS')
.option('--read', 'read but do not generate output')
.option('--book', 'for single-sheet formats, emit a file per worksheet')
@ -102,18 +104,18 @@ var wb_formats_2 = [
program.parse(process.argv);
var filename = '', sheetname = '';
if(program.args[0]) {
if (program.args[0]) {
filename = program.args[0];
if(program.args[1]) sheetname = program.args[1];
if (program.args[1]) sheetname = program.args[1];
}
if(program.sheet) sheetname = program.sheet;
if(program.file) filename = program.file;
if (program.sheet) sheetname = program.sheet;
if (program.file) filename = program.file;
if(!filename) {
if (!filename) {
console.error(n + ": must specify a filename");
process.exit(1);
}
if(!fs.existsSync(filename)) {
if (!fs.existsSync(filename)) {
console.error(n + ": " + filename + ": No such file or directory");
process.exit(2);
}
@ -209,15 +211,15 @@ wb_formats_2.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
} });
var target_sheet = sheetname || '';
if(target_sheet === '') {
if(+program.sheetIndex < (wb.SheetNames||[]).length) target_sheet = wb.SheetNames[+program.sheetIndex];
else target_sheet = (wb.SheetNames||[""])[0];
if (target_sheet === '') {
if (+program.sheetIndex < (wb.SheetNames || []).length) target_sheet = wb.SheetNames[+program.sheetIndex];
else target_sheet = (wb.SheetNames || [""])[0];
}
var ws;
try {
ws = wb.Sheets[target_sheet];
if(!ws) {
if (!ws) {
console.error("Sheet " + target_sheet + " cannot be found");
process.exit(3);
}
@ -226,7 +228,7 @@ try {
process.exit(4);
}
if(!program.quiet && !program.book) console.error(target_sheet);
if (!program.quiet && !program.book) console.error(target_sheet);
/* single worksheet file formats */
[
@ -254,21 +256,21 @@ if(!program.quiet && !program.book) console.error(target_sheet);
process.exit(0);
} });
function outit(o, fn) { if(fn) fs.writeFileSync(fn, o); else console.log(o); }
function outit(o, fn) { if (fn) fs.writeFileSync(fn, o); else console.log(o); }
function doit(cb) {
/*:: if(!wb) throw new Error("unreachable"); */
if(program.book) wb.SheetNames.forEach(function(n, i) {
/*:: if(!wb) throw new Error("unreachable"); */
/*:: if (!wb) throw new Error("unreachable"); */
if (program.book) wb.SheetNames.forEach(function (n, i) {
/*:: if (!wb) throw new Error("unreachable"); */
outit(cb(wb.Sheets[n]), (program.output || sheetname || filename) + "." + i);
});
else outit(cb(ws), program.output);
}
var jso = {};
switch(true) {
switch (true) {
case program.formulae:
doit(function(ws) { return X.utils.sheet_to_formulae(ws).join("\n"); });
doit(function (ws) { return X.utils.sheet_to_formulae(ws).join("\n"); });
break;
case program.arrays: jso.header = 1;
@ -276,33 +278,33 @@ switch(true) {
case program.rawJs: jso.raw = true;
/* falls through */
case program.json:
doit(function(ws) { return JSON.stringify(X.utils.sheet_to_json(ws,jso)); });
doit(function (ws) { return JSON.stringify(X.utils.sheet_to_json(ws, jso)); });
break;
default:
if(!program.book) {
var stream = X.stream.to_csv(ws, {FS:program.fieldSep||",", RS:program.rowSep||"\n"});
if(program.output) stream.pipe(fs.createWriteStream(program.output));
if (!program.book) {
var stream = X.stream.to_csv(ws, { FS: program.fieldSep || ",", RS: program.rowSep || "\n" });
if (program.output) stream.pipe(fs.createWriteStream(program.output));
else stream.pipe(process.stdout);
} else doit(function(ws) { return X.utils.sheet_to_csv(ws,{FS:program.fieldSep, RS:program.rowSep}); });
} else doit(function (ws) { return X.utils.sheet_to_csv(ws, { FS: program.fieldSep, RS: program.rowSep }); });
break;
}
function dump_props(wb/*:Workbook*/) {
var propaoa = [];
if(Object.assign && Object.entries) propaoa = Object.entries(Object.assign({}, wb.Props, wb.Custprops));
if (Object.assign && Object.entries) propaoa = Object.entries(Object.assign({}, wb.Props, wb.Custprops));
else {
var Keys/*:: :Array<string> = []*/, pi;
if(wb.Props) {
if (wb.Props) {
Keys = Object.keys(wb.Props);
for(pi = 0; pi < Keys.length; ++pi) {
if(Object.prototype.hasOwnProperty.call(Keys, Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]);
for (pi = 0; pi < Keys.length; ++pi) {
if (Object.prototype.hasOwnProperty.call(Keys, Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]);
}
}
if(wb.Custprops) {
if (wb.Custprops) {
Keys = Object.keys(wb.Custprops);
for(pi = 0; pi < Keys.length; ++pi) {
if(Object.prototype.hasOwnProperty.call(Keys, Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]);
for (pi = 0; pi < Keys.length; ++pi) {
if (Object.prototype.hasOwnProperty.call(Keys, Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]);
}
}
}

@ -1 +1 @@
XLSX.version = '0.20.2';
XLSX.version = '0.20.3';

@ -243,6 +243,7 @@ function SSF_large_exp(v/*:number*/)/*:string*/ {
}
function SSF_general_num(v/*:number*/)/*:string*/ {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -420,7 +421,11 @@ function hashq(str/*:string*/)/*:string*/ {
}
return o;
}
function rnd(val/*:number*/, d/*:number*/)/*:string*/ { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); }
function rnd(val/*:number*/, d/*:number*/)/*:string*/ {
var sgn = val < 0 ? -1 : 1;
var dd = Math.pow(10,d);
return ""+sgn*(Math.round(sgn * val * dd)/dd);
}
function dec(val/*:number*/, d/*:number*/)/*:number*/ {
var _frac = val - Math.floor(val), dd = Math.pow(10,d);
if (d < ('' + Math.round(_frac * dd)).length) return 0;
@ -940,6 +945,8 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -976,6 +983,8 @@ function SSF_format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt/*:string*/, idx/*:?number*/)/*:number*/ {

@ -42,7 +42,9 @@ type CFBFiles = {[n:string]:CFBEntry};
var CRC32 = /*#__PURE__*/(function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*::
type CRC32TableType = Array<number> | Int32Array;
*/
/*global Int32Array */
function signed_crc_table()/*:any*/ {
var c = 0, table/*:Array<number>*/ = new Array(256);
@ -80,7 +82,7 @@ var TT = slice_by_16_tables(T0);
var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4];
var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9];
var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
function crc32_bstr(bstr/*:string*/, seed/*:number*/)/*:number*/ {
function crc32_bstr(bstr/*:string*/, seed/*:?number*/)/*:number*/ {
var C = seed/*:: ? 0 : 0 */ ^ -1;
for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF];
return ~C;
@ -1446,8 +1448,8 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -1458,7 +1460,7 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -1493,9 +1495,10 @@ function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);

@ -67,6 +67,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);

@ -32,6 +32,26 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*
}
return z;
}
function parsexmltagraw(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*/)/*:any*/ {
var z = ({}/*:any*/);
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x/*:string*/)/*:string*/ { return x.replace(nsregex2, "<$1"); }
var encodings = {
@ -47,7 +67,7 @@ var rencoding = /*#__PURE__*/evert(encodings);
// TODO: CP remap (need to read file version to determine OS)
var unescapexml/*:StringConv*/ = /*#__PURE__*/(function() {
/* 22.4.2.4 bstr (Basic String) */
var encregex = /&(?:quot|apos|gt|lt|amp|#x?([\da-fA-F]+));/ig, coderegex = /_x([\da-fA-F]{4})_/ig;
var encregex = /&(?:quot|apos|gt|lt|amp|#x?([\da-fA-F]+));/ig, coderegex = /_x([\da-fA-F]{4})_/g;
function raw_unescapexml(text/*:string*/)/*:string*/ {
var s = text + '', i = s.indexOf("<![CDATA[");
if(i == -1) return s.replace(encregex, function($$, $1) { return encodings[$$]||String.fromCharCode(parseInt($1,$$.indexOf("x")>-1?16:10))||$$; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
@ -133,7 +153,13 @@ function utf8readb(data) {
function utf8readc(data) { return Buffer_from(data, 'binary').toString('utf8'); }
var utf8corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
var utf8read = has_buf && (/*#__PURE__*/utf8readc(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readc || /*#__PURE__*/utf8readb(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readb) || utf8reada;
var utf8read = /*#__PURE__*/(function() {
if(has_buf) {
if(utf8readc(utf8corpus) == utf8reada(utf8corpus)) return utf8readc;
if(utf8readb(utf8corpus) == utf8reada(utf8corpus)) return utf8readb;
}
return utf8reada;
})();
var utf8write/*:StringConv*/ = has_buf ? function(data) { return Buffer_from(data, 'utf8').toString("binary"); } : function(orig/*:string*/)/*:string*/ {
var out/*:Array<string>*/ = [], i = 0, c = 0, d = 0;

@ -20,7 +20,9 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
/* control buffer usage for fixed-length buffers */
function buf_array()/*:BufArray*/ {
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 256 : 2048;
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 16384 : 2048;
var has_buf_subarray = has_buf && (typeof new_buf(blksz).subarray == "function");
var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ {
var o/*:Block*/ = (new_buf(sz)/*:any*/);
prep_blob(o, 0);
@ -49,10 +51,18 @@ function buf_array()/*:BufArray*/ {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
if(curbuf.l > 0) bufs.push(curbuf.slice(0, curbuf.l));
bufs.push(buf);
curbuf = has_buf_subarray ? curbuf.subarray(curbuf.l || 0) : curbuf.slice(curbuf.l || 0);
prep_blob(curbuf, 0);
};
return ({ next:next, push:push, end:end, _bufs:bufs }/*:any*/);
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 }/*:any*/);
}
function write_record(ba/*:BufArray*/, type/*:number*/, payload, length/*:?number*/) {

@ -119,7 +119,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
var ws/*:Worksheet*/ = _ws || (dense ? ({"!data": []}) : ({}/*:any*/));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -144,31 +144,35 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data[R][C] }/*:any*/);
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data_R[C], t:"" }/*:any*/);
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
else if(!o.sheetStubs) continue;
else cell.t = 'z';
}
else if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'number') {
if(isFinite(cell.v)) cell.t = 'n';
else if(isNaN(cell.v)) { cell.t = 'e'; cell.v = 0x0F; /* #VALUE! */ }
else { cell.t = 'e'; cell.v = 0x07; /*# DIV/0 */ }
}
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.z = o.dateNF || table_fmt[14];
@ -182,7 +186,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr/*:any*/;
var cell_ref = encode_col(__C) + (__R + 1)/*:any*/;
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}
@ -192,4 +196,3 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
return ws;
}
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }

@ -123,8 +123,8 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
case 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,'');
case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob);
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);

@ -593,7 +593,7 @@ var SYLK = /*#__PURE__*/(function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -822,7 +822,7 @@ var ETH = /*#__PURE__*/(function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -865,11 +865,7 @@ var ETH = /*#__PURE__*/(function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -879,6 +875,19 @@ var ETH = /*#__PURE__*/(function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -910,6 +919,7 @@ var PRN = /*#__PURE__*/(function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -1027,6 +1037,8 @@ var PRN = /*#__PURE__*/(function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;
@ -1126,3 +1138,17 @@ function read_wb_ID(d, opts) {
}
}
function read_wb_TABL(d, opts) {
var o = opts || {}, OLD_WTF = !!o.WTF; o.WTF = true;
try {
var out = DIF.to_workbook(d, o);
if(!out || !out.Sheets) throw "DIF bad workbook";
var ws = out.Sheets[out.SheetNames[0]];
if(!ws || !ws["!ref"]) throw "DIF empty worksheet";
o.WTF = OLD_WTF;
return out;
} catch(e) {
o.WTF = OLD_WTF;
return PRN.to_workbook(d, opts);
}
}

@ -598,7 +598,6 @@ var WK_ = /*#__PURE__*/(function() {
else console.error("WK1 bad formula parse |" + out.join("|") + "|");
}
function parse_cell_3(blob/*::, length*/) {
var o = [{c:0,r:0}, {t:'n',v:0}, 0];
o[0].r = blob.read_shift(2); o[3] = blob[blob.l++]; o[0].c = blob[blob.l++];

@ -49,6 +49,10 @@ function rtf_to_sheet_str(str, opts) {
if (o.cellText !== false)
cell.w = cell.v;
cell.v = fuzzynum(cell.v);
} else if (RBErr[cell.v] != null) {
cell.t = "e";
cell.w = cell.v;
cell.v = RBErr[cell.v];
}
if (dense)
row[C] = cell;

@ -163,10 +163,12 @@ function parse_fonts(t, styles, themes, opts) {
/* 18.8.2 b CT_BooleanProperty */
case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
case '<b/>': font.bold = 1; break;
case '</b>': case '</b': break;
/* 18.8.26 i CT_BooleanProperty */
case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
case '<i/>': font.italic = 1; break;
case '</i>': case '</i': break;
/* 18.4.13 u CT_UnderlineProperty */
case '<u':
@ -178,48 +180,55 @@ function parse_fonts(t, styles, themes, opts) {
case "doubleAccounting": font.underline = 0x22; break;
} break;
case '<u/>': font.underline = 1; break;
case '</u>': case '</u': break;
/* 18.4.10 strike CT_BooleanProperty */
case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
case '<strike/>': font.strike = 1; break;
case '</strike>': case '</strike': break;
/* 18.4.2 outline CT_BooleanProperty */
case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
case '<outline/>': font.outline = 1; break;
case '</outline>': case '</outline': break;
/* 18.8.36 shadow CT_BooleanProperty */
case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
case '<shadow/>': font.shadow = 1; break;
case '</shadow>': case '</shadow': break;
/* 18.8.12 condense CT_BooleanProperty */
case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
case '<condense/>': font.condense = 1; break;
case '</condense>': case '</condense': break;
/* 18.8.17 extend CT_BooleanProperty */
case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
case '<extend/>': font.extend = 1; break;
case '</extend>': case '</extend': break;
/* 18.4.11 sz CT_FontSize */
case '<sz': if(y.val) font.sz = +y.val; break;
case '<sz/>': case '</sz>': break;
case '<sz/>': case '</sz>': case '</sz': break;
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<vertAlign/>': case '</vertAlign>': case '</vertAlign': break;
/* 18.8.18 family CT_FontFamily */
case '<family': if(y.val) font.family = parseInt(y.val,10); break;
case '<family/>': case '</family>': break;
case '<family/>': case '</family>': case '</family': break;
/* 18.8.35 scheme CT_FontScheme */
case '<scheme': if(y.val) font.scheme = y.val; break;
case '<scheme/>': case '</scheme>': break;
case '<scheme/>': case '</scheme>': case '</scheme': break;
/* 18.4.1 charset CT_IntProperty */
case '<charset':
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': case '</charset': break;
/* 18.?.? color CT_Color */
case '<color':
@ -242,11 +251,11 @@ function parse_fonts(t, styles, themes, opts) {
}
break;
case '<color/>': case '</color>': break;
case '<color/>': case '</color>': case '</color': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
case '</AlternateContent>': case '</AlternateContent': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;

@ -52,6 +52,10 @@ function parse_xlmeta_bin(data, name, _opts) {
var metatype = 2;
recordhopper(data, function(val, R, RT) {
switch (RT) {
case 58:
break;
case 59:
break;
case 335:
out.Types.push({ name: val.name });
break;

@ -35,6 +35,7 @@ function parse_xlink_bin(data, rel, name/*:string*/, _opts) {
case 0x0249: /* 'BrtSupNameFmla' */
case 0x024A: /* 'BrtSupNameBits' */
case 0x024B: /* 'BrtSupNameEnd' */
case 0x13F4: /* 'BrtExternalLinksAlternateUrls' */
break;
case 0x0023: /* 'BrtFRTBegin' */

@ -23,9 +23,10 @@ var rc_to_a1 = /*#__PURE__*/(function(){
};
})();
var crefregex = /(^|[^._A-Z0-9])(\$?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])(\$?)(\d{1,7})(?![_.\(A-Za-z0-9])/g;
/* TODO: check if engines support \b */
var crefregex = /(^|[^._A-Za-z0-9])(\$?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])(\$?)(\d{1,7})(?![_.\(A-Za-z0-9])/g;
try {
crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)(10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6]|[1-9]\d{0,5})(?![_.\(A-Za-z0-9])/g;
crefregex = /(^|[^._A-Za-z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)(10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6]|[1-9]\d{0,5})(?![_.\(A-Za-z0-9])/g;
}catch(e){}
var a1_to_rc = /*#__PURE__*/(function(){
return function a1_to_rc(fstr/*:string*/, base/*:CellAddress*/) {

@ -6,7 +6,7 @@ var mergecregex = /<(?:\w+:)?mergeCell ref=["'][A-Z0-9:]+['"]\s*[\/]?>/g;
var hlinkregex = /<(?:\w+:)?hyperlink [^<>]*>/mg;
var dimregex = /"(\w*:\w*)"/;
var colregex = /<(?:\w+:)?col\b[^<>]*[\/]?>/g;
var afregex = /<(?:\w+:)?autoFilter[^>]*/g;
var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g;
var marginregex= /<(?:\w+:)?pageMargins[^<>]*\/>/g;
var sheetprregex = /<(?:\w+:)?sheetPr\b[^<>]*?\/>/;
@ -62,7 +62,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
var merges/*:Array<Range>*/ = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -217,7 +217,7 @@ function write_ws_xml_cols(ws, cols)/*:string*/ {
}
function parse_ws_xml_autofilter(data/*:string*/) {
var o = { ref: (data.match(/ref="([^"]*)"/)||[])[1]};
var o = { ref: (data.match(/ref=["']([^"']*)["']/)||[])[1]};
return o;
}
function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
@ -521,16 +521,17 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*//*::, rels*/)/*:string*/ {
var o/*:Array<string>*/ = [], r/*:Array<string>*/ = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols/*:Array<string>*/ = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
for(C = range.s.c; C <= range.e.c; ++C) {
var data_R = dense ? data[R] : [];
if(data_R) for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}

@ -505,7 +505,7 @@ function parse_BrtDVal(/*data, length, opts*/) {
}
function parse_BrtDVal14(/*data, length, opts*/) {
}
/* [MS-XLSB] 2.1.7.61 Worksheet */
/* [MS-XLSB] 2.1.7.62 Worksheet */
function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ {
if(!data) return data;
var opts = _opts || {};
@ -847,12 +847,15 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) {
if(last_seen) write_record(ba, 0x000D /* BrtShortRk */, write_BrtShortRk(cell, o));
else write_record(ba, 0x0002 /* BrtCellRk */, write_BrtCellRk(cell, o));
} else if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else if(!isFinite(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
o.t = "e";
if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
}
} else {
if(last_seen) write_record(ba, 0x0010 /* BrtShortReal */, write_BrtShortReal(cell, o));
else write_record(ba, 0x0005 /* BrtCellReal */, write_BrtCellReal(cell, o));
@ -874,23 +877,24 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
}
function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols/*:Array<string>*/ = [];
var range = safe_decode_range(ws['!ref'] || "A1"), rr = "", cols/*:Array<string>*/ = [];
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
write_record(ba, 0x0091 /* BrtBeginSheetData */);
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, row = dense ? ws["!data"][range.s.r] : [];
var cap = range.e.r;
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
for(var R = range.s.r; R <= cap; ++R) {
rr = encode_row(R);
if(dense) row = ws["!data"][R];
/* [ACCELLTABLE] */
/* BrtRowHdr */
write_row_header(ba, ws, range, R);
if(dense && !row) continue;
var last_seen = false;
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
var cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) { last_seen = false; continue; }
/* write cell */
last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904);

@ -1144,7 +1144,13 @@ function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb,
var t = "", p = "";
switch(cell.t) {
case 'z': if(!opts.sheetStubs) return ""; break;
case 'n': t = 'Number'; p = String(cell.v); break;
case 'n': {
if(!isFinite(cell.v)) {
t = 'Error'; p = BErr[isNaN(cell.v) ? 0x24 : 0x07];
} else {
t = 'Number'; p = String(cell.v);
}
} break;
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
case 'e': t = 'Error'; p = BErr[cell.v]; break;
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || table_fmt[14]; break;
@ -1186,9 +1192,12 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
o.push(writextag("Column",null,k));
});
var dense = ws["!data"] != null;
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
@ -1199,7 +1208,6 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
break;
}
if(skip) continue;
var addr = {r:R,c:C};
var ref = encode_col(C) + encode_row(R), cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr));
}
@ -1223,7 +1231,7 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
/* WorksheetOptions */
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
if(ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
if(ws && ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
return o.join("");
}
@ -1242,11 +1250,10 @@ function write_xlml(wb, opts)/*:string*/ {
d.push(write_props_xlml(wb, opts));
d.push(write_wb_xlml(wb, opts));
d.push("");
d.push("");
d.push(write_names_xlml(wb, opts));
for(var i = 0; i < wb.SheetNames.length; ++i)
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
d[2] = write_sty_xlml(wb, opts);
d[3] = write_names_xlml(wb, opts);
return XML_HEADER + writextag("Workbook", d.join(""), {
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,

@ -627,14 +627,14 @@ function parse_xls_props(cfb/*:CFBContainer*/, props, o) {
if(DSI && DSI.size > 0) try {
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI);
for(var d in DocSummary) props[d] = DocSummary[d];
} catch(e) {if(o.WTF) throw e;/* empty */}
} catch(e) {if(o.WTF) console.error(e && e.message || e);}
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
var SI = CFB.find(cfb, '/!SummaryInformation');
if(SI && SI.size > 0) try {
var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI);
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
} catch(e) {if(o.WTF) throw e;/* empty */}
} catch(e) {if(o.WTF) console.error(e && e.message || e);}
if(props.HeadingPairs && props.TitlesOfParts) {
load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o);

@ -856,6 +856,25 @@ var XLSBRecordEnum = {
0x13E8: { /* n:"BrtEndCalcFeatures", */ T:-1 },
0x13E9: { /* n:"BrtCalcFeature" */ },
0x13EB: { /* n:"BrtExternalLinksPr" */ },
0x13EC: { /* n:"BrtPivotCacheImplicitMeasureSupport" */ },
0x13ED: { /* n:"BrtPivotFieldIgnorableAfter" */ },
0x13EE: { /* n:"BrtPivotHierarchyIgnorableAfter" */ },
0x13EF: { /* n:"BrtPivotDataFieldFutureData" */ },
0x13F1: { /* n:"BrtPivotCacheRichData" */ },
0x13F4: { /* n:"BrtExternalLinksAlternateUrls" */ },
0x13F5: { /* n:"BrtBeginPivotVersionInfo" */ },
0x13F6: { /* n:"BrtEndPivotVersionInfo" */ },
0x13F7: { /* n:"BrtBeginCacheVersionInfo" */ },
0x13F8: { /* n:"BrtEndCacheVersionInfo" */ },
0x13F9: { /* n:"BrtPivotRequiredFeature" */ },
0x13FA: { /* n:"BrtPivotLastUsedFeature" */ },
0x13FD: { /* n:"BrtExternalCodeService" */ },
0x1407: { /* n:"BrtShowDataTypeIcons" */ },
0x140A: { /* n:"BrtSXDIAggregation" */ },
0x140B: { /* n:"BrtPivotFieldFeatureSupportInfo" */ },
0x140C: { /* n:"BrtPivotCacheAutoRefresh" */ },
0x140E: { /* n:"BrtShowDataTypeIconsUserShView" */ },
0x140F: { /* n:"BrtWorkbookCompatibilityVersion" */ },
0xFFFF: { n:"" }
};

@ -105,7 +105,7 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts,
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, 0x3FFF);
range.e.r = Math.min(range.e.r, 0x3FFF);
}
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
var row = [], comments = [];
@ -431,8 +431,54 @@ function write_FMTS_biff8(ba, NF/*:?SSFTable*/, opts) {
});
}
function write_ws_protect_biff8(sp) {
/* SheetProtection */
var flags = 0x0000;
[
["objects", false, 0x0001], // fObjects - Bit 0 (Edit objects)
["scenarios", false, 0x0002], // fScenarios - Bit 1 (Edit scenarios)
["formatCells", true, 0x0004], // fFormatCells - Bit 2 (Change cell formatting)
["formatColumns", true, 0x0008], // fFormatColumns - Bit 3 (Change column formatting)
["formatRows", true, 0x0010], // fFormatRows - Bit 4 (Change row formatting)
["insertColumns", true, 0x0020], // fInsertColumns - Bit 5 (Insert columns)
["insertRows", true, 0x0040], // fInsertRows - Bit 6 (Insert rows)
["insertHyperlinks", true, 0x0080], // fInsertHyperlinks - Bit Bit 7 (Insert hyperlinks)
["deleteColumns", true, 0x0100], // fDeleteColumns - Bit 8 (Delete columns)
["deleteRows", true, 0x0200], // fDeleteRows - Bit 9 (Delete rows)
["selectLockedCells", false, 0x0400], // fSelLockedCells - Bit 10 (Select locked cells)
["sort", true, 0x0800], // fSort - Bit 11 (Sort a cell range)
["autoFilter", true, 0x1000], // fAutoFilter - Bit 12 (Edit auto filters)
["pivotTables", true, 0x2000], // fPivotTables - Bit 13 (Edit PivotTables)
["selectUnlockedCells", false, 0x4000] // fSelUnlockedCells - Bit 14 (Select unlocked cells)
].forEach(function(n) {
if(n[1]) flags |= sp[n[0]] != null && !sp[n[0]] ? n[2] : 0x0000;
else flags |= sp[n[0]] != null && sp[n[0]] ? 0x0000 : n[2];
});
/* [MS-XLS] 2.4.112 */
var featHdr = new_buf(23);
/* [MS-XLS] 2.5.135 */
featHdr.write_shift(2, 0x0867);
featHdr.write_shift(2, 0x0000);
featHdr.write_shift(4, 0x00000000);
featHdr.write_shift(4, 0x00000000);
/* [MS-XLS] 2.5.237 */
featHdr.write_shift(2, 0x0002); // SharedFeatureType ISFPROTECTION
/* Reserved byte */
featHdr.write_shift(1, 0x01);
/* cbHdrData */
featHdr.write_shift(4, 0xffffffff);
/* [MS-XLS] 2.5.104 */
featHdr.write_shift(4, flags);
return featHdr;
}
function write_FEAT(ba, ws) {
/* [MS-XLS] 2.4.112 */
/* ISFPROTECTION */
if(ws['!protect']) write_biff_rec(ba, 0x0867 /* FeatHdr */, write_ws_protect_biff8(ws['!protect']));
/* ISFFEC2 */
var o = new_buf(19);
o.write_shift(4, 0x867); o.write_shift(4, 0); o.write_shift(4, 0);
o.write_shift(2, 3); o.write_shift(1, 1); o.write_shift(4, 0);
@ -515,9 +561,9 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
var range = safe_decode_range(ws['!ref'] || "A1");
var MAX_ROWS = b8 ? 65536 : 16384;
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV" + MAX_ROWS);
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
range.e.r = Math.min(range.e.r, MAX_ROWS-1);
}
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
@ -537,6 +583,14 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
/* Footer (string) */
write_biff_rec(ba, 0x0083 /* HCenter */, writebool(false));
write_biff_rec(ba, 0x0084 /* VCenter */, writebool(false));
/* PROTECTION */
if(ws['!protect']){
var sp = ws['!protect'];
/* [MS-XLS] 2.4.207 */
write_biff_rec(ba, 0x0012 /* Protect */, writeuint16(1));
/* [MS-XLS] 2.4.191 */
if(sp.password) write_biff_rec(ba, 0x0013 /* Password */, writeuint16(crypto_CreatePasswordVerifier_Method1(sp.password)));
}
/* ... */
if(b8) write_ws_cols_biff8(ba, ws["!cols"]);
/* ... */
@ -552,12 +606,11 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
if(dense) row = ws["!data"][R] || [];
rr = encode_row(R);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var cell = dense ? row[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) continue;
/* write cell */
write_ws_biff8_cell(ba, cell, R, C, opts, date1904);
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
if(b8 && cell.l) ws['!links'].push([cols[C] + rr, cell.l]);
if(cell.c) comments.push([cell.c, R, C]);
}
}
@ -701,6 +754,9 @@ function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
if(range.e.c > 255) { // note: 255 is IV
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond column IV (255). Data may be lost.");
}
if(range.e.r > 65535) {
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond row 65536. Data may be lost.");
}
}
var o = opts || {};

@ -48,6 +48,8 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
if(opts.UTC === false) o.v = utc_to_local(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
} else if(m.charCodeAt(0) == 35 /* # */ && RBErr[m] != null) {
o.t = 'e'; o.w = m; o.v = RBErr[m];
}
if(o.cellText !== false) o.w = m;
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
@ -75,6 +77,10 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
if(RS < 0) continue;
var coord = encode_col(C) + encode_row(R);
var cell = dense ? (ws["!data"][R]||[])[C] : ws[coord];
if(cell && cell.t == 'n' && cell.v != null && !isFinite(cell.v)) {
if(isNaN(cell.v)) cell = ({t:'e', v:0x24, w:BErr[0x24]});
else cell = ({t:'e', v:0x07, w:BErr[0x07]});
}
/* TODO: html entities */
var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
sp = ({}/*:any*/);
@ -86,6 +92,7 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
// note: data-v is unaffected by the timezone interpretation
if(cell.v != null) sp["data-v"] = escapehtml(cell.v instanceof Date ? cell.v.toISOString() : cell.v);
if(cell.z != null) sp["data-z"] = cell.z;
if(cell.f != null) sp["data-f"] = escapehtml(cell.f);
if(cell.l && (cell.l.Target || "#").charAt(0) != "#") w = '<a href="' + escapehtml(cell.l.Target) +'">' + w + '</a>';
}
sp.id = (o.id || "sjs") + "-" + coord;
@ -130,12 +137,6 @@ function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*//*, wb:?Workboo
}
function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
var rows/*:HTMLCollection<HTMLTableRowElement>*/ = table.rows;
if(!rows) {
/* not an HTML TABLE */
throw "Unsupported origin when " + table.tagName + " is not a TABLE";
}
var opts = _opts || {};
var dense = ws["!data"] != null;
var or_R = 0, or_C = 0;
@ -147,7 +148,6 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
}
}
var sheetRows = Math.min(opts.sheetRows||10000000, rows.length);
var range/*:Range*/ = {s:{r:0,c:0},e:{r:or_R,c:or_C}};
if(ws["!ref"]) {
var _range/*:Range*/ = decode_range(ws["!ref"]);
@ -157,6 +157,15 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
range.e.c = Math.max(range.e.c, _range.e.c);
if(or_R == -1) range.e.r = or_R = _range.e.r + 1;
}
var rows/*:HTMLCollection<HTMLTableRowElement>*/ = table.rows;
if(!rows) {
/* not an HTML TABLE */
throw "Unsupported origin when " + table.tagName + " is not a TABLE";
}
var sheetRows = Math.min(opts.sheetRows||10000000, rows.length);
var merges/*:Array<Range>*/ = [], midx = 0;
var rowinfo/*:Array<RowInfo>*/ = ws["!rows"] || (ws["!rows"] = []);
var _R = 0, R = 0, _C = 0, C = 0, RS = 0, CS = 0;
@ -173,18 +182,22 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if (opts.display && is_dom_element_hidden(elt)) continue;
var v/*:?string*/ = elt.hasAttribute('data-v') ? elt.getAttribute('data-v') : elt.hasAttribute('v') ? elt.getAttribute('v') : htmldecode(elt.innerHTML);
var z/*:?string*/ = elt.getAttribute('data-z') || elt.getAttribute('z');
var f/*:?string*/ = elt.hasAttribute('data-f') ? elt.getAttribute('data-f') : elt.hasAttribute('f') ? elt.getAttribute('f') : null;
for(midx = 0; midx < merges.length; ++midx) {
var m/*:Range*/ = merges[midx];
if(m.s.c == C + or_C && m.s.r < R + or_R && R + or_R <= m.e.r) { C = m.e.c+1 - or_C; midx = -1; }
}
/* TODO: figure out how to extract nonstandard mso- style */
CS = +elt.getAttribute("colspan") || 1;
if( ((RS = (+elt.getAttribute("rowspan") || 1)))>1 || CS>1) merges.push({s:{r:R + or_R,c:C + or_C},e:{r:R + or_R + (RS||1) - 1, c:C + or_C + (CS||1) - 1}});
if( ((RS = (+elt.getAttribute("rowspan") || 1)))>1 || CS>1) {
merges.push({s:{r:R + or_R,c:C + or_C},e:{r:R + or_R + (RS||1) - 1, c:C + or_C + (CS||1) - 1}});
}
var o/*:Cell*/ = {t:'s', v:v};
var _t/*:string*/ = elt.getAttribute("data-t") || elt.getAttribute("t") || "";
if(v != null) {
if(v.length == 0) o.t = _t || 'z';
else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(_t == "e" && BErr[+v]) o = {t:'e', v:+v, w: BErr[+v]};
else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -193,7 +206,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(opts.UTC) o.v = local_to_utc(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
}
} else if(v.charCodeAt(0) == 35 /* # */ && RBErr[v] != null) o = ({t:'e', v: RBErr[v], w: v});
}
if(o.z === undefined && z != null) o.z = z;
/* The first link is used. Links are assumed to be fully specified.
@ -203,6 +216,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
l = Aelts[Aelti].getAttribute("href"); if(l.charAt(0) != "#") break;
}
if(l && l.charAt(0) != "#" && l.slice(0, 11).toLowerCase() != 'javascript:') o.l = ({ Target: l });
if(f != null) o.f = f;
if(dense) { if(!ws["!data"][R + or_R]) ws["!data"][R + or_R] = []; ws["!data"][R + or_R][C + or_C] = o; }
else ws[encode_cell({c:C + or_C, r:R + or_R})] = o;
if(range.e.c < C + or_C) range.e.c = C + or_C;

@ -205,7 +205,7 @@ function parse_ods_styles(d/*:string*/, _opts, _nfm) {
// TODO: handle more complex maps
y = parsexmltag(Rn[0], false);
if(unescapexml(y["condition"]) == "value()>=0") NF = number_format_map[y["apply-style-name"]] + ";" + NF;
else console.error("ODS number format may be incorrect: " + y["condition"]);
else if(_opts && _opts.WTF) console.error("ODS number format may be incorrect: " + y["condition"]);
break;
case 'number': // <number:number> 16.29.3
@ -247,16 +247,16 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
var Sheets = {}, SheetNames/*:Array<string>*/ = [];
var ws = ({}/*:any*/); if(opts.dense) ws["!data"] = [];
var Rn, q/*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
var ctag = ({value:""}/*:any*/);
var ctag = ({value:""}/*:any*/), ctag2 = ({}/*:any*/);
var textp = "", textpidx = 0, textptag/*:: = {}*/, oldtextp = "", oldtextpidx = 0;
var textR = [], oldtextR = [];
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
var row_ol = 0;
var number_format_map = _nfm || {}, styles = {};
var number_format_map = _nfm || {}, styles = {}, tstyles = {};
var merges/*:Array<Range>*/ = [], mrange = {}, mR = 0, mC = 0;
var rowinfo/*:Array<RowInfo>*/ = [], rowpeat = 1, colpeat = 1;
var arrayf/*:Array<[Range, string]>*/ = [];
var WB = {Names:[], WBProps:{}};
var WB = {Names:[], WBProps:{}, Sheets:[]};
var atag = ({}/*:any*/);
var _Ref/*:[string, string]*/ = ["", ""];
var comments/*:Array<Comment>*/ = [], comment/*:Comment*/ = ({}/*:any*/);
@ -282,6 +282,10 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(typeof JSON !== 'undefined') JSON.stringify(sheetag);
SheetNames.push(sheetag.name);
Sheets[sheetag.name] = ws;
WB.Sheets.push({
/* TODO: CodeName */
Hidden: (tstyles[sheetag["style-name"]] && tstyles[sheetag["style-name"]]["display"] ? (parsexmlbool(tstyles[sheetag["style-name"]]["display"]) ? 0 : 1) : 0)
});
intable = false;
}
else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
@ -306,10 +310,18 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
C = -1; break;
case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
if(Rn[1] !== '/') ++C;
if(opts.sheetStubs) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
if(Rn[1] !== '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1",10) || 1;
if(opts.sheetStubs) {
while(colpeat-- > 0) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
++C;
} --C;
}
else C += colpeat - 1;
}
textp = ""; textR = [];
break; /* stub */
@ -317,7 +329,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(Rn[0].charAt(Rn[0].length-2) === '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10)||1;
q = ({t:'z', v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -341,6 +353,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(R < range.s.r) range.s.r = R;
if(rptR > range.e.r) range.e.r = rptR;
ctag = parsexmltag(Rn[0], false);
ctag2 = parsexmltagraw(Rn[0], true);
comments = []; comment = ({}/*:any*/);
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -360,10 +373,12 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
q.F = arrayf[i][1];
}
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
mC = parseInt(ctag['number-columns-spanned'],10) || 0;
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
mR = parseInt(ctag['number-rows-spanned']||"1",10) || 1;
mC = parseInt(ctag['number-columns-spanned']||"1",10) || 1;
if(mR * mC > 1) {
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
}
}
/* 19.675.2 table:number-columns-repeated */
@ -394,6 +409,9 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
}
} else {
isstub = false;
if(ctag2['calcext:value-type'] == "error" && RBErr[textp] != null) {
q.t = 'e'; q.w = textp; q.v = RBErr[textp];
}
if(q.t === 's') {
q.v = textp || '';
if(textR.length) q.R = textR;
@ -515,12 +533,16 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
case 'style': { // 16.2 <style:style>
var styletag = parsexmltag(Rn[0], false);
if(styletag["family"] == "table-cell" && number_format_map[styletag["data-style-name"]]) styles[styletag["name"]] = number_format_map[styletag["data-style-name"]];
else if(styletag["family"] == "table") tstyles[styletag["name"]] = styletag;
} break;
case 'map': break; // 16.3 <style:map>
case 'font-face': break; // 16.21 <style:font-face>
case 'paragraph-properties': break; // 17.6 <style:paragraph-properties>
case 'table-properties': break; // 17.15 <style:table-properties>
case 'table-properties': { // 17.15 <style:table-properties>
var proptag = parsexmltag(Rn[0], false);
if(styletag && styletag.family == "table") styletag.display = proptag.display;
} break;
case 'table-column-properties': break; // 17.16 <style:table-column-properties>
case 'table-row-properties': break; // 17.17 <style:table-row-properties>
case 'table-cell-properties': break; // 17.18 <style:table-cell-properties>
@ -742,6 +764,10 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
_Ref = ods_to_csf_3D(atag.Target.slice(1));
atag.Target = "#" + _Ref[0] + "!" + _Ref[1];
} else if(atag.Target.match(/^\.\.[\\\/]/)) atag.Target = atag.Target.slice(3);
/* Appendix D.2 Hyperlink Titles */
if(atag.title) {
atag.Tooltip = unescapexml(atag.title); delete atag.title;
}
}
break;
@ -792,4 +818,3 @@ function parse_fods(data/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
wb.bookType = "fods";
return wb;
}

@ -214,7 +214,9 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
var write_ws = function(ws, wb/*:Workbook*/, i/*:number*/, opts, nfs, date1904)/*:string*/ {
/* Section 9 Tables */
var o/*:Array<string>*/ = [];
o.push(' <table:table table:name="' + escapexml(wb.SheetNames[i]) + '" table:style-name="ta1">\n');
var tstyle = "ta1";
if(((((wb||{}).Workbook||{}).Sheets||[])[i]||{}).Hidden) tstyle = "ta2";
o.push(' <table:table table:name="' + escapexml(wb.SheetNames[i]) + '" table:style-name="' + tstyle + '">\n');
var R=0,C=0, range = decode_range(ws['!ref']||"A1");
var marr/*:Array<Range>*/ = ws['!merges'] || [], mi = 0;
var dense = ws["!data"] != null;
@ -262,9 +264,22 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
break;
case 'n':
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
if(!isFinite(cell.v)) {
if(isNaN(cell.v)) {
textp = "#NUM!";
ct['table:formula'] = "of:=#NUM!";
} else {
textp = "#DIV/0!";
ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
}
ct['office:string-value'] = "";
ct['office:value-type'] = "string";
ct['calcext:value-type'] = "error";
} else {
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
}
break;
case 's': case 'str':
textp = cell.v == null ? "" : cell.v;
@ -349,6 +364,9 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
o.push(' <style:style style:name="ta1" style:family="table" style:master-page-name="mp1">\n');
o.push(' <style:table-properties table:display="true" style:writing-mode="lr-tb"/>\n');
o.push(' </style:style>\n');
o.push(' <style:style style:name="ta2" style:family="table" style:master-page-name="mp1">\n');
o.push(' <style:table-properties table:display="false" style:writing-mode="lr-tb"/>\n');
o.push(' </style:style>\n');
o.push(' <number:date-style style:name="N37" number:automatic-order="true">\n');
o.push(' <number:month number:style="long"/>\n');

@ -1117,7 +1117,7 @@ function s5s_to_iwa_comment(s5s) {
return out;
}
function parse_TST_TableModelArchive(M, root, ws, opts) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
var pb = parse_shallow(root.data);
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
@ -1196,6 +1196,38 @@ function parse_TST_TableModelArchive(M, root, ws, opts) {
};
});
}
if (!((_k = ws["!merges"]) == null ? void 0 : _k.length) && ((_l = pb[47]) == null ? void 0 : _l[0])) {
var merge_owner = parse_shallow(pb[47][0].data);
if ((_m = merge_owner[2]) == null ? void 0 : _m[0]) {
var formula_store = parse_shallow(merge_owner[2][0].data);
if ((_n = formula_store[3]) == null ? void 0 : _n[0]) {
ws["!merges"] = mappa(formula_store[3], function(u) {
var _a2, _b2, _c2, _d2, _e2;
var formula_pair = parse_shallow(u);
var formula = parse_shallow(formula_pair[2][0].data);
var AST_node_array = parse_shallow(formula[1][0].data);
if (!((_a2 = AST_node_array[1]) == null ? void 0 : _a2[0]))
return;
var AST_node0 = parse_shallow(AST_node_array[1][0].data);
var AST_node_type = varint_to_i32(AST_node0[1][0].data);
if (AST_node_type != 67)
return;
var AST_colon_tract = parse_shallow(AST_node0[40][0].data);
if (!((_b2 = AST_colon_tract[3]) == null ? void 0 : _b2[0]) || !((_c2 = AST_colon_tract[4]) == null ? void 0 : _c2[0]))
return;
var colrange = parse_shallow(AST_colon_tract[3][0].data);
var rowrange = parse_shallow(AST_colon_tract[4][0].data);
var c = varint_to_i32(colrange[1][0].data);
var C = ((_d2 = colrange[2]) == null ? void 0 : _d2[0]) ? varint_to_i32(colrange[2][0].data) : c;
var r = varint_to_i32(rowrange[1][0].data);
var R = ((_e2 = rowrange[2]) == null ? void 0 : _e2[0]) ? varint_to_i32(rowrange[2][0].data) : r;
return { s: { r: r, c: c }, e: { r: R, c: C } };
}).filter(function(x) {
return x != null;
});
}
}
}
}
function parse_TST_TableInfoArchive(M, root, opts) {
var pb = parse_shallow(root.data);

@ -75,6 +75,8 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var o = opts||{};
if(o.codepage && typeof $cptable === "undefined") console.error("Codepage tables are not loaded. Non-ASCII characters may not give expected results");
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
/* Javet projects `byte[]` to `Int8Array` */
if(typeof Int8Array !== 'undefined' && data instanceof Int8Array) return readSync(new Uint8Array(data.buffer, data.byteOffset, data.length), 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; }
@ -97,7 +99,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
if(n[1] === 0x49 && n[2] === 0x2a && n[3] === 0x00) throw new Error("TIFF Image File is not a spreadsheet");
if(n[1] === 0x44) return read_wb_ID(d, o);
break;
case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o); break;
case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return read_wb_TABL(d, o); break;
case 0x50: return (n[1] === 0x4B && n[2] < 0x09 && n[3] < 0x09) ? read_zip(d, o) : read_prn(data, d, o, str);
case 0xEF: return n[3] === 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
case 0xFF:

@ -111,7 +111,7 @@ function write_binary_type(out, opts/*:WriteOpts*/)/*:any*/ {
function writeSyncXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
reset_cp();
check_wb(wb);
if(!opts || !opts.unsafe) check_wb(wb);
var o = dup(opts||{});
if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSyncXLSX(wb, o)/*:any*/); o.type = "array"; return s2ab(out); }
@ -120,7 +120,7 @@ function writeSyncXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
reset_cp();
check_wb(wb);
if(!opts || !opts.unsafe) check_wb(wb);
var o = dup(opts||{});
if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSync(wb, o)/*:any*/); o.type = "array"; return s2ab(out); }

@ -24,7 +24,7 @@ function make_json_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Ar
switch(val.t){
case 'z': if(v == null) break; continue;
case 'e': v = (v == 0 ? null : void 0); break;
case 's': case 'b':
case 's': case 'b': break;
case 'n': if(!val.z || !fmt_is_date(val.z)) break;
v = numdate(v); // TODO: date1904 setting should also be stored in worksheet object
if(typeof v == "number") break;
@ -104,7 +104,7 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) {
}
var qreg = /"/g;
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, w/*:number*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
var isempty = true;
var row/*:Array<string>*/ = [], txt = "", rr = encode_row(R);
var dense = sheet["!data"] != null;
@ -116,8 +116,8 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr
else if(val.v != null) {
isempty = false;
txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
if(txt == "ID") txt = '"ID"';
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 10 ||cc === 13 || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"';
} else if(val.f != null && !val.F) {
isempty = false;
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
@ -144,7 +144,7 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
var w = 0;
for(var R = r.s.r; R <= r.e.r; ++R) {
if ((rowinfo[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o);
if(row == null) { continue; }
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
}
@ -159,7 +159,7 @@ function sheet_to_txt(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
function sheet_to_formulae(sheet/*:Worksheet*/, opts/*:?Sheet2FormulaOpts*/)/*:Array<string>*/ {
var y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols/*:Array<string>*/ = [], C;
@ -180,6 +180,7 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
if(y.indexOf(":") == -1) y = y + ":" + y;
}
if(x.f != null) val = x.f;
else if(opts && opts.values === false) continue;
else if(x.t == 'z') continue;
else if(x.t == 'n' && x.v != null) val = "" + x.v;
else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";

@ -19,7 +19,7 @@ function write_csv_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
while(R <= r.e.r) {
++R;
if ((rowinfo[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, w, o);
if(row != null) {
if(row || (o.blankrows !== false)) return stream.push((w++ ? RS : "") + row);
}
@ -103,7 +103,10 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
R = r.s.r + offset;
stream._read = function() {
while(R <= r.e.r) {
if ((rowinfo[R-1]||{}).hidden) continue;
if ((rowinfo[R]||{}).hidden) {
++R;
continue;
};
var row = make_json_row(sheet, r, R, cols, header, hdr, o);
++R;
if((row.isempty === false) || (header === 1 ? o.blankrows !== false : !!o.blankrows)) {
@ -116,9 +119,164 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
return stream;
}
function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
var stream = _Readable();
var opts = o == null ? {} : o;
var stride = +opts.stride || 10;
if(!wb.SSF) wb.SSF = dup(table_fmt);
if(wb.SSF) {
make_ssf(); SSF_load_table(wb.SSF);
// $FlowIgnore
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
opts.ssf = wb.SSF;
opts.cellXfs = [];
get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
}
/* do one pass to determine styles since they must be added before tables */
wb.SheetNames.forEach(function(n) {
var ws = wb.Sheets[n];
if(!ws || !ws["!ref"]) return;
var range = decode_range(ws["!ref"]);
var dense = ws["!data"] != null;
var ddata = dense ? ws["!data"] : [];
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
addr.r = R;
if(dense && !ddata[R]) continue;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var cell = dense ? ddata[R][C] : ws[encode_col(C) + encode_row(R)];
if(!cell) continue;
if(cell.t == "d" && cell.z == null) { cell = dup(cell); cell.z = table_fmt[14]; }
void get_cell_style(opts.cellXfs, cell, opts);
}
}
});
var sty = write_sty_xlml(wb, opts);
var stage = 0, wsidx = 0, ws = wb.Sheets[wb.SheetNames[wsidx]], range = safe_decode_range(ws), R = -1, T = false;
var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
stream._read = function() { switch(stage) {
/* header */
case 0: {
stage = 1;
stream.push(XML_HEADER);
stream.push("<Workbook" + wxt_helper({
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
'xmlns:x': XLMLNS.x,
'xmlns:ss': XLMLNS.ss,
'xmlns:dt': XLMLNS.dt,
'xmlns:html': XLMLNS.html
}) + ">");
} break;
/* preamble */
case 1: {
stage = 2;
stream.push(write_props_xlml(wb, opts));
stream.push(write_wb_xlml(wb, opts));
} break;
/* style and name tables */
case 2: {
stage = 3;
stream.push(sty);
stream.push(write_names_xlml(wb, opts));
} break;
/* worksheet preamble */
case 3: {
T = false;
if(wsidx >= wb.SheetNames.length) { stage = -1; stream.push(""); break; }
stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
ws = wb.Sheets[wb.SheetNames[wsidx]];
if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
var names = write_ws_xlml_names(ws, opts, wsidx, wb);
if(names.length) stream.push("<Names>" + names + "</Names>");
if(!ws["!ref"]) return (stage = 5);
range = safe_decode_range(ws["!ref"]);
R = range.s.r;
stage = 4;
} break;
/* worksheet intramble */
case 4: {
if(R < 0 || R > range.e.r) { if(T) stream.push("</Table>"); return void (stage = 5); }
if(R <= range.s.r) {
if(ws['!cols']) ws['!cols'].forEach(function(n, i) {
process_col(n);
var w = !!n.width;
var p = col_obj_w(i, n);
var k/*:any*/ = {"ss:Index":i+1};
if(w) k['ss:Width'] = width2px(p.width);
if(n.hidden) k['ss:Hidden']="1";
if(!T) { T = true; stream.push("<Table>"); }
stream.push(writextag("Column",null,k));
});
dense = ws["!data"] != null;
if(dense) darr = ws["!data"];
addr.r = addr.c = 0;
}
/* process `stride` rows per invocation */
for(var cnt = 0; R <= range.e.r && cnt < stride; ++R, ++cnt) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
if(!(dense && !darr[R])) for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
if(marr[mi].s.r > R) continue;
if(marr[mi].e.c < C) continue;
if(marr[mi].e.r < R) continue;
if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
break;
}
if(skip) continue;
var ref = encode_col(C) + encode_row(R), cell = dense ? darr[R][C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, wsidx, wb, addr));
}
row.push("</Row>");
if(!T) { T = true; stream.push("<Table>"); }
stream.push(row.join(""));
}
} break;
/* worksheet postamble */
case 5: {
stream.push(write_ws_xlml_wsopts(ws, opts, wsidx, wb));
if(ws && ws["!autofilter"]) stream.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
stream.push("</Worksheet>");
wsidx++; R = -1;
return void (stage = 3);
}
/* footer */
case -1: {
stage = -2;
stream.push("</Workbook>");
} break;
/* exeunt */
case -2: stream.push(null); break;
}};
return stream;
}
var __stream = {
to_json: write_json_stream,
to_html: write_html_stream,
to_csv: write_csv_stream,
to_xlml: write_xlml_stream,
set_readable: set_readable
};

33
dist/xlsx.core.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.core.min.map generated vendored

File diff suppressed because one or more lines are too long

458
dist/xlsx.extendscript.js generated vendored

@ -160,7 +160,7 @@ var DO_NOT_EXPORT_CODEPAGE = true;
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false */
var XLSX = {};
function make_xlsx_lib(XLSX){
XLSX.version = '0.20.2';
XLSX.version = '0.20.3';
var current_codepage = 1200, current_ansi = 1252;
/*global cptable:true, window */
var $cptable;
@ -695,6 +695,7 @@ function SSF_large_exp(v) {
}
function SSF_general_num(v) {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -1388,6 +1389,8 @@ function choose_fmt(f, v) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -1424,6 +1427,8 @@ function SSF_format(fmt,v,o) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt, idx) {
@ -1547,7 +1552,6 @@ function SSF__load(fmt, idx) {
var CRC32 = (function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*global Int32Array */
function signed_crc_table() {
var c = 0, table = new Array(256);
@ -2946,8 +2950,8 @@ function parse_local_file(blob, csz, usz, o, EF) {
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -2958,7 +2962,7 @@ function parse_local_file(blob, csz, usz, o, EF) {
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -2993,9 +2997,10 @@ function write_zip(cfb, options) {
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
@ -3888,6 +3893,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);
@ -3958,6 +3966,26 @@ function parsexmltag(tag, skip_root, skip_LC) {
}
return z;
}
function parsexmltagraw(tag, skip_root, skip_LC) {
var z = ({});
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x) { return x.replace(nsregex2, "<$1"); }
var encodings = {
@ -4464,7 +4492,8 @@ function recordhopper(data, cb, opts) {
/* control buffer usage for fixed-length buffers */
function buf_array() {
var bufs = [], blksz = has_buf ? 256 : 2048;
var bufs = [], blksz = has_buf ? 16384 : 2048;
var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function");
var newblk = function ba_newblk(sz) {
var o = (new_buf(sz));
prep_blob(o, 0);
@ -4493,10 +4522,15 @@ function buf_array() {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz);
};
return ({ next:next, push:push, end:end, _bufs:bufs });
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 });
}
function write_record(ba, type, payload, length) {
@ -4683,7 +4717,7 @@ function sheet_add_aoa(_ws, data, opts) {
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws = _ws || ({});
var ws = _ws || (dense ? ({"!data": []}) : ({}));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -4708,31 +4742,35 @@ function sheet_add_aoa(_ws, data, opts) {
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell = ({v: data[R][C] });
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell = ({v: data_R[C], t:"" });
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
else if(!o.sheetStubs) continue;
else cell.t = 'z';
}
else if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'number') {
if(isFinite(cell.v)) cell.t = 'n';
else if(isNaN(cell.v)) { cell.t = 'e'; cell.v = 0x0F; /* #VALUE! */ }
else { cell.t = 'e'; cell.v = 0x07; }
}
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.z = o.dateNF || table_fmt[14];
@ -4746,7 +4784,7 @@ function sheet_add_aoa(_ws, data, opts) {
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr;
var cell_ref = encode_col(__C) + (__R + 1);
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}
@ -4756,7 +4794,6 @@ function sheet_add_aoa(_ws, data, opts) {
return ws;
}
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
function parse_Int32LE(data) {
return data.read_shift(4, 'i');
}
@ -6338,8 +6375,8 @@ function parse_TypedPropertyValue(blob, type, _opts) {
case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
case 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,'');
case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob);
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
@ -8631,7 +8668,7 @@ var SYLK = (function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -8860,7 +8897,7 @@ var ETH = (function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -8903,11 +8940,7 @@ var ETH = (function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -8917,6 +8950,19 @@ var ETH = (function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -8948,6 +8994,7 @@ var PRN = (function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -9065,6 +9112,8 @@ var PRN = (function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;
@ -9764,7 +9813,6 @@ var WK_ = (function() {
else console.error("WK1 bad formula parse |" + out.join("|") + "|");
}
function parse_cell_3(blob) {
var o = [{c:0,r:0}, {t:'n',v:0}, 0];
o[0].r = blob.read_shift(2); o[3] = blob[blob.l++]; o[0].c = blob[blob.l++];
@ -10999,6 +11047,10 @@ function rtf_to_sheet_str(str, opts) {
if (o.cellText !== false)
cell.w = cell.v;
cell.v = fuzzynum(cell.v);
} else if (RBErr[cell.v] != null) {
cell.t = "e";
cell.w = cell.v;
cell.v = RBErr[cell.v];
}
if (dense)
row[C] = cell;
@ -11334,10 +11386,12 @@ function parse_fonts(t, styles, themes, opts) {
/* 18.8.2 b CT_BooleanProperty */
case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
case '<b/>': font.bold = 1; break;
case '</b>': case '</b': break;
/* 18.8.26 i CT_BooleanProperty */
case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
case '<i/>': font.italic = 1; break;
case '</i>': case '</i': break;
/* 18.4.13 u CT_UnderlineProperty */
case '<u':
@ -11349,48 +11403,55 @@ function parse_fonts(t, styles, themes, opts) {
case "doubleAccounting": font.underline = 0x22; break;
} break;
case '<u/>': font.underline = 1; break;
case '</u>': case '</u': break;
/* 18.4.10 strike CT_BooleanProperty */
case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
case '<strike/>': font.strike = 1; break;
case '</strike>': case '</strike': break;
/* 18.4.2 outline CT_BooleanProperty */
case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
case '<outline/>': font.outline = 1; break;
case '</outline>': case '</outline': break;
/* 18.8.36 shadow CT_BooleanProperty */
case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
case '<shadow/>': font.shadow = 1; break;
case '</shadow>': case '</shadow': break;
/* 18.8.12 condense CT_BooleanProperty */
case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
case '<condense/>': font.condense = 1; break;
case '</condense>': case '</condense': break;
/* 18.8.17 extend CT_BooleanProperty */
case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
case '<extend/>': font.extend = 1; break;
case '</extend>': case '</extend': break;
/* 18.4.11 sz CT_FontSize */
case '<sz': if(y.val) font.sz = +y.val; break;
case '<sz/>': case '</sz>': break;
case '<sz/>': case '</sz>': case '</sz': break;
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<vertAlign/>': case '</vertAlign>': case '</vertAlign': break;
/* 18.8.18 family CT_FontFamily */
case '<family': if(y.val) font.family = parseInt(y.val,10); break;
case '<family/>': case '</family>': break;
case '<family/>': case '</family>': case '</family': break;
/* 18.8.35 scheme CT_FontScheme */
case '<scheme': if(y.val) font.scheme = y.val; break;
case '<scheme/>': case '</scheme>': break;
case '<scheme/>': case '</scheme>': case '</scheme': break;
/* 18.4.1 charset CT_IntProperty */
case '<charset':
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': case '</charset': break;
/* 18.?.? color CT_Color */
case '<color':
@ -11413,11 +11474,11 @@ function parse_fonts(t, styles, themes, opts) {
}
break;
case '<color/>': case '</color>': break;
case '<color/>': case '</color>': case '</color': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
case '</AlternateContent>': case '</AlternateContent': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -15920,7 +15981,7 @@ function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
var merges = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -16379,16 +16440,17 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles, wb) {
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}), row, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
var data_R = dense ? data[R] : [];
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}
@ -17389,12 +17451,15 @@ function write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904) {
if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) {
if(last_seen) write_record(ba, 0x000D /* BrtShortRk */, write_BrtShortRk(cell, o));
else write_record(ba, 0x0002 /* BrtCellRk */, write_BrtCellRk(cell, o));
} else if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else if(!isFinite(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
o.t = "e";
if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
}
} else {
if(last_seen) write_record(ba, 0x0010 /* BrtShortReal */, write_BrtShortReal(cell, o));
else write_record(ba, 0x0005 /* BrtCellReal */, write_BrtCellReal(cell, o));
@ -17416,23 +17481,24 @@ function write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904) {
}
function write_CELLTABLE(ba, ws, idx, opts, wb) {
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
var range = safe_decode_range(ws['!ref'] || "A1"), rr = "", cols = [];
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
write_record(ba, 0x0091 /* BrtBeginSheetData */);
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, row = dense ? ws["!data"][range.s.r] : [];
var cap = range.e.r;
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
for(var R = range.s.r; R <= cap; ++R) {
rr = encode_row(R);
if(dense) row = ws["!data"][R];
/* [ACCELLTABLE] */
/* BrtRowHdr */
write_row_header(ba, ws, range, R);
if(dense && !row) continue;
var last_seen = false;
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
var cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) { last_seen = false; continue; }
/* write cell */
last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904);
@ -19695,7 +19761,13 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
var t = "", p = "";
switch(cell.t) {
case 'z': if(!opts.sheetStubs) return ""; break;
case 'n': t = 'Number'; p = String(cell.v); break;
case 'n': {
if(!isFinite(cell.v)) {
t = 'Error'; p = BErr[isNaN(cell.v) ? 0x24 : 0x07];
} else {
t = 'Number'; p = String(cell.v);
}
} break;
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
case 'e': t = 'Error'; p = BErr[cell.v]; break;
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || table_fmt[14]; break;
@ -19737,9 +19809,12 @@ function write_ws_xlml_table(ws, opts, idx, wb) {
o.push(writextag("Column",null,k));
});
var dense = ws["!data"] != null;
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
@ -19750,7 +19825,6 @@ function write_ws_xlml_table(ws, opts, idx, wb) {
break;
}
if(skip) continue;
var addr = {r:R,c:C};
var ref = encode_col(C) + encode_row(R), cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr));
}
@ -19774,7 +19848,7 @@ function write_ws_xlml(idx, opts, wb) {
/* WorksheetOptions */
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
if(ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
if(ws && ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
return o.join("");
}
@ -19793,11 +19867,10 @@ function write_xlml(wb, opts) {
d.push(write_props_xlml(wb, opts));
d.push(write_wb_xlml(wb, opts));
d.push("");
d.push("");
d.push(write_names_xlml(wb, opts));
for(var i = 0; i < wb.SheetNames.length; ++i)
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
d[2] = write_sty_xlml(wb, opts);
d[3] = write_names_xlml(wb, opts);
return XML_HEADER + writextag("Workbook", d.join(""), {
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
@ -21978,7 +22051,7 @@ function write_ws_biff2(ba, ws, idx, opts, wb) {
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, 0x3FFF);
range.e.r = Math.min(range.e.r, 0x3FFF);
}
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
var row = [], comments = [];
@ -22387,9 +22460,9 @@ function write_ws_biff8(idx, opts, wb) {
var range = safe_decode_range(ws['!ref'] || "A1");
var MAX_ROWS = b8 ? 65536 : 16384;
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV" + MAX_ROWS);
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
range.e.r = Math.min(range.e.r, MAX_ROWS-1);
}
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
@ -22424,12 +22497,11 @@ function write_ws_biff8(idx, opts, wb) {
if(dense) row = ws["!data"][R] || [];
rr = encode_row(R);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var cell = dense ? row[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) continue;
/* write cell */
write_ws_biff8_cell(ba, cell, R, C, opts, date1904);
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
if(b8 && cell.l) ws['!links'].push([cols[C] + rr, cell.l]);
if(cell.c) comments.push([cell.c, R, C]);
}
}
@ -22573,6 +22645,9 @@ function write_biff_buf(wb, opts) {
if(range.e.c > 255) { // note: 255 is IV
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond column IV (255). Data may be lost.");
}
if(range.e.r > 65535) {
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond row 65536. Data may be lost.");
}
}
var o = opts || {};
@ -22632,6 +22707,8 @@ function html_to_sheet(str, _opts) {
if(opts.UTC === false) o.v = utc_to_local(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
o.z = opts.dateNF || table_fmt[14];
} else if(m.charCodeAt(0) == 35 /* # */ && RBErr[m] != null) {
o.t = 'e'; o.w = m; o.v = RBErr[m];
}
if(o.cellText !== false) o.w = m;
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
@ -22659,6 +22736,10 @@ function make_html_row(ws, r, R, o) {
if(RS < 0) continue;
var coord = encode_col(C) + encode_row(R);
var cell = dense ? (ws["!data"][R]||[])[C] : ws[coord];
if(cell && cell.t == 'n' && cell.v != null && !isFinite(cell.v)) {
if(isNaN(cell.v)) cell = ({t:'e', v:0x24, w:BErr[0x24]});
else cell = ({t:'e', v:0x07, w:BErr[0x07]});
}
/* TODO: html entities */
var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
sp = ({});
@ -22769,6 +22850,7 @@ function sheet_add_dom(ws, table, _opts) {
if(v != null) {
if(v.length == 0) o.t = _t || 'z';
else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(_t == "e" && BErr[+v]) o = {t:'e', v:+v, w: BErr[+v]};
else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -22777,7 +22859,7 @@ function sheet_add_dom(ws, table, _opts) {
if(opts.UTC) o.v = local_to_utc(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
o.z = opts.dateNF || table_fmt[14];
}
} else if(v.charCodeAt(0) == 35 /* # */ && RBErr[v] != null) o = ({t:'e', v: RBErr[v], w: v});
}
if(o.z === undefined && z != null) o.z = z;
/* The first link is used. Links are assumed to be fully specified.
@ -23078,7 +23160,7 @@ function parse_content_xml(d, _opts, _nfm) {
var Sheets = {}, SheetNames = [];
var ws = ({}); if(opts.dense) ws["!data"] = [];
var Rn, q;
var ctag = ({value:""});
var ctag = ({value:""}), ctag2 = ({});
var textp = "", textpidx = 0, textptag, oldtextp = "", oldtextpidx = 0;
var textR = [], oldtextR = [];
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
@ -23137,10 +23219,18 @@ function parse_content_xml(d, _opts, _nfm) {
if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
C = -1; break;
case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
if(Rn[1] !== '/') ++C;
if(opts.sheetStubs) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
if(Rn[1] !== '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1",10) || 1;
if(opts.sheetStubs) {
while(colpeat-- > 0) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
++C;
} --C;
}
else C += colpeat - 1;
}
textp = ""; textR = [];
break; /* stub */
@ -23148,7 +23238,7 @@ function parse_content_xml(d, _opts, _nfm) {
if(Rn[0].charAt(Rn[0].length-2) === '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10)||1;
q = ({t:'z', v:null});
if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -23172,6 +23262,7 @@ function parse_content_xml(d, _opts, _nfm) {
if(R < range.s.r) range.s.r = R;
if(rptR > range.e.r) range.e.r = rptR;
ctag = parsexmltag(Rn[0], false);
ctag2 = parsexmltagraw(Rn[0], true);
comments = []; comment = ({});
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null});
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -23191,10 +23282,12 @@ function parse_content_xml(d, _opts, _nfm) {
q.F = arrayf[i][1];
}
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
mC = parseInt(ctag['number-columns-spanned'],10) || 0;
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
mR = parseInt(ctag['number-rows-spanned']||"1",10) || 1;
mC = parseInt(ctag['number-columns-spanned']||"1",10) || 1;
if(mR * mC > 1) {
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
}
}
/* 19.675.2 table:number-columns-repeated */
@ -23225,6 +23318,9 @@ function parse_content_xml(d, _opts, _nfm) {
}
} else {
isstub = false;
if(ctag2['calcext:value-type'] == "error" && RBErr[textp] != null) {
q.t = 'e'; q.w = textp; q.v = RBErr[textp];
}
if(q.t === 's') {
q.v = textp || '';
if(textR.length) q.R = textR;
@ -23623,7 +23719,6 @@ function parse_fods(data, opts) {
wb.bookType = "fods";
return wb;
}
/* OpenDocument */
var write_styles_ods = /* @__PURE__ */(function() {
var master_styles = [
@ -23888,9 +23983,22 @@ var write_content_ods = /* @__PURE__ */(function() {
ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
break;
case 'n':
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
if(!isFinite(cell.v)) {
if(isNaN(cell.v)) {
textp = "#NUM!";
ct['table:formula'] = "of:=#NUM!";
} else {
textp = "#DIV/0!";
ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
}
ct['office:string-value'] = "";
ct['office:value-type'] = "string";
ct['calcext:value-type'] = "error";
} else {
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
}
break;
case 's': case 'str':
textp = cell.v == null ? "" : cell.v;
@ -25242,7 +25350,7 @@ function s5s_to_iwa_comment(s5s) {
return out;
}
function parse_TST_TableModelArchive(M, root, ws, opts) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
var pb = parse_shallow(root.data);
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
@ -25321,6 +25429,38 @@ function parse_TST_TableModelArchive(M, root, ws, opts) {
};
});
}
if (!((_k = ws["!merges"]) == null ? void 0 : _k.length) && ((_l = pb[47]) == null ? void 0 : _l[0])) {
var merge_owner = parse_shallow(pb[47][0].data);
if ((_m = merge_owner[2]) == null ? void 0 : _m[0]) {
var formula_store = parse_shallow(merge_owner[2][0].data);
if ((_n = formula_store[3]) == null ? void 0 : _n[0]) {
ws["!merges"] = mappa(formula_store[3], function(u) {
var _a2, _b2, _c2, _d2, _e2;
var formula_pair = parse_shallow(u);
var formula = parse_shallow(formula_pair[2][0].data);
var AST_node_array = parse_shallow(formula[1][0].data);
if (!((_a2 = AST_node_array[1]) == null ? void 0 : _a2[0]))
return;
var AST_node0 = parse_shallow(AST_node_array[1][0].data);
var AST_node_type = varint_to_i32(AST_node0[1][0].data);
if (AST_node_type != 67)
return;
var AST_colon_tract = parse_shallow(AST_node0[40][0].data);
if (!((_b2 = AST_colon_tract[3]) == null ? void 0 : _b2[0]) || !((_c2 = AST_colon_tract[4]) == null ? void 0 : _c2[0]))
return;
var colrange = parse_shallow(AST_colon_tract[3][0].data);
var rowrange = parse_shallow(AST_colon_tract[4][0].data);
var c = varint_to_i32(colrange[1][0].data);
var C = ((_d2 = colrange[2]) == null ? void 0 : _d2[0]) ? varint_to_i32(colrange[2][0].data) : c;
var r = varint_to_i32(rowrange[1][0].data);
var R = ((_e2 = rowrange[2]) == null ? void 0 : _e2[0]) ? varint_to_i32(rowrange[2][0].data) : r;
return { s: { r: r, c: c }, e: { r: R, c: C } };
}).filter(function(x) {
return x != null;
});
}
}
}
}
function parse_TST_TableInfoArchive(M, root, opts) {
var pb = parse_shallow(root.data);
@ -27127,6 +27267,8 @@ function readSync(data, opts) {
var o = opts||{};
if(o.codepage && typeof $cptable === "undefined") console.error("Codepage tables are not loaded. Non-ASCII characters may not give expected results");
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
/* Javet projects `byte[]` to `Int8Array` */
if(typeof Int8Array !== 'undefined' && data instanceof Int8Array) return readSync(new Uint8Array(data.buffer, data.byteOffset, data.length), 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; }
@ -27482,7 +27624,7 @@ function sheet_to_json(sheet, opts) {
}
var qreg = /"/g;
function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
function make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o) {
var isempty = true;
var row = [], txt = "", rr = encode_row(R);
var dense = sheet["!data"] != null;
@ -27495,7 +27637,7 @@ function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
isempty = false;
txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
if(txt == "ID") txt = '"ID"';
if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"';
} else if(val.f != null && !val.F) {
isempty = false;
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
@ -27522,7 +27664,7 @@ function sheet_to_csv(sheet, opts) {
var w = 0;
for(var R = r.s.r; R <= r.e.r; ++R) {
if ((rowinfo[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o);
if(row == null) { continue; }
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
}
@ -27537,7 +27679,7 @@ function sheet_to_txt(sheet, opts) {
return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet) {
function sheet_to_formulae(sheet, opts) {
var y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C;
@ -27558,6 +27700,7 @@ function sheet_to_formulae(sheet) {
if(y.indexOf(":") == -1) y = y + ":" + y;
}
if(x.f != null) val = x.f;
else if(opts && opts.values === false) continue;
else if(x.t == 'z') continue;
else if(x.t == 'n' && x.v != null) val = "" + x.v;
else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";
@ -27826,7 +27969,7 @@ function write_csv_stream(sheet, opts) {
while(R <= r.e.r) {
++R;
if ((rowinfo[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, w, o);
if(row != null) {
if(row || (o.blankrows !== false)) return stream.push((w++ ? RS : "") + row);
}
@ -27923,10 +28066,165 @@ function write_json_stream(sheet, opts) {
return stream;
}
function write_xlml_stream(wb, o) {
var stream = _Readable();
var opts = o == null ? {} : o;
var stride = +opts.stride || 10;
if(!wb.SSF) wb.SSF = dup(table_fmt);
if(wb.SSF) {
make_ssf(); SSF_load_table(wb.SSF);
// $FlowIgnore
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
opts.ssf = wb.SSF;
opts.cellXfs = [];
get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
}
/* do one pass to determine styles since they must be added before tables */
wb.SheetNames.forEach(function(n) {
var ws = wb.Sheets[n];
if(!ws || !ws["!ref"]) return;
var range = decode_range(ws["!ref"]);
var dense = ws["!data"] != null;
var ddata = dense ? ws["!data"] : [];
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
addr.r = R;
if(dense && !ddata[R]) continue;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var cell = dense ? ddata[R][C] : ws[encode_col(C) + encode_row(R)];
if(!cell) continue;
if(cell.t == "d" && cell.z == null) { cell = dup(cell); cell.z = table_fmt[14]; }
void get_cell_style(opts.cellXfs, cell, opts);
}
}
});
var sty = write_sty_xlml(wb, opts);
var stage = 0, wsidx = 0, ws = wb.Sheets[wb.SheetNames[wsidx]], range = safe_decode_range(ws), R = -1, T = false;
var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
stream._read = function() { switch(stage) {
/* header */
case 0: {
stage = 1;
stream.push(XML_HEADER);
stream.push("<Workbook" + wxt_helper({
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
'xmlns:x': XLMLNS.x,
'xmlns:ss': XLMLNS.ss,
'xmlns:dt': XLMLNS.dt,
'xmlns:html': XLMLNS.html
}) + ">");
} break;
/* preamble */
case 1: {
stage = 2;
stream.push(write_props_xlml(wb, opts));
stream.push(write_wb_xlml(wb, opts));
} break;
/* style and name tables */
case 2: {
stage = 3;
stream.push(sty);
stream.push(write_names_xlml(wb, opts));
} break;
/* worksheet preamble */
case 3: {
T = false;
if(wsidx >= wb.SheetNames.length) { stage = -1; stream.push(""); break; }
stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
ws = wb.Sheets[wb.SheetNames[wsidx]];
if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
var names = write_ws_xlml_names(ws, opts, wsidx, wb);
if(names.length) stream.push("<Names>" + names + "</Names>");
if(!ws["!ref"]) return (stage = 5);
range = safe_decode_range(ws["!ref"]);
R = range.s.r;
stage = 4;
} break;
/* worksheet intramble */
case 4: {
if(R < 0 || R > range.e.r) { if(T) stream.push("</Table>"); return void (stage = 5); }
if(R <= range.s.r) {
if(ws['!cols']) ws['!cols'].forEach(function(n, i) {
process_col(n);
var w = !!n.width;
var p = col_obj_w(i, n);
var k = {"ss:Index":i+1};
if(w) k['ss:Width'] = width2px(p.width);
if(n.hidden) k['ss:Hidden']="1";
if(!T) { T = true; stream.push("<Table>"); }
stream.push(writextag("Column",null,k));
});
dense = ws["!data"] != null;
if(dense) darr = ws["!data"];
addr.r = addr.c = 0;
}
/* undefined `stride` rows per invocation */
for(var cnt = 0; R <= range.e.r && cnt < stride; ++R, ++cnt) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
if(!(dense && !darr[R])) for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
if(marr[mi].s.r > R) continue;
if(marr[mi].e.c < C) continue;
if(marr[mi].e.r < R) continue;
if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
break;
}
if(skip) continue;
var ref = encode_col(C) + encode_row(R), cell = dense ? darr[R][C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, wsidx, wb, addr));
}
row.push("</Row>");
if(!T) { T = true; stream.push("<Table>"); }
stream.push(row.join(""));
}
} break;
/* worksheet postamble */
case 5: {
stream.push(write_ws_xlml_wsopts(ws, opts, wsidx, wb));
if(ws && ws["!autofilter"]) stream.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
stream.push("</Worksheet>");
wsidx++; R = -1;
return void (stage = 3);
}
/* footer */
case -1: {
stage = -2;
stream.push("</Workbook>");
} break;
/* exeunt */
case -2: stream.push(null); break;
}};
return stream;
}
var __stream = {
to_json: write_json_stream,
to_html: write_html_stream,
to_csv: write_csv_stream,
to_xlml: write_xlml_stream,
set_readable: set_readable
};
if(typeof parse_xlscfb !== "undefined") XLSX.parse_xlscfb = parse_xlscfb;

34
dist/xlsx.full.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.full.min.map generated vendored

File diff suppressed because one or more lines are too long

18
dist/xlsx.mini.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.mini.min.map generated vendored

File diff suppressed because one or more lines are too long

@ -49,6 +49,10 @@ function rtf_to_sheet_str(str, opts) {
if (o.cellText !== false)
cell.w = cell.v;
cell.v = fuzzynum(cell.v);
} else if (RBErr[cell.v] != null) {
cell.t = "e";
cell.w = cell.v;
cell.v = RBErr[cell.v];
}
if (dense)
row[C] = cell;

@ -12,6 +12,7 @@ declare function a2s(a: any): string;
declare var has_buf: boolean;
declare function Base64_decode(s: string): string;
declare function fuzzynum(s: string): number;
declare var RBErr: {[key: string]: number};
function rtf_to_sheet(d: RawData, opts: ParsingOptions): WorkSheet {
switch(opts.type) {
@ -54,7 +55,7 @@ function rtf_to_sheet_str(str: string, opts: ParsingOptions): WorkSheet {
var cell: CellObject = {v: payload.join(""), t:"s"};
if(cell.v == "TRUE" || cell.v == "FALSE") { cell.v = cell.v == "TRUE"; cell.t = "b"; }
else if(!isNaN(fuzzynum(cell.v as string))) { cell.t = 'n'; if(o.cellText !== false) cell.w = cell.v as string; cell.v = fuzzynum(cell.v as string); }
else if(RBErr[cell.v as string] != null) { cell.t = "e"; cell.w = cell.v as string; cell.v = RBErr[cell.v as string]; }
if(dense) row[C] = cell;
else (ws as SparseSheet)[encode_cell({r:R, c:C})] = cell;
}

@ -52,6 +52,10 @@ function parse_xlmeta_bin(data, name, _opts) {
var metatype = 2;
recordhopper(data, function(val, R, RT) {
switch (RT) {
case 58:
break;
case 59:
break;
case 335:
out.Types.push({ name: val.name });
break;

@ -73,15 +73,37 @@ function parse_xlmeta_bin(data: RawData, name: string, _opts?: ParseXLMetaOption
// case 0x014D: /* BrtEndMetadata */
// case 0x014E: /* BrtBeginEsmdtinfo */
// case 0x0150: /* BrtEndEsmdtinfo */
// case 0x0151: /* BrtBeginEsmdb */
// case 0x0152: /* BrtEndEsmdb */
// case 0x0153: /* BrtBeginEsfmd */
// case 0x0154: /* BrtEndEsfmd */
// case 0x0174: /* BrtBeginEsmdx */
// case 0x0175: /* BrtEndEsmdx */
// case 0x0176: /* BrtBeginMdxSet */
// case 0x0177: /* BrtEndMdxSet */
// case 0x0178: /* BrtBeginMdxMbrProp */
// case 0x0179: /* BrtEndMdxMbrProp */
// case 0x017A: /* BrtBeginMdxKPI */
// case 0x017B: /* BrtEndMdxKPI */
// case 0x017C: /* BrtBeginEsstr */
// case 0x017D: /* BrtEndEsstr */
// case 0x0034: /* BrtBeginFmd */
// case 0x0035: /* BrtEndFmd */
// case 0x0036: /* BrtBeginMdx */
// case 0x0037: /* BrtEndMdx */
// case 0x0038: /* BrtBeginMdxTuple */
// case 0x0039: /* BrtEndMdxTuple */
// case 0x1000: /* BrtBeginDynamicArrayPr */
// case 0x1001: /* BrtEndDynamicArrayPr */
// case 0x138A: /* BrtBeginRichValueBlock */
// case 0x138B: /* BrtEndRichValueBlock */
case 0x003A: /* BrtMdxMbrIstr */
break;
case 0x003B: /* BrtStr */
break;
case 0x014F: /* BrtMdtinfo */
out.Types.push({name: (val as BrtMdtinfo).name}); break;

@ -1117,7 +1117,7 @@ function s5s_to_iwa_comment(s5s) {
return out;
}
function parse_TST_TableModelArchive(M, root, ws, opts) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
var pb = parse_shallow(root.data);
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
@ -1196,6 +1196,38 @@ function parse_TST_TableModelArchive(M, root, ws, opts) {
};
});
}
if (!((_k = ws["!merges"]) == null ? void 0 : _k.length) && ((_l = pb[47]) == null ? void 0 : _l[0])) {
var merge_owner = parse_shallow(pb[47][0].data);
if ((_m = merge_owner[2]) == null ? void 0 : _m[0]) {
var formula_store = parse_shallow(merge_owner[2][0].data);
if ((_n = formula_store[3]) == null ? void 0 : _n[0]) {
ws["!merges"] = mappa(formula_store[3], function(u) {
var _a2, _b2, _c2, _d2, _e2;
var formula_pair = parse_shallow(u);
var formula = parse_shallow(formula_pair[2][0].data);
var AST_node_array = parse_shallow(formula[1][0].data);
if (!((_a2 = AST_node_array[1]) == null ? void 0 : _a2[0]))
return;
var AST_node0 = parse_shallow(AST_node_array[1][0].data);
var AST_node_type = varint_to_i32(AST_node0[1][0].data);
if (AST_node_type != 67)
return;
var AST_colon_tract = parse_shallow(AST_node0[40][0].data);
if (!((_b2 = AST_colon_tract[3]) == null ? void 0 : _b2[0]) || !((_c2 = AST_colon_tract[4]) == null ? void 0 : _c2[0]))
return;
var colrange = parse_shallow(AST_colon_tract[3][0].data);
var rowrange = parse_shallow(AST_colon_tract[4][0].data);
var c = varint_to_i32(colrange[1][0].data);
var C = ((_d2 = colrange[2]) == null ? void 0 : _d2[0]) ? varint_to_i32(colrange[2][0].data) : c;
var r = varint_to_i32(rowrange[1][0].data);
var R = ((_e2 = rowrange[2]) == null ? void 0 : _e2[0]) ? varint_to_i32(rowrange[2][0].data) : r;
return { s: { r: r, c: c }, e: { r: R, c: C } };
}).filter(function(x) {
return x != null;
});
}
}
}
}
function parse_TST_TableInfoArchive(M, root, opts) {
var pb = parse_shallow(root.data);

@ -4,7 +4,7 @@
/* these are type imports and do not show up in the generated JS */
import { CFB$Container, CFB$Entry } from 'cfb';
import { WorkBook, WorkSheet, Range, CellObject, ParsingOptions, WritingOptions, DenseWorkSheet, Comments } from '../';
import type { utils, NumberFormat } from "../";
import type { utils, NumberFormat, DenseSheetData } from "../";
declare var encode_col: typeof utils.encode_col;
declare var encode_row: typeof utils.encode_row;
@ -960,6 +960,7 @@ function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: Work
_R += _tile.nrows;
});
/* old-style merges */
if(store[13]?.[0]) {
var ref = M[parse_TSP_Reference(store[13][0].data)][0];
var mtype = varint_to_i32(ref.meta[1][0].data);
@ -976,6 +977,50 @@ function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: Work
};
});
}
/* new-style merges */
if(!ws["!merges"]?.length && pb[47]?.[0]) {
// .TST.MergeOwnerArchive
var merge_owner = parse_shallow(pb[47][0].data);
if(merge_owner[2]?.[0]) {
// .TST.FormulaStoreArchive
var formula_store = parse_shallow(merge_owner[2][0].data);
if(formula_store[3]?.[0]) {
ws["!merges"] = mappa<Range|undefined>(formula_store[3], (u) => {
var formula_pair = parse_shallow(u);
/* TODO: this should eventually use a proper formula parser */
// .TSCE.FormulaArchive
var formula = parse_shallow(formula_pair[2][0].data);
// .TSCE.ASTNodeArrayArchive
var AST_node_array = parse_shallow(formula[1][0].data);
// .TSCE.ASTNodeArrayArchive.ASTNodeArchive
if(!AST_node_array[1]?.[0]) return;
var AST_node0 = parse_shallow(AST_node_array[1][0].data);
// .TSCE.ASTNodeArrayArchive.ASTNodeType
var AST_node_type = varint_to_i32(AST_node0[1][0].data);
if(AST_node_type != 67) return; // COLON_TRACT_NODE
// .TSCE.ASTNodeArrayArchive.ASTColonTractArchive
var AST_colon_tract = parse_shallow(AST_node0[40][0].data);
if(!AST_colon_tract[3]?.[0] || !AST_colon_tract[4]?.[0]) return;
// ASTColonTractAbsoluteRangeArchive
var colrange = parse_shallow(AST_colon_tract[3][0].data);
var rowrange = parse_shallow(AST_colon_tract[4][0].data);
var c = varint_to_i32(colrange[1][0].data);
var C = colrange[2]?.[0] ? varint_to_i32(colrange[2][0].data) : c;
var r = varint_to_i32(rowrange[1][0].data);
var R = rowrange[2]?.[0] ? varint_to_i32(rowrange[2][0].data) : r;
return { s: { r, c }, e: { r: R, c: C }} as Range;
}).filter(x => x != null) as Range[];
// .TST.FormulaStoreArchive.FormulaStorePair
}
}
}
}
/** Parse .TST.TableInfoArchive (6000) */
@ -1652,7 +1697,7 @@ function write_numbers_tma(cfb: CFB$Container, deps: Dependents, ws: WorkSheet,
if(trunc) console.error(`Truncating to ${encode_range(range)}`);
/* preprocess data and build up shared string table */
var data: CellObject[][] = [];
var data: DenseSheetData = [];
if(ws["!data"]) data = ws["!data"];
else {
var colstr: string[] = [];
@ -1663,7 +1708,7 @@ function write_numbers_tma(cfb: CFB$Container, deps: Dependents, ws: WorkSheet,
for(_C = 0; _C <= range.e.c; ++_C) {
var _cell = ws[colstr[_C] + _R];
if(!_cell) continue;
data[R_][_C] = _cell;
data[R_]![_C] = _cell;
}
}
}

@ -1,6 +1,6 @@
{
"name": "xlsx",
"version": "0.20.2",
"version": "0.20.3",
"author": "sheetjs",
"description": "SheetJS Spreadsheet data parser and writer",
"keywords": [
@ -142,10 +142,7 @@
"url": "https://git.sheetjs.com/SheetJS/sheetjs"
},
"scripts": {
"pretest": "npm run lint",
"test": "npm run tests-only",
"pretest-only": "git submodule init && git submodule update",
"tests-only": "make travis",
"test": "make travis",
"build": "make",
"lint": "make fullint",
"dtslint": "dtslint types"

@ -5,6 +5,6 @@ function pad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v;return t.length>=d?t
function rpad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:t+fill(' ',d-t.length);}
function pad0r1(v/*:any*/,d/*:number*/)/*:string*/{var t=""+Math.round(v); return t.length>=d?t:fill('0',d-t.length)+t;}
function pad0r2(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
var p2_32 = Math.pow(2,32);
var p2_32 = /*#__PURE__*/Math.pow(2,32);
function pad0r(v/*:any*/,d/*:number*/)/*:string*/{if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); }
function isgeneral(s/*:string*/, i/*:?number*/)/*:boolean*/ { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; }

@ -1,4 +1,5 @@
function init_table(t/*:any*/) {
if(!t) t = {};
t[0]= 'General';
t[1]= '0';
t[2]= '0.00';
@ -28,6 +29,7 @@ function init_table(t/*:any*/) {
t[48]= '##0.0E+0';
t[49]= '@';
t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "';
return t;
}
var table_fmt = {};

@ -29,6 +29,7 @@ var general_fmt_num = (function make_general_fmt_num() {
}
function general_fmt_num_base(v/*:number*/)/*:string*/ {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);

@ -39,7 +39,7 @@ function write_num_f2(r/*:Array<string>*/, aval/*:number*/, sign/*:string*/)/*:s
return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
}
var dec1 = /^#*0*\.([0#]+)/;
var closeparen = /\).*[0#]/;
var closeparen = /\)[^)]*[0#]/;
var phone = /\(###\) ###\\?-####/;
function hashq(str/*:string*/)/*:string*/ {
var o = "", cc;

@ -4,6 +4,8 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -40,5 +42,7 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
if(isgeneral(f[1])) return general_fmt(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}

@ -13,8 +13,8 @@ a { text-decoration: none }
<pre>
<b><a href="http://sheetjs.com">SSF (Spreadsheet Number Format) Live Demo</a></b>
<a href="https://github.com/SheetJS/ssf">Source Code Repo</a>
<a href="https://github.com/SheetJS/ssf/issues">Issues? Something look weird? Click here and report an issue</a>
<a href="https://git.sheetjs.com/sheetjs/sheetjs/src/branch/master/packages/ssf">Source Code Repo</a>
<a href="https://git.sheetjs.com/SheetJS/sheetjs/issues">Issues? Something look weird? Click here and report an issue</a>
</pre>
<table>
<tr><td><b>Format code:</b></td><td><input type="text" id="fmt" value="General"></td></tr>

@ -20,7 +20,7 @@
"dtslint": "^0.1.2",
"mocha": "~2.5.3",
"typescript": "2.2.0",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz"
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
},
"repository": {
"type": "git",

@ -12,7 +12,7 @@ function pad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v;return t.length>=d?t
function rpad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:t+fill(' ',d-t.length);}
function pad0r1(v/*:any*/,d/*:number*/)/*:string*/{var t=""+Math.round(v); return t.length>=d?t:fill('0',d-t.length)+t;}
function pad0r2(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
var p2_32 = Math.pow(2,32);
var p2_32 = /*#__PURE__*/Math.pow(2,32);
function pad0r(v/*:any*/,d/*:number*/)/*:string*/{if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); }
function isgeneral(s/*:string*/, i/*:?number*/)/*:boolean*/ { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; }
/*::
@ -42,6 +42,7 @@ var months/*:Array<Array<string> >*/ = [
['D', 'Dec', 'December']
];
function init_table(t/*:any*/) {
if(!t) t = {};
t[0]= 'General';
t[1]= '0';
t[2]= '0.00';
@ -71,6 +72,7 @@ function init_table(t/*:any*/) {
t[48]= '##0.0E+0';
t[49]= '@';
t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "';
return t;
}
var table_fmt = {};
@ -252,6 +254,7 @@ var general_fmt_num = (function make_general_fmt_num() {
}
function general_fmt_num_base(v/*:number*/)/*:string*/ {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -417,7 +420,7 @@ function write_num_f2(r/*:Array<string>*/, aval/*:number*/, sign/*:string*/)/*:s
return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
}
var dec1 = /^#*0*\.([0#]+)/;
var closeparen = /\).*[0#]/;
var closeparen = /\)[^)]*[0#]/;
var phone = /\(###\) ###\\?-####/;
function hashq(str/*:string*/)/*:string*/ {
var o = "", cc;
@ -951,6 +954,8 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -987,6 +992,8 @@ function format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
if(isgeneral(f[1])) return general_fmt(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function load_entry(fmt/*:string*/, idx/*:?number*/)/*:number*/ {

@ -38,6 +38,7 @@ var months = [
['D', 'Dec', 'December']
];
function init_table(t) {
if(!t) t = {};
t[0]= 'General';
t[1]= '0';
t[2]= '0.00';
@ -67,6 +68,7 @@ function init_table(t) {
t[48]= '##0.0E+0';
t[49]= '@';
t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "';
return t;
}
var table_fmt = {};
@ -248,6 +250,7 @@ var general_fmt_num = (function make_general_fmt_num() {
}
function general_fmt_num_base(v) {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -412,7 +415,7 @@ function write_num_f2(r, aval, sign) {
return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
}
var dec1 = /^#*0*\.([0#]+)/;
var closeparen = /\).*[0#]/;
var closeparen = /\)[^)]*[0#]/;
var phone = /\(###\) ###\\?-####/;
function hashq(str) {
var o = "", cc;
@ -943,6 +946,8 @@ function choose_fmt(f, v) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -979,6 +984,8 @@ function format(fmt,v,o) {
if(isgeneral(f[1])) return general_fmt(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function load_entry(fmt, idx) {

@ -1446,7 +1446,7 @@ SSF.load_table = function load_table(tbl/*:{[n:number]:string}*/) { for(var i=0;
## Fraction Library
The implementation is from [our frac library](https://github.com/SheetJS/frac/):
The implementation is from [our frac library](https://git.sheetjs.com/SheetJS/frac/):
```js>bits/30_frac.js
function frac(x, D, mixed) {

@ -19,4 +19,14 @@ describe('oddities', function() {
var chk = function(fmt){ return function(){ SSF.format(fmt,0); }; };
bad.forEach(function(fmt){assert.throws(chk(fmt));});
});
it('should handle NaN values and infinities', function() {
assert.equal(SSF.format('#,##0.0; (#,##0.0); "-"', NaN), " -");
assert.equal(SSF.format('#,##0.0; (#,##0.0); "-"', Infinity), " -");
assert.equal(SSF.format('#,##0.0; (#,##0.0); "-"', -Infinity), " -");
["0.00", "General"].forEach(function(fmt) {
assert.equal(SSF.format(fmt, NaN), "#VALUE!");
assert.equal(SSF.format(fmt, Infinity), "#DIV/0!");
assert.equal(SSF.format(fmt, -Infinity), "#DIV/0!");
});
});
});

80
test.js

@ -54,7 +54,7 @@ if(!browser) {
for(var _fileAi = 0; _fileAi < _fileA.length; ++_fileAi) if(test_file(_fileA[_fileAi])) fileA.push(_fileA[_fileAi]);
}
var can_write_numbers = typeof Array.prototype.findIndex == "function" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.indexOf == "function";
var can_write_numbers = typeof Set !== "undefined" && typeof Array.prototype.findIndex == "function" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.indexOf == "function";
/* Excel enforces 31 character sheet limit, although technical file limit is 255 */
function fixsheetname(x/*:string*/)/*:string*/ { return x.substr(0,31); }
@ -800,6 +800,17 @@ describe('API', function() {
]);
if(assert.deepEqual) assert.deepEqual(data.A2, { l: { Target: 'https://123.com' }, v: 'url', t: 's' });
});
it('sheet_to_formulae', function() {
var ws = X.utils.aoa_to_sheet([
["a", "b", "c"],
[1, 2, 3],
[4, 5, 6]
], {dense: true});
ws["!data"][2][0].f = "2*B2";
ws["!data"][2][1].f = "B2+C2";
assert.equal(X.utils.sheet_to_formulae(ws).join("\n"), "A1='a\nB1='b\nC1='c\nA2=1\nB2=2\nC2=3\nA3=2*B2\nB3=B2+C2\nC3=6");
assert.equal(X.utils.sheet_to_formulae(ws, {values: false}).join("\n"), "A3=2*B2\nB3=B2+C2");
});
it('decode_range', function() {
var _c = "ABC", _r = "123", _C = "DEF", _R = "456";
@ -1761,8 +1772,8 @@ describe('roundtrip features', function() {
['xlsx', paths.svxlsx],
['xlsb', paths.svxlsb],
['xls', paths.svxls],
['biff5', paths.svxls5]
// ['ods', paths.svods]
['biff5', paths.svxls5],
['ods', paths.svods]
].forEach(function(w) {
it(w[0], function() {
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE});
@ -1772,7 +1783,9 @@ describe('roundtrip features', function() {
assert.equal(wbs1.length, wbs2.length);
for(var i = 0; i < wbs1.length; ++i) {
assert.equal(wbs1[i].name, wbs2[i].name);
assert.equal(wbs1[i].Hidden, wbs2[i].Hidden);
/* NOTE: ODS does not support the equivalent of "Very Hidden" */
if(w[0] != "ods") assert.equal(wbs1[i].Hidden, wbs2[i].Hidden);
else assert.equal(!!wbs1[i].Hidden, !!wbs2[i].Hidden);
}
});
});
@ -1889,6 +1902,32 @@ describe('roundtrip features', function() {
assert.ok(wb7.Workbook.WBProps.date1904);
}); });
it('should handle numeric NaN and Infinity', function() {[
"xlsx", "xlsm", "xlsb", "xls", "biff5", "biff4", "biff3", "biff2", "xlml", "csv", "txt", "sylk", "html", "rtf", "prn", "eth", "ods", "fods"
].forEach(function(ext) {
var ws = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var buf = X.write(wb, { type: TYPE, bookType: ext, numbers: XLSX_ZAHL });
var wb2 = X.read(buf, { type: TYPE, PRN: true });
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
}); });
});
//function password_file(x){return x.match(/^password.*\.xls$/); }
@ -2176,7 +2215,7 @@ function plaintext_test(wb, raw) {
var sheet = wb.Sheets[wb.SheetNames[0]];
plaintext_val.forEach(function(x) {
var cell = get_cell(sheet, x[0]);
var tcval = x[2+(raw ? 1 : 0)];
var tcval = x[2+(!!raw ? 1 : 0)];
var type = raw ? 's' : x[1];
if(x.length == 1) { if(cell) { assert.equal(cell.t, 'z'); assert.ok(!cell.v); } return; }
assert.equal(cell.v, tcval); assert.equal(cell.t, type);
@ -2535,6 +2574,8 @@ function get_dom_element(html) {
domelt.innerHTML = html;
if(document.body) document.body.appendChild(domelt);
inserted_dom_elements.push(domelt);
var elts = domelt.getElementsByTagName("TABLE");
if(elts && elts[0]) return elts[0];
return domelt.children[0];
}
if(!JSDOM) throw new Error("Browser test fail");
@ -2668,6 +2709,30 @@ describe('HTML', function() {
assert.equal(range.e.c, expectedCellCount - 1);
});
});
if(domtest) it('should handle numeric NaN and Infinity', function() {
var ws = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var str = X.write(wb, { type: "string", bookType: "html" });
var wb2 = X.utils.table_to_book(get_dom_element(str));
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
});
});
describe('js -> file -> js', function() {
@ -3039,6 +3104,11 @@ describe('corner cases', function() {
}
});
});
(fs.existsSync(dir + 'shared_formula.xlsx') ? it : it.skip)('should properly handle defined names in shared formulae', function() {
var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE});
var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]);
assert.equal(formulae[4], 'A5=nvRTX6090');
});
});
describe('encryption', function() {

191
test.mjs generated

@ -371,13 +371,13 @@ if(!browser) describe('should parse test files', function() {
});
function get_cell(ws/*:Worksheet*/, addr/*:string*/) {
if(!Array.isArray(ws)) return ws[addr];
if(!ws["!data"]) return ws[addr];
var a = X.utils.decode_cell(addr);
return (ws[a.r]||[])[a.c];
return (ws["!data"][a.r]||[])[a.c];
}
function each_cell(ws, f) {
if(Array.isArray(ws)) ws.forEach(function(row) { if(row) row.forEach(f); });
if(ws["!data"]) ws["!data"].forEach(function(row) { if(row) row.forEach(f); });
else Object.keys(ws).forEach(function(addr) { if(addr[0] === "!" || !ws.hasOwnProperty(addr)) return; f(ws[addr]); });
}
@ -804,6 +804,17 @@ describe('API', function() {
]);
if(assert.deepEqual) assert.deepEqual(data.A2, { l: { Target: 'https://123.com' }, v: 'url', t: 's' });
});
it('sheet_to_formulae', function() {
var ws = X.utils.aoa_to_sheet([
["a", "b", "c"],
[1, 2, 3],
[4, 5, 6]
], {dense: true});
ws["!data"][2][0].f = "2*B2";
ws["!data"][2][1].f = "B2+C2";
assert.equal(X.utils.sheet_to_formulae(ws).join("\n"), "A1='a\nB1='b\nC1='c\nA2=1\nB2=2\nC2=3\nA3=2*B2\nB3=B2+C2\nC3=6");
assert.equal(X.utils.sheet_to_formulae(ws, {values: false}).join("\n"), "A3=2*B2\nB3=B2+C2");
});
it('decode_range', function() {
var _c = "ABC", _r = "123", _C = "DEF", _R = "456";
@ -1027,10 +1038,14 @@ describe('parse features', function() {
});
describe('column properties', function() {
var wbs = [], wbs_no_slk = [];
var wbs = [], wbs_no_slk = [], ols = [];
var ol = fs.existsSync(paths.olxls);
var bef = (function() {
wbs = CWPaths.map(function(n) { return X.read(fs.readFileSync(n), {type:TYPE, cellStyles:true}); });
wbs_no_slk = wbs.slice(0, 5);
/* */
if(!ol) return;
ols = OLPaths.map(function(p) { return X.read(fs.readFileSync(p), {type:TYPE, cellStyles:true}); });
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
@ -1065,6 +1080,22 @@ describe('parse features', function() {
assert.equal(x[7].wpx, 101);
});
});
it('should have correct outline levels', function() {
ols.map(function(x) { return x.Sheets["Sheet1"]; }).forEach(function(ws) {
var cols = ws['!cols'];
if(!cols) return; // TODO: ODS!!!
for(var i = 0; i < 29; ++i) {
var cell = get_cell(ws, X.utils.encode_col(i) + "1");
var lvl = (cols[i]||{}).level||0;
if(!cell || cell.t == 's') assert.equal(lvl, 0);
else if(cell.t == 'n') {
if(cell.v === 0) assert.equal(lvl, 0);
else assert.equal(lvl, cell.v);
}
}
assert.equal(cols[29].level, 7);
});
});
});
describe('row properties', function() {
@ -1873,6 +1904,32 @@ describe('roundtrip features', function() {
assert.ok(wb7.Workbook.WBProps.date1904);
}); });
it('should handle numeric NaN and Infinity', function() {[
"xlsx", "xlsm", "xlsb", "xls", "biff5", "biff4", "biff3", "biff2", "xlml", "csv", "txt", "sylk", "html", "rtf", "prn", "eth", "ods", "fods"
].forEach(function(ext) {
var ws = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var buf = X.write(wb, { type: TYPE, bookType: ext, numbers: XLSX_ZAHL });
var wb2 = X.read(buf, { type: TYPE, PRN: true });
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
}); });
});
//function password_file(x){return x.match(/^password.*\.xls$/); }
@ -2480,10 +2537,12 @@ describe('dbf', function() {
it(wbs[1][0], function() {
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
[
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
["C2", "v", 12.345], ["D2", "v", 1234.1],
["E2", "v", 6260], ["E2", "w", "19170219"],
["F2", "v", 6260], ["F2", "w", "19170219"],
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
["G2", "v", 1231.4], ["H2", "v", 123234],
["I2", "v", true], ["L2", "v", "SheetJS"]
].forEach(function(r) {
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[2]);
});
@ -2649,6 +2708,30 @@ describe('HTML', function() {
assert.equal(range.e.c, expectedCellCount - 1);
});
});
if(domtest) it('should handle numeric NaN and Infinity', function() {
var ws = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var str = X.write(wb, { type: "string", bookType: "html" });
var wb2 = X.utils.table_to_book(get_dom_element(str));
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
});
});
describe('js -> file -> js', function() {
@ -2706,6 +2789,97 @@ describe('rtf', function() {
});
});
describe('dense mode', function() {
it('sheet_new', function() {
var sp = X.utils.sheet_new(); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({}); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({dense: false}); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({dense: true}); assert.ok(!!sp["!data"]);
});
it('read', function() {
ILPaths.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws = wb.Sheets[wb.SheetNames[0]];
assert.equal(ws["A1"].v, "Link to Sheet2");
assert.ok(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(!ws["A1"]);
assert.equal(ws["!data"][0][0].v, "Link to Sheet2");
});
if(!browser) artifax.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(ws["A1"]);
assert.ok(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(!ws["A1"]);
assert.ok(ws["!data"][0][0]);
});
});
it('aoa_to_sheet', function() {
var aoa = [["SheetJS"],[5433795]];
var sp = X.utils.aoa_to_sheet(aoa); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
});
it('json_to_sheet', function() {
var json = [{"SheetJS": 5433795}];
var sp = X.utils.json_to_sheet(json); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
});
it('sheet_add_aoa', function() {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
});
it('sheet_add_json', function() {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader:1}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader: 1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: 1}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: 1, dense: true}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
});
ofmt.forEach(function(f) { it('write ' + f, function() {
var aoa = [["SheetJS"],[5433795]];
var wb = X.utils.book_new(X.utils.aoa_to_sheet(aoa));
var newwb = X.read(X.write(wb, {type:"binary", bookType:f}), {type:"binary"});
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A1").v, "SheetJS");
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A2").v, 5433795);
}); });
it('sheet_to_formulae', function() {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_formulae(wb1.Sheets[n]).sort().join("\n"),
X.utils.sheet_to_formulae(wb2.Sheets[n]).sort().join("\n")
);
});
});
it('sheet_to_csv', function() {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_csv(wb1.Sheets[n]),
X.utils.sheet_to_csv(wb2.Sheets[n])
);
});
});
});
describe('corner cases', function() {
it('output functions', function() {
var ws = X.utils.aoa_to_sheet([
@ -2929,6 +3103,11 @@ describe('corner cases', function() {
}
});
});
(fs.existsSync(dir + 'shared_formula.xlsx') ? it : it.skip)('should properly handle defined names in shared formulae', function() {
var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE});
var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]);
assert.equal(formulae[4], 'A5=nvRTX6090');
});
});
describe('encryption', function() {

182
test.mts

@ -9,10 +9,10 @@ declare type EmptyFunc = (() => void) | null;
declare var afterEach:(test:EmptyFunc)=>void;
declare var cptable: any;
*/
import * as assert_ from 'https://deno.land/std/testing/asserts.ts';
import * as base64_ from 'https://deno.land/std/encoding/base64.ts';
import * as assert_ from 'https://deno.land/std@0.169.0/testing/asserts.ts';
import * as base64_ from 'https://deno.land/std@0.169.0/encoding/base64.ts';
const assert: any = {...assert_};
assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e); }})};
assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e as string); }})};
assert.doesNotThrow = function(f: ()=>void) { f(); };
assert.equal = assert.assertEquals;
assert.notEqual = assert.assertNotEquals;
@ -36,7 +36,7 @@ function readFileSync2(x: string, e?: ShEncoding): Uint8Array | string {
if(!e) return u8;
switch(e) {
case 'utf-8': return new TextDecoder().decode(u8);
case 'base64': return base64_.encode(u8);
case 'base64': return base64_.encode(u8 as any);
case 'buffer': return u8;
case 'binary': return Array.from({length: u8.length}, (_,i) => String.fromCharCode(u8[i])).join("");
}
@ -388,9 +388,9 @@ describe('should parse test files', function() {
});
function get_cell(ws: X.WorkSheet, addr: string) {
if(!Array.isArray(ws)) return ws[addr];
if(!Array.isArray(ws["!data"])) return ws[addr];
var a = X.utils.decode_cell(addr);
return (ws[a.r]||[])[a.c];
return (ws["!data"][a.r]||[])[a.c];
}
function each_cell(ws: X.WorkSheet, f: (c: X.CellObject) => any) {
@ -1035,6 +1035,8 @@ describe('parse features', function() {
var wbs: X.WorkBook[] = [], wbs_no_slk: X.WorkBook[] = [];
wbs = CWPaths.map(function(n) { return X.read(fs.readFileSync(n), {type:TYPE, cellStyles:true}); });
wbs_no_slk = wbs.slice(0, 5);
/* */
var ols = OLPaths.map(function(p) { return X.read(fs.readFileSync(p), {type:TYPE, cellStyles:true}); });
it('should have "!cols"', function() {
wbs.forEach(function(wb) { assert.ok(wb.Sheets["Sheet1"]['!cols']); });
});
@ -1066,6 +1068,22 @@ describe('parse features', function() {
assert.equal(x?.[7].wpx, 101);
});
});
it('should have correct outline levels', function() {
ols.map(function(x) { return x.Sheets["Sheet1"]; }).forEach(function(ws) {
var cols = ws['!cols'];
if(!cols) return; // TODO: ODS!!!
for(var i = 0; i < 29; ++i) {
var cell = get_cell(ws, X.utils.encode_col(i) + "1");
var lvl = (cols[i]||{}).level||0;
if(!cell || cell.t == 's') assert.equal(lvl, 0);
else if(cell.t == 'n') {
if(cell.v === 0) assert.equal(lvl, 0);
else assert.equal(lvl, cell.v);
}
}
assert.equal(cols[29].level, 7);
});
});
});
describe('row properties', function() {
@ -1833,6 +1851,32 @@ describe('roundtrip features', function() {
assert.ok(wb7.Workbook?.WBProps?.date1904);
}); });
it('should handle numeric NaN and Infinity', function() {([
"xlsx", "xlsm", "xlsb", "xls", "biff5", "biff4", "biff3", "biff2", "xlml", "csv", "txt", "sylk", "html", "rtf", "prn", "eth", "ods", "fods"
] as Array<X.BookType>).forEach(function(ext) {
var ws: X.DenseWorkSheet = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var buf = X.write(wb, { type: TYPE, bookType: ext, numbers: XLSX_ZAHL });
var wb2 = X.read(buf, { type: TYPE, PRN: true });
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
}); });
});
//function password_file(x){return x.match(/^password.*\.xls$/); }
@ -2585,6 +2629,30 @@ describe('HTML', function() {
assert.equal(range.e.c, expectedCellCount - 1);
});
});
if(domtest) it('should handle numeric NaN and Infinity', function() {
var ws: X.DenseWorkSheet = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var str = X.write(wb, { type: "string", bookType: "html" });
var wb2 = X.utils.table_to_book(get_dom_element(str));
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
});
});
describe('js -> file -> js', function() {
@ -2638,6 +2706,99 @@ describe('rtf', function() {
});
});
describe('dense mode', function() {
it('sheet_new', function() {
var sp = X.utils.sheet_new(); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({}); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({dense: false}); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({dense: true}); assert.ok(!!sp["!data"]);
});
it('read', function() {
ILPaths.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws: X.WorkSheet = wb.Sheets[wb.SheetNames[0]];
assert.equal(ws["A1"].v, "Link to Sheet2");
assert.ok(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(!ws["A1"]);
assert.equal(ws["!data"]?.[0]![0]!.v, "Link to Sheet2");
});
if(!browser) artifax.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(ws["A1"]);
assert.ok(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(!ws["A1"]);
assert.ok(!!ws["!data"]);
assert.ok(ws["!data"]?.[0]![0]);
});
});
it('aoa_to_sheet', function() {
var aoa = [["SheetJS"],[5433795]];
var sp = X.utils.aoa_to_sheet(aoa); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]);
});
it('json_to_sheet', function() {
var json = [{"SheetJS": 5433795}];
var sp = X.utils.json_to_sheet(json); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]);
});
it('sheet_add_aoa', function() {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]);
});
it('sheet_add_json', function() {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader:true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]);
});
for(var ofmti = 0; ofmti < ofmt.length; ++ofmti) { var f = ofmt[ofmti];
it('write ' + f, function() {
var aoa = [["SheetJS"],[5433795]];
var wb = X.utils.book_new(X.utils.aoa_to_sheet(aoa));
var newwb = X.read(X.write(wb, {type:"binary", bookType:f}), {type:"binary"});
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A1").v, "SheetJS");
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A2").v, 5433795);
}); }
it('sheet_to_formulae', function() {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_formulae(wb1.Sheets[n]).sort().join("\n"),
X.utils.sheet_to_formulae(wb2.Sheets[n]).sort().join("\n")
);
});
});
it('sheet_to_csv', function() {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_csv(wb1.Sheets[n]),
X.utils.sheet_to_csv(wb2.Sheets[n])
);
});
});
});
describe('corner cases', function() {
it('output functions', function() {
var ws = X.utils.aoa_to_sheet([
@ -2861,6 +3022,11 @@ describe('corner cases', function() {
}
});
});
if(fs.existsSync(dir + 'shared_formula.xlsx')) it('should properly handle defined names in shared formulae', function() {
var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE});
var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]);
assert.equal(formulae[4], 'A5=nvRTX6090');
});
});
describe('encryption', function() {
@ -2872,14 +3038,14 @@ describe('encryption', function() {
X.read(fs.readFileSync(dir + x), {type:TYPE,password:'Password',WTF:opts.WTF});
throw new Error("incorrect password was accepted");
} catch(e) {
if(e.message != "Password is incorrect") throw e;
if((e as any).message != "Password is incorrect") throw e;
}
});
it('should recognize correct password', function() {
try {
X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
} catch(e) {
if(e.message == "Password is incorrect") throw e;
if((e as any).message == "Password is incorrect") throw e;
}
});
if(false) it('should decrypt file', function() {

21
test.sh

@ -2,8 +2,12 @@
set -euxo pipefail
TZONES=(America/New_York Europe/London Asia/Seoul America/Los_Angeles Europe/Berlin Asia/Kolkata Asia/Shanghai America/Cancun America/Anchorage America/Barbados Asia/Tokyo America/Cayman Pacific/Honolulu America/Mexico_City Asia/Hong_Kong Europe/Paris Atlantic/Azores)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
if [ -e datetest.js ]; then
sudo n 20;
nvm use 20
# sudo n 20;
for TZ in ${TZONES[@]}; do
echo "$TZ"
env TZ="$TZ" mocha -R dot datetest.js
@ -11,19 +15,22 @@ if [ -e datetest.js ]; then
fi
# min test
for n in 20 10 0.8 0.10 0.12 4 6 8 12 14 16 18; do
sudo n $n
for n in 20 10 0.8 0.10 0.12 4 6 8 12 14 16 18 22 24; do
nvm use $n
# sudo n $n
env WTF=1 make testdot_misc
for TZ in ${TZONES[@]}; do
sudo n $n
# sudo n $n
nvm use $n
env WTF=1 TZ="$TZ" make testdot_misc
done
done
# full test
for n in 20 10 0.12; do
for n in 24 16 0.12; do
for TZ in America/New_York Asia/Seoul Asia/Kolkata Europe/Paris; do
sudo n $n
# sudo n $n
nvm use $n
env WTF=1 TZ="$TZ" make testdot
done
done
@ -40,5 +47,3 @@ for TZ in ${TZONES[@]}; do
env TZ="$TZ" WTF=1 make test-deno_misc;
env TZ="$TZ" WTF=1 make test-denocp_misc;
done

@ -1,10 +1,3 @@
var pdizzle = 0, fails = 0, passes = 0;
var describe = function(m,cb){console.log(" ".repeat(pdizzle) + m); ++pdizzle; if(cb) cb(); --pdizzle; };
describe.skip = function(m,cb){};
var it = function(m,cb){console.log(" ".repeat(pdizzle) + m); ++pdizzle; if(cb) try { cb(); ++passes } catch(e) { ++fails, console.log("\x1b[31mFAILED: " + (e.message || e) + "\x1b[0m"); } --pdizzle;};
it.skip = function(m,cb){};
var before = function(cb){if(cb) cb();};
var afterEach = function(cb){if(cb) cb();};
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
/*jshint mocha:true */
@ -43,7 +36,7 @@ if(typeof Buffer !== 'undefined') {
}
var opts = ({cellNF: true}/*:any*/);
var TYPE = browser ? "buffer" : "buffer";
var TYPE = browser ? "binary" : "buffer";
opts.type = TYPE;
var fullex = [".xlsb", /*".xlsm",*/ ".xlsx"/*, ".xlml", ".xls"*/];
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "biff5", "biff8", "xlml", "sylk", "dif", "dbf", "eth", "fods", "csv", "txt", "html"];
@ -378,13 +371,13 @@ if(!browser) describe('should parse test files', function() {
});
function get_cell(ws/*:Worksheet*/, addr/*:string*/) {
if(!Array.isArray(ws)) return ws[addr];
if(!ws["!data"]) return ws[addr];
var a = X.utils.decode_cell(addr);
return (ws[a.r]||[])[a.c];
return (ws["!data"][a.r]||[])[a.c];
}
function each_cell(ws, f) {
if(Array.isArray(ws)) ws.forEach(function(row) { if(row) row.forEach(f); });
if(ws["!data"]) ws["!data"].forEach(function(row) { if(row) row.forEach(f); });
else Object.keys(ws).forEach(function(addr) { if(addr[0] === "!" || !ws.hasOwnProperty(addr)) return; f(ws[addr]); });
}
@ -535,11 +528,11 @@ describe('parse options', function() {
"!ref": "A1:A1",
"A1": { t:"n", v:2, f:"_xlfn.IFS(2>3,1,3>2,2)"}
} } };
var str = X.write(wb, {bookType: "xlsx", type: "buffer"});
var wb2 = X.read(str, {type: "buffer"});
var str = X.write(wb, {bookType: "xlsx", type: "binary"});
var wb2 = X.read(str, {type: "binary"});
/*jshint -W069 */
assert.equal(wb2.Sheets["Sheet1"]["A1"].f, "IFS(2>3,1,3>2,2)");
var wb3 = X.read(str, {type: "buffer", xlfn: true});
var wb3 = X.read(str, {type: "binary", xlfn: true});
assert.equal(wb3.Sheets["Sheet1"]["A1"].f, "_xlfn.IFS(2>3,1,3>2,2)");
/*jshint +W069 */
});
@ -584,7 +577,7 @@ describe('parse options', function() {
checkcells(X.read(fs.readFileSync(p), {type:TYPE, sheetRows:10}), false, false, false, true);
}); });
it('sheetRows n=1', function() { ofmt.forEach(function(fmt) {
[TYPE, "buffer", "buffer", "array"].forEach(function(ot) {
[TYPE, "base64", "binary", "array"].forEach(function(ot) {
var data = [[1,2],[3,4],[5,6]];
var ws = X.utils.aoa_to_sheet(data);
assert.ok(ws['!ref'] === "A1:B3");
@ -688,10 +681,10 @@ describe('parse options', function() {
});
describe('input formats', function() {
if(false) it('should read binary strings', function() { artifax.forEach(function(p) {
it('should read binary strings', function() { artifax.forEach(function(p) {
X.read(fs.readFileSync(p, 'binary'), {type: 'binary'});
}); });
if(false) it('should read base64 strings', function() { artifax.forEach(function(p) {
it('should read base64 strings', function() { artifax.forEach(function(p) {
X.read(fs.readFileSync(p, 'base64'), {type: 'base64'});
}); });
it('handles base64 within data URI scheme (gh-2762)', function() {
@ -710,7 +703,7 @@ describe('input formats', function() {
assert.equal(get_cell(ws, "A3").v, "Sam");
});
});
if(false) if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) {
if(typeof Uint8Array !== 'undefined') it('should read array', function() { artifax.forEach(function(p) {
X.read(fs.readFileSync(p, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
}); });
((browser || typeof Buffer === 'undefined') ? it.skip : it)('should read Buffers', function() { artifax.forEach(function(p) {
@ -811,6 +804,17 @@ describe('API', function() {
]);
if(assert.deepEqual) assert.deepEqual(data.A2, { l: { Target: 'https://123.com' }, v: 'url', t: 's' });
});
it('sheet_to_formulae', function() {
var ws = X.utils.aoa_to_sheet([
["a", "b", "c"],
[1, 2, 3],
[4, 5, 6]
], {dense: true});
ws["!data"][2][0].f = "2*B2";
ws["!data"][2][1].f = "B2+C2";
assert.equal(X.utils.sheet_to_formulae(ws).join("\n"), "A1='a\nB1='b\nC1='c\nA2=1\nB2=2\nC2=3\nA3=2*B2\nB3=B2+C2\nC3=6");
assert.equal(X.utils.sheet_to_formulae(ws, {values: false}).join("\n"), "A3=2*B2\nB3=B2+C2");
});
it('decode_range', function() {
var _c = "ABC", _r = "123", _C = "DEF", _R = "456";
@ -1034,10 +1038,14 @@ describe('parse features', function() {
});
describe('column properties', function() {
var wbs = [], wbs_no_slk = [];
var wbs = [], wbs_no_slk = [], ols = [];
var ol = fs.existsSync(paths.olxls);
var bef = (function() {
wbs = CWPaths.map(function(n) { return X.read(fs.readFileSync(n), {type:TYPE, cellStyles:true}); });
wbs_no_slk = wbs.slice(0, 5);
/* */
if(!ol) return;
ols = OLPaths.map(function(p) { return X.read(fs.readFileSync(p), {type:TYPE, cellStyles:true}); });
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
@ -1072,6 +1080,22 @@ describe('parse features', function() {
assert.equal(x[7].wpx, 101);
});
});
it('should have correct outline levels', function() {
ols.map(function(x) { return x.Sheets["Sheet1"]; }).forEach(function(ws) {
var cols = ws['!cols'];
if(!cols) return; // TODO: ODS!!!
for(var i = 0; i < 29; ++i) {
var cell = get_cell(ws, X.utils.encode_col(i) + "1");
var lvl = (cols[i]||{}).level||0;
if(!cell || cell.t == 's') assert.equal(lvl, 0);
else if(cell.t == 'n') {
if(cell.v === 0) assert.equal(lvl, 0);
else assert.equal(lvl, cell.v);
}
}
assert.equal(cols[29].level, 7);
});
});
});
describe('row properties', function() {
@ -1267,8 +1291,8 @@ describe('parse features', function() {
if(typeof before != 'undefined') before(bef);
else it('before', bef);
['xlsx', 'xlsb'].forEach(function(m) { it(m, function() {
var bstr = X.write(wb, {type: "buffer", bookType: m});
var nwb = X.read(bstr, {type: "buffer"});
var bstr = X.write(wb, {type: "binary", bookType: m});
var nwb = X.read(bstr, {type: "binary"});
assert.equal(nwb.Workbook.WBProps.CodeName, wb.Workbook.WBProps.CodeName);
}); });
});
@ -1506,7 +1530,7 @@ describe('write features', function() {
var sheet = X.utils.aoa_to_sheet([["abc"]]);
get_cell(sheet, "A1").h = "<b>abc</b>";
var wb = {SheetNames:["Sheet1"], Sheets:{Sheet1:sheet}};
var str = X.write(wb, {bookType:"html", type:"buffer"});
var str = X.write(wb, {bookType:"html", type:"binary"});
assert.ok(str.indexOf("<b>abc</b>") > 0);
});
});
@ -1613,7 +1637,7 @@ function parseDate(str/*:string*/, date1904/*:boolean*/)/*:Date*/ {
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
if(false) describe('roundtrip features', function() {
describe('roundtrip features', function() {
describe('should preserve core properties', function() { [
['xls', paths.cpxls],
['xlml', paths.cpxml],
@ -1734,7 +1758,7 @@ if(false) describe('roundtrip features', function() {
['xlsb', paths.pmxlsb]
].forEach(function(w) { it(w[0], function() {
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"binary"}), {type:"binary"});
[
/* Sheet Name Margins: left right top bottom head foot */
["Normal", [0.70, 0.70, 0.75, 0.75, 0.30, 0.30]],
@ -1880,6 +1904,32 @@ if(false) describe('roundtrip features', function() {
assert.ok(wb7.Workbook.WBProps.date1904);
}); });
it('should handle numeric NaN and Infinity', function() {[
"xlsx", "xlsm", "xlsb", "xls", "biff5", "biff4", "biff3", "biff2", "xlml", "csv", "txt", "sylk", "html", "rtf", "prn", "eth", "ods", "fods"
].forEach(function(ext) {
var ws = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var buf = X.write(wb, { type: TYPE, bookType: ext, numbers: XLSX_ZAHL });
var wb2 = X.read(buf, { type: TYPE, PRN: true });
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
}); });
});
//function password_file(x){return x.match(/^password.*\.xls$/); }
@ -1888,7 +1938,7 @@ var password_files = [
"password_2002_40_xor.xls"
];
describe('invalid files', function() {
if(false) describe('parse', function() { [
describe('parse', function() { [
['KEY files', 'numbers/Untitled.key'],
['PAGES files', 'numbers/Untitled.pages'],
['password', 'apachepoi_password.xls'],
@ -2187,21 +2237,18 @@ var html_bstr = make_html_str(1), html_str = make_html_str(0);
var csv_bstr = make_csv_str(1), csv_str = make_csv_str(0);
// WTF=1 make test-bun_misc in bun 1.0.15 reached this point
console.log(`${fails} FAILED ${passes} PASSED`); process.exit(+!!(fails > 0));
describe('CSV', function() {
describe('input', function(){
var b = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
it('should generate date numbers by default', function() {
var opts = {type:"buffer"};
var opts = {type:"binary"};
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
assert.equal(cell.w, '2/19/14');
assert.equal(cell.t, 'n');
assert.ok(typeof cell.v == "number");
});
it('should generate dates when requested', function() {
var opts = {type:"buffer", cellDates:true};
var opts = {type:"binary", cellDates:true};
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
assert.equal(cell.w, '2/19/14');
assert.equal(cell.t, 'd');
@ -2209,7 +2256,7 @@ describe('CSV', function() {
});
it('should use US date code 14 by default', function() {
var opts = ({type:"buffer"}/*:any*/);
var opts = ({type:"binary"}/*:any*/);
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
assert.equal(cell.w, '2/19/14');
opts.cellDates = true;
@ -2217,7 +2264,7 @@ describe('CSV', function() {
assert.equal(cell.w, '2/19/14');
});
it('should honor dateNF override', function() {
var opts = ({type:"buffer", dateNF:"YYYY-MM-DD", cellNF: true}/*:any*/);
var opts = ({type:"binary", dateNF:"YYYY-MM-DD", cellNF: true}/*:any*/);
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
/* NOTE: IE interprets 2-digit years as 19xx */
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19' || cell.w == "2/19/14");
@ -2225,7 +2272,7 @@ describe('CSV', function() {
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
assert.ok(cell.w == '14-02-19' || cell.w == "2/19/14");
var opts = ({type:"buffer", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
var opts = ({type:"binary", dateNF:"YYYY-MM-DD", UTC: true}/*:any*/);
var cell = get_cell(X.read(b, opts).Sheets["Sheet1"], "C3");
/* NOTE: IE interprets 2-digit years as 19xx */
assert.ok(cell.w == '2014-02-19' || cell.w == '1914-02-19');
@ -2235,7 +2282,7 @@ describe('CSV', function() {
});
it('should interpret dateNF', function() {
var bb = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/3/14,0.3\n,,,\nbaz,,qux,\n";
var opts = {type:"buffer", cellDates:true, dateNF:'m/d/yy'};
var opts = {type:"binary", cellDates:true, dateNF:'m/d/yy'};
var cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
assert.equal(cell.v.getMonth(), 1);
assert.equal(cell.w, "2/3/14");
@ -2243,7 +2290,7 @@ describe('CSV', function() {
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
assert.equal(cell.v.getMonth(), 2);
assert.equal(cell.w, "2/3/14");
opts = {type:"buffer", cellDates:true, dateNF:'m/d/yy', UTC: true};
opts = {type:"binary", cellDates:true, dateNF:'m/d/yy', UTC: true};
cell = get_cell(X.read(bb, opts).Sheets["Sheet1"], "C3");
assert.equal(cell.v.getUTCMonth(), 1);
assert.equal(cell.w, "2/3/14");
@ -2252,11 +2299,11 @@ describe('CSV', function() {
assert.equal(cell.v.getUTCMonth(), 2);
assert.equal(cell.w, "2/3/14");
});
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"buffer"}), false); });
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false); });
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_str, {type:"string", raw:true}), true); });
it('should handle formulae', function() {
var bb = '=,=1+1,="100"';
var sheet = X.read(bb, {type:"buffer"}).Sheets["Sheet1"];
var sheet = X.read(bb, {type:"binary"}).Sheets["Sheet1"];
assert.equal(get_cell(sheet, "A1").t, 's');
assert.equal(get_cell(sheet, "A1").v, '=');
assert.equal(get_cell(sheet, "B1").f, '1+1');
@ -2270,7 +2317,7 @@ describe('CSV', function() {
if(!browser || typeof cptable !== 'undefined') it('should honor codepage for binary strings', function() {
var data = "abc,def\nghi,j\xD3l";
[[1251, 'У'],[1252, 'Ó'], [1253, 'Σ'], [1254, 'Ó'], [1255, '׃'], [1256, 'س'], [10000, '”']].forEach(function(m) {
var ws = X.read(data, {type:"buffer", codepage:m[0]}).Sheets["Sheet1"];
var ws = X.read(data, {type:"binary", codepage:m[0]}).Sheets["Sheet1"];
assert.equal(get_cell(ws, "B2").v, "j" + m[1] + "l");
});
});
@ -2280,7 +2327,8 @@ describe('CSV', function() {
["3b", "3 b", "3 b-1"],
["3p", "3 P", "3 p-1"]
];
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true}).Sheets.Sheet1;
var ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: false}).Sheets.Sheet1;
for(var R = 0; R < 3; ++R) {
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
@ -2288,15 +2336,12 @@ describe('CSV', function() {
assert.equal(get_cell(ws, "B2").v, "3 b");
var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "d"); assert.equal(B1.v.getHours(), 3);
var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "d"); assert.equal(B3.v.getHours(), 15);
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false}).Sheets.Sheet1;
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: false, UTC: false}).Sheets.Sheet1;
for(var R = 0; R < 3; ++R) {
assert.equal(get_cell(ws, "A" + (R+1)).v, aoa[R][0]);
assert.equal(get_cell(ws, "C" + (R+1)).v, aoa[R][2]);
}
assert.equal(get_cell(ws, "B2").v, "3 b");
/* this particular case is not well-defined */
//var B1 = get_cell(ws, "B1"); assert.equal(B1.t, "n"); assert.equal((24 + Math.round(B1.v * 24)) % 24, Math.round(3 + 24 + new Date(1899,11,31,0,0,0,0).getTimezoneOffset()/60) % 24);
//var B3 = get_cell(ws, "B3"); assert.equal(B3.t, "n"); assert.equal((24 + Math.round(B3.v * 24)) % 24, Math.round(15 + 24 + new Date(1899,11,31,0,0,0,0).getTimezoneOffset()/60) % 24);
ws = X.read(aoa.map(function(row) { return row.join(","); }).join("\n"), {type: "string", cellDates: true, UTC: true}).Sheets.Sheet1;
for(var R = 0; R < 3; ++R) {
@ -2426,24 +2471,24 @@ describe('sylk', function() {
it('codepage', cpavail ? function() {
var str = "ID;PWXL;N;E\r\nC;X1;Y1;K\"a b\"\r\nE", A1 = "a b";
assert.equal(get_cell(X.read(str, {type:"string"}).Sheets["Sheet1"], "A1").v, A1);
assert.equal(get_cell(X.read(str.replace(//, "\x96"), {type:"buffer", codepage:1252}).Sheets["Sheet1"], "A1").v, A1);
assert.equal(get_cell(X.read(str.replace(//, "\x96"), {type:"binary", codepage:1252}).Sheets["Sheet1"], "A1").v, A1);
if(typeof Buffer !== 'undefined' && !browser) {
assert.equal(get_cell(X.read(Buffer_from(str), {type:"buffer", codepage:65001}).Sheets["Sheet1"], "A1").v, A1);
assert.equal(get_cell(X.read(Buffer_from(str.replace(//, "\x96"), "buffer"), {type:"buffer", codepage:1252}).Sheets["Sheet1"], "A1").v, A1);
assert.equal(get_cell(X.read(Buffer_from(str.replace(//, "\x96"), "binary"), {type:"buffer", codepage:1252}).Sheets["Sheet1"], "A1").v, A1);
}
} : null);
});
describe('date system', function() {
function make_slk(d1904) { return "ID;PSheetJS\nP;Pd\\/m\\/yy\nP;Pd\\/m\\/yyyy\n" + (d1904 != null ? "O;D;V" + d1904 : "") + "\nF;P0;FG0G;X1;Y1\nC;K1\nE"; }
it('should default to 1900', function() {
assert.equal(get_cell(X.read(make_slk(), {type: "buffer"}).Sheets["Sheet1"], "A1").v, 1);
assert.ok(get_cell(X.read(make_slk(), {type: "buffer", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() < 1902);
assert.equal(get_cell(X.read(make_slk(5), {type: "buffer"}).Sheets["Sheet1"], "A1").v, 1);
assert.ok(get_cell(X.read(make_slk(5), {type: "buffer", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() < 1902);
assert.equal(get_cell(X.read(make_slk(), {type: "binary"}).Sheets["Sheet1"], "A1").v, 1);
assert.ok(get_cell(X.read(make_slk(), {type: "binary", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() < 1902);
assert.equal(get_cell(X.read(make_slk(5), {type: "binary"}).Sheets["Sheet1"], "A1").v, 1);
assert.ok(get_cell(X.read(make_slk(5), {type: "binary", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() < 1902);
});
it('should use 1904 when specified', function() {
assert.ok(get_cell(X.read(make_slk(1), {type: "buffer", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() > 1902);
assert.ok(get_cell(X.read(make_slk(4), {type: "buffer", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() > 1902);
assert.ok(get_cell(X.read(make_slk(1), {type: "binary", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() > 1902);
assert.ok(get_cell(X.read(make_slk(4), {type: "binary", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() > 1902);
});
});
});
@ -2481,25 +2526,32 @@ describe('dbf', function() {
['d11', dir + 'dbf/d11.dbf'],
['vfp3', dir + 'dbf/vfp3.dbf']
]/*:any*/);
var wbstrue = ([]);
var wbsfalse = ([]);
var wbstrue = ([]);
var bef = (function() {
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, UTC: false })]; });
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, UTC: true })]; });
wbsfalse = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: false })]; });
wbstrue = wbs.map(function(x) { return [x[0], X.read(fs.readFileSync(x[1]), { type:TYPE, cellDates: true })]; });
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
it(wbs[1][0], function() {
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
var wsfalse = wbsfalse[1][1].Sheets["Sheet1"];
[
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45], ["C2", "v", 12.345], ["D2", "v", 1234.1],
["E2", "w", "19170219", (new Date(1917,1,19).getTimezoneOffset() > 0 ? "19170218" : "19170219")],
["F2", "w", "19170219", (new Date(1917,1,19).getTimezoneOffset() > 0 ? "19170218" : "19170219")],
["G2", "v", 1231.4], ["H2", "v", 123234], ["I2", "v", true], ["L2", "v", "SheetJS"]
["A1", "v", "CHAR10"], ["A2", "v", "test1"], ["B2", "v", 123.45],
["C2", "v", 12.345], ["D2", "v", 1234.1],
["E2", "v", 6260], ["E2", "w", "19170219"],
["F2", "v", 6260], ["F2", "w", "19170219"],
["G2", "v", 1231.4], ["H2", "v", 123234],
["I2", "v", true], ["L2", "v", "SheetJS"]
].forEach(function(r) {
assert.equal(get_cell(wstrue, r[0])[r[1]], r[2]);
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[3] || r[2]);
assert.equal(get_cell(wsfalse, r[0])[r[1]], r[2]);
});
var wstrue = wbstrue[1][1].Sheets["Sheet1"];
[
["E2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["E2", "w", "19170219"],
["F2", "v", Date.UTC(1917,1,19,0,0,0,0)], ["F2", "w", "19170219"]
].forEach(function(r) {
assert.equal(get_cell(wstrue, r[0])[r[1]].valueOf(), r[2].valueOf());
});
});
if(!browser || typeof cptable !== 'undefined') it("Ś╫êëτ⌡ś and Š╫ěéτ⌡š", function() {
@ -2513,8 +2565,7 @@ describe('dbf', function() {
});
});
});
//import { JSDOM } from 'jsdom';
const JSDOM = void 0;
import { JSDOM } from 'jsdom';
var domtest = true;
var inserted_dom_elements = [];
@ -2539,8 +2590,8 @@ describe('HTML', function() {
inserted_dom_elements = [];
});
describe('input string', function() {
it('should interpret values by default', function() { plaintext_test(X.read(html_bstr, {type:"buffer"}), false); });
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(html_bstr, {type:"buffer", raw:true}), true); });
it('should interpret values by default', function() { plaintext_test(X.read(html_bstr, {type:"binary"}), false); });
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(html_bstr, {type:"binary", raw:true}), true); });
it('should handle "string" type', function() { plaintext_test(X.read(html_str, {type:"string"}), false); });
it('should handle newlines correctly', function() {
var table = "<table><tr><td>foo<br/>bar</td><td>baz</td></tr></table>";
@ -2657,10 +2708,34 @@ describe('HTML', function() {
assert.equal(range.e.c, expectedCellCount - 1);
});
});
if(domtest) it('should handle numeric NaN and Infinity', function() {
var ws = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var str = X.write(wb, { type: "string", bookType: "html" });
var wb2 = X.utils.table_to_book(get_dom_element(str));
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
});
});
describe('js -> file -> js', function() {
var wb, BIN="buffer";
var wb, BIN="binary";
var bef = (function() {
var ws = X.utils.aoa_to_sheet([
["number", "bool", "string", "date"],
@ -2714,6 +2789,97 @@ describe('rtf', function() {
});
});
describe('dense mode', function() {
it('sheet_new', function() {
var sp = X.utils.sheet_new(); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({}); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({dense: false}); assert.ok(!sp["!data"]);
sp = X.utils.sheet_new({dense: true}); assert.ok(!!sp["!data"]);
});
it('read', function() {
ILPaths.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws = wb.Sheets[wb.SheetNames[0]];
assert.equal(ws["A1"].v, "Link to Sheet2");
assert.ok(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(!ws["A1"]);
assert.equal(ws["!data"][0][0].v, "Link to Sheet2");
});
if(!browser) artifax.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(ws["A1"]);
assert.ok(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.ok(!ws["A1"]);
assert.ok(ws["!data"][0][0]);
});
});
it('aoa_to_sheet', function() {
var aoa = [["SheetJS"],[5433795]];
var sp = X.utils.aoa_to_sheet(aoa); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
});
it('json_to_sheet', function() {
var json = [{"SheetJS": 5433795}];
var sp = X.utils.json_to_sheet(json); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
});
it('sheet_add_aoa', function() {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
});
it('sheet_add_json', function() {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader:1}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader: 1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: 1}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: 1, dense: true}); assert.equal(ds["!data"][1][0].v, 5433795); assert.ok(!ds["A2"]);
});
ofmt.forEach(function(f) { it('write ' + f, function() {
var aoa = [["SheetJS"],[5433795]];
var wb = X.utils.book_new(X.utils.aoa_to_sheet(aoa));
var newwb = X.read(X.write(wb, {type:"binary", bookType:f}), {type:"binary"});
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A1").v, "SheetJS");
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A2").v, 5433795);
}); });
it('sheet_to_formulae', function() {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_formulae(wb1.Sheets[n]).sort().join("\n"),
X.utils.sheet_to_formulae(wb2.Sheets[n]).sort().join("\n")
);
});
});
it('sheet_to_csv', function() {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_csv(wb1.Sheets[n]),
X.utils.sheet_to_csv(wb2.Sheets[n])
);
});
});
});
describe('corner cases', function() {
it('output functions', function() {
var ws = X.utils.aoa_to_sheet([
@ -2731,13 +2897,13 @@ describe('corner cases', function() {
ws['!cols'] = [ {wch:6}, {wch:7}, {wch:10}, {wch:20} ];
var wb = {SheetNames:['sheetjs'], Sheets:{sheetjs:ws}};
X.write(wb, {type: "buffer", bookType: 'xlsx'});
X.write(wb, {type: "binary", bookType: 'xlsx'});
X.write(wb, {type: TYPE, bookType: 'xlsm'});
X.write(wb, {type: "base64", bookType: 'xlsb'});
X.write(wb, {type: "buffer", bookType: 'ods'});
X.write(wb, {type: "buffer", bookType: 'biff2'});
X.write(wb, {type: "buffer", bookType: 'biff5'});
X.write(wb, {type: "buffer", bookType: 'biff8'});
X.write(wb, {type: "binary", bookType: 'ods'});
X.write(wb, {type: "binary", bookType: 'biff2'});
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.sheet_to_json(ws); });
});
@ -2779,7 +2945,7 @@ describe('corner cases', function() {
}
var ws = X.utils.aoa_to_sheet(data);
var wb = { Sheets:{ Sheet1: ws }, SheetNames: ["Sheet1"] };
var type = "buffer";
var type = "binary";
["xlsb", "biff8", "biff5", "biff2"].forEach(function(btype) {
void X.read(X.write(wb, {bookType:btype, type:type}), {type:type});
});
@ -2937,6 +3103,11 @@ describe('corner cases', function() {
}
});
});
(fs.existsSync(dir + 'shared_formula.xlsx') ? it : it.skip)('should properly handle defined names in shared formulae', function() {
var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE});
var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]);
assert.equal(formulae[4], 'A5=nvRTX6090');
});
});
describe('encryption', function() {

182
test.ts

@ -9,10 +9,10 @@ declare type EmptyFunc = (() => void) | null;
declare var afterEach:(test:EmptyFunc)=>void;
declare var cptable: any;
*/
import * as assert_ from 'https://deno.land/std/testing/asserts.ts';
import * as base64_ from 'https://deno.land/std/encoding/base64.ts';
import * as assert_ from 'https://deno.land/std@0.169.0/testing/asserts.ts';
import * as base64_ from 'https://deno.land/std@0.169.0/encoding/base64.ts';
const assert: any = {...assert_};
assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e); }})};
assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e as string); }})};
assert.doesNotThrow = function(f: ()=>void) { f(); };
assert.equal = assert.assertEquals;
assert.notEqual = assert.assertNotEquals;
@ -36,7 +36,7 @@ function readFileSync2(x: string, e?: ShEncoding): Uint8Array | string {
if(!e) return u8;
switch(e) {
case 'utf-8': return new TextDecoder().decode(u8);
case 'base64': return base64_.encode(u8);
case 'base64': return base64_.encode(u8 as any);
case 'buffer': return u8;
case 'binary': return Array.from({length: u8.length}, (_,i) => String.fromCharCode(u8[i])).join("");
}
@ -388,9 +388,9 @@ Deno.test('should parse test files', async function(t) {
});
function get_cell(ws: X.WorkSheet, addr: string) {
if(!Array.isArray(ws)) return ws[addr];
if(!Array.isArray(ws["!data"])) return ws[addr];
var a = X.utils.decode_cell(addr);
return (ws[a.r]||[])[a.c];
return (ws["!data"][a.r]||[])[a.c];
}
function each_cell(ws: X.WorkSheet, f: (c: X.CellObject) => any) {
@ -1035,6 +1035,8 @@ Deno.test('parse features', async function(t) {
var wbs: X.WorkBook[] = [], wbs_no_slk: X.WorkBook[] = [];
wbs = CWPaths.map(function(n) { return X.read(fs.readFileSync(n), {type:TYPE, cellStyles:true}); });
wbs_no_slk = wbs.slice(0, 5);
/* */
var ols = OLPaths.map(function(p) { return X.read(fs.readFileSync(p), {type:TYPE, cellStyles:true}); });
await t.step('should have "!cols"', async function(t) {
wbs.forEach(function(wb) { assert.assert(wb.Sheets["Sheet1"]['!cols']); });
});
@ -1066,6 +1068,22 @@ Deno.test('parse features', async function(t) {
assert.equal(x?.[7].wpx, 101);
});
});
await t.step('should have correct outline levels', async function(t) {
ols.map(function(x) { return x.Sheets["Sheet1"]; }).forEach(function(ws) {
var cols = ws['!cols'];
if(!cols) return; // TODO: ODS!!!
for(var i = 0; i < 29; ++i) {
var cell = get_cell(ws, X.utils.encode_col(i) + "1");
var lvl = (cols[i]||{}).level||0;
if(!cell || cell.t == 's') assert.equal(lvl, 0);
else if(cell.t == 'n') {
if(cell.v === 0) assert.equal(lvl, 0);
else assert.equal(lvl, cell.v);
}
}
assert.equal(cols[29].level, 7);
});
});
});
await t.step('row properties', async function(t) {
@ -1833,6 +1851,32 @@ Deno.test('roundtrip features', async function(t) {
assert.assert(wb7.Workbook?.WBProps?.date1904);
}); });
await t.step('should handle numeric NaN and Infinity', async function(t) {([
"xlsx", "xlsm", "xlsb", "xls", "biff5", "biff4", "biff3", "biff2", "xlml", "csv", "txt", "sylk", "html", "rtf", "prn", "eth", "ods", "fods"
] as Array<X.BookType>).forEach(function(ext) {
var ws: X.DenseWorkSheet = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var buf = X.write(wb, { type: TYPE, bookType: ext, numbers: XLSX_ZAHL });
var wb2 = X.read(buf, { type: TYPE, PRN: true });
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
}); });
});
//function password_file(x){return x.match(/^password.*\.xls$/); }
@ -2585,6 +2629,30 @@ Deno.test('HTML', async function(t) {
assert.equal(range.e.c, expectedCellCount - 1);
});
});
if(domtest) await t.step('should handle numeric NaN and Infinity', async function(t) {
var ws: X.DenseWorkSheet = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var str = X.write(wb, { type: "string", bookType: "html" });
var wb2 = X.utils.table_to_book(get_dom_element(str));
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
});
});
Deno.test('js -> file -> js', async function(t) {
@ -2638,6 +2706,99 @@ Deno.test('rtf', async function(t) {
});
});
Deno.test('dense mode', async function(t) {
await t.step('sheet_new', async function(t) {
var sp = X.utils.sheet_new(); assert.assert(!sp["!data"]);
sp = X.utils.sheet_new({}); assert.assert(!sp["!data"]);
sp = X.utils.sheet_new({dense: false}); assert.assert(!sp["!data"]);
sp = X.utils.sheet_new({dense: true}); assert.assert(!!sp["!data"]);
});
await t.step('read', async function(t) {
ILPaths.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws: X.WorkSheet = wb.Sheets[wb.SheetNames[0]];
assert.equal(ws["A1"].v, "Link to Sheet2");
assert.assert(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.assert(!ws["A1"]);
assert.equal(ws["!data"]?.[0]![0]!.v, "Link to Sheet2");
});
if(!browser) artifax.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws = wb.Sheets[wb.SheetNames[0]];
assert.assert(ws["A1"]);
assert.assert(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.assert(!ws["A1"]);
assert.assert(!!ws["!data"]);
assert.assert(ws["!data"]?.[0]![0]);
});
});
await t.step('aoa_to_sheet', async function(t) {
var aoa = [["SheetJS"],[5433795]];
var sp = X.utils.aoa_to_sheet(aoa); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
});
await t.step('json_to_sheet', async function(t) {
var json = [{"SheetJS": 5433795}];
var sp = X.utils.json_to_sheet(json); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
});
await t.step('sheet_add_aoa', async function(t) {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
});
await t.step('sheet_add_json', async function(t) {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader:true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
});
for(var ofmti = 0; ofmti < ofmt.length; ++ofmti) { var f = ofmt[ofmti];
await t.step('write ' + f, async function(t) {
var aoa = [["SheetJS"],[5433795]];
var wb = X.utils.book_new(X.utils.aoa_to_sheet(aoa));
var newwb = X.read(X.write(wb, {type:"binary", bookType:f}), {type:"binary"});
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A1").v, "SheetJS");
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A2").v, 5433795);
}); }
await t.step('sheet_to_formulae', async function(t) {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_formulae(wb1.Sheets[n]).sort().join("\n"),
X.utils.sheet_to_formulae(wb2.Sheets[n]).sort().join("\n")
);
});
});
await t.step('sheet_to_csv', async function(t) {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_csv(wb1.Sheets[n]),
X.utils.sheet_to_csv(wb2.Sheets[n])
);
});
});
});
Deno.test('corner cases', async function(t) {
await t.step('output functions', async function(t) {
var ws = X.utils.aoa_to_sheet([
@ -2861,6 +3022,11 @@ Deno.test('corner cases', async function(t) {
}
});
});
if(fs.existsSync(dir + 'shared_formula.xlsx')) await t.step('should properly handle defined names in shared formulae', async function(t) {
var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE});
var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]);
assert.equal(formulae[4], 'A5=nvRTX6090');
});
});
Deno.test('encryption', async function(t) {
@ -2872,14 +3038,14 @@ Deno.test('encryption', async function(t) {
X.read(fs.readFileSync(dir + x), {type:TYPE,password:'Password',WTF:opts.WTF});
throw new Error("incorrect password was accepted");
} catch(e) {
if(e.message != "Password is incorrect") throw e;
if((e as any).message != "Password is incorrect") throw e;
}
});
await t.step('should recognize correct password', async function(t) {
try {
X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
} catch(e) {
if(e.message == "Password is incorrect") throw e;
if((e as any).message == "Password is incorrect") throw e;
}
});
if(false) await t.step('should decrypt file', async function(t) {

@ -1 +0,0 @@
Subproject commit 1ea05a3eee0a746c102dea42e729b31e4ebfca35

@ -9,10 +9,10 @@ declare type EmptyFunc = (() => void) | null;
declare var afterEach:(test:EmptyFunc)=>void;
declare var cptable: any;
*/
import * as assert_ from 'https://deno.land/std/testing/asserts.ts';
import * as base64_ from 'https://deno.land/std/encoding/base64.ts';
import * as assert_ from 'https://deno.land/std@0.169.0/testing/asserts.ts';
import * as base64_ from 'https://deno.land/std@0.169.0/encoding/base64.ts';
const assert: any = {...assert_};
assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e); }})};
assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e as string); }})};
assert.doesNotThrow = function(f: ()=>void) { f(); };
assert.equal = assert.assertEquals;
assert.notEqual = assert.assertNotEquals;
@ -35,7 +35,7 @@ function readFileSync2(x: string, e?: ShEncoding): Uint8Array | string {
if(!e) return u8;
switch(e) {
case 'utf-8': return new TextDecoder().decode(u8);
case 'base64': return base64_.encode(u8);
case 'base64': return base64_.encode(u8 as any);
case 'buffer': return u8;
case 'binary': return Array.from({length: u8.length}, (_,i) => String.fromCharCode(u8[i])).join("");
}
@ -387,9 +387,9 @@ Deno.test('should parse test files', async function(t) {
});
function get_cell(ws: X.WorkSheet, addr: string) {
if(!Array.isArray(ws)) return ws[addr];
if(!Array.isArray(ws["!data"])) return ws[addr];
var a = X.utils.decode_cell(addr);
return (ws[a.r]||[])[a.c];
return (ws["!data"][a.r]||[])[a.c];
}
function each_cell(ws: X.WorkSheet, f: (c: X.CellObject) => any) {
@ -1034,6 +1034,8 @@ Deno.test('parse features', async function(t) {
var wbs: X.WorkBook[] = [], wbs_no_slk: X.WorkBook[] = [];
wbs = CWPaths.map(function(n) { return X.read(fs.readFileSync(n), {type:TYPE, cellStyles:true}); });
wbs_no_slk = wbs.slice(0, 5);
/* */
var ols = OLPaths.map(function(p) { return X.read(fs.readFileSync(p), {type:TYPE, cellStyles:true}); });
await t.step('should have "!cols"', async function(t) {
wbs.forEach(function(wb) { assert.assert(wb.Sheets["Sheet1"]['!cols']); });
});
@ -1065,6 +1067,22 @@ Deno.test('parse features', async function(t) {
assert.equal(x?.[7].wpx, 101);
});
});
await t.step('should have correct outline levels', async function(t) {
ols.map(function(x) { return x.Sheets["Sheet1"]; }).forEach(function(ws) {
var cols = ws['!cols'];
if(!cols) return; // TODO: ODS!!!
for(var i = 0; i < 29; ++i) {
var cell = get_cell(ws, X.utils.encode_col(i) + "1");
var lvl = (cols[i]||{}).level||0;
if(!cell || cell.t == 's') assert.equal(lvl, 0);
else if(cell.t == 'n') {
if(cell.v === 0) assert.equal(lvl, 0);
else assert.equal(lvl, cell.v);
}
}
assert.equal(cols[29].level, 7);
});
});
});
await t.step('row properties', async function(t) {
@ -1832,6 +1850,32 @@ Deno.test('roundtrip features', async function(t) {
assert.assert(wb7.Workbook?.WBProps?.date1904);
}); });
await t.step('should handle numeric NaN and Infinity', async function(t) {([
"xlsx", "xlsm", "xlsb", "xls", "biff5", "biff4", "biff3", "biff2", "xlml", "csv", "txt", "sylk", "html", "rtf", "prn", "eth", "ods", "fods"
] as Array<X.BookType>).forEach(function(ext) {
var ws: X.DenseWorkSheet = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var buf = X.write(wb, { type: TYPE, bookType: ext, numbers: XLSX_ZAHL });
var wb2 = X.read(buf, { type: TYPE, PRN: true });
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
}); });
});
//function password_file(x){return x.match(/^password.*\.xls$/); }
@ -2584,6 +2628,30 @@ Deno.test('HTML', async function(t) {
assert.equal(range.e.c, expectedCellCount - 1);
});
});
if(domtest) await t.step('should handle numeric NaN and Infinity', async function(t) {
var ws: X.DenseWorkSheet = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var str = X.write(wb, { type: "string", bookType: "html" });
var wb2 = X.utils.table_to_book(get_dom_element(str));
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
});
});
Deno.test('js -> file -> js', async function(t) {
@ -2637,6 +2705,99 @@ Deno.test('rtf', async function(t) {
});
});
Deno.test('dense mode', async function(t) {
await t.step('sheet_new', async function(t) {
var sp = X.utils.sheet_new(); assert.assert(!sp["!data"]);
sp = X.utils.sheet_new({}); assert.assert(!sp["!data"]);
sp = X.utils.sheet_new({dense: false}); assert.assert(!sp["!data"]);
sp = X.utils.sheet_new({dense: true}); assert.assert(!!sp["!data"]);
});
await t.step('read', async function(t) {
ILPaths.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws: X.WorkSheet = wb.Sheets[wb.SheetNames[0]];
assert.equal(ws["A1"].v, "Link to Sheet2");
assert.assert(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.assert(!ws["A1"]);
assert.equal(ws["!data"]?.[0]![0]!.v, "Link to Sheet2");
});
if(!browser) artifax.forEach(function(p) {
var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true});
var ws = wb.Sheets[wb.SheetNames[0]];
assert.assert(ws["A1"]);
assert.assert(!ws["!data"]);
wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true});
ws = wb.Sheets[wb.SheetNames[0]];
assert.assert(!ws["A1"]);
assert.assert(!!ws["!data"]);
assert.assert(ws["!data"]?.[0]![0]);
});
});
await t.step('aoa_to_sheet', async function(t) {
var aoa = [["SheetJS"],[5433795]];
var sp = X.utils.aoa_to_sheet(aoa); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
});
await t.step('json_to_sheet', async function(t) {
var json = [{"SheetJS": 5433795}];
var sp = X.utils.json_to_sheet(json); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.json_to_sheet(json, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
});
await t.step('sheet_add_aoa', async function(t) {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
});
await t.step('sheet_add_json', async function(t) {
var aoa = [["SheetJS"]];
var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader:true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]);
var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]);
});
for(var ofmti = 0; ofmti < ofmt.length; ++ofmti) { var f = ofmt[ofmti];
await t.step('write ' + f, async function(t) {
var aoa = [["SheetJS"],[5433795]];
var wb = X.utils.book_new(X.utils.aoa_to_sheet(aoa));
var newwb = X.read(X.write(wb, {type:"binary", bookType:f}), {type:"binary"});
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A1").v, "SheetJS");
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A2").v, 5433795);
}); }
await t.step('sheet_to_formulae', async function(t) {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_formulae(wb1.Sheets[n]).sort().join("\n"),
X.utils.sheet_to_formulae(wb2.Sheets[n]).sort().join("\n")
);
});
});
await t.step('sheet_to_csv', async function(t) {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_csv(wb1.Sheets[n]),
X.utils.sheet_to_csv(wb2.Sheets[n])
);
});
});
});
Deno.test('corner cases', async function(t) {
await t.step('output functions', async function(t) {
var ws = X.utils.aoa_to_sheet([
@ -2860,6 +3021,11 @@ Deno.test('corner cases', async function(t) {
}
});
});
if(fs.existsSync(dir + 'shared_formula.xlsx')) await t.step('should properly handle defined names in shared formulae', async function(t) {
var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE});
var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]);
assert.equal(formulae[4], 'A5=nvRTX6090');
});
});
Deno.test('encryption', async function(t) {
@ -2871,14 +3037,14 @@ Deno.test('encryption', async function(t) {
X.read(fs.readFileSync(dir + x), {type:TYPE,password:'Password',WTF:opts.WTF});
throw new Error("incorrect password was accepted");
} catch(e) {
if(e.message != "Password is incorrect") throw e;
if((e as any).message != "Password is incorrect") throw e;
}
});
await t.step('should recognize correct password', async function(t) {
try {
X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
} catch(e) {
if(e.message == "Password is incorrect") throw e;
if((e as any).message == "Password is incorrect") throw e;
}
});
if(false) await t.step('should decrypt file', async function(t) {

@ -690,7 +690,6 @@ apachepoi_15573.xls
apachepoi_1904DateWindowing.xls
apachepoi_19599-1.xls
apachepoi_19599-2.xls
apachepoi_22742.xls
apachepoi_24207.xls
apachepoi_24215.xls
apachepoi_25183.xls

96
tests/core.js generated

@ -54,7 +54,7 @@ if(!browser) {
for(var _fileAi = 0; _fileAi < _fileA.length; ++_fileAi) if(test_file(_fileA[_fileAi])) fileA.push(_fileA[_fileAi]);
}
var can_write_numbers = typeof Array.prototype.findIndex == "function" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.indexOf == "function";
var can_write_numbers = typeof Set !== "undefined" && typeof Array.prototype.findIndex == "function" && typeof Uint8Array !== "undefined" && typeof Uint8Array.prototype.indexOf == "function";
/* Excel enforces 31 character sheet limit, although technical file limit is 255 */
function fixsheetname(x/*:string*/)/*:string*/ { return x.substr(0,31); }
@ -800,6 +800,17 @@ describe('API', function() {
]);
if(assert.deepEqual) assert.deepEqual(data.A2, { l: { Target: 'https://123.com' }, v: 'url', t: 's' });
});
it('sheet_to_formulae', function() {
var ws = X.utils.aoa_to_sheet([
["a", "b", "c"],
[1, 2, 3],
[4, 5, 6]
], {dense: true});
ws["!data"][2][0].f = "2*B2";
ws["!data"][2][1].f = "B2+C2";
assert.equal(X.utils.sheet_to_formulae(ws).join("\n"), "A1='a\nB1='b\nC1='c\nA2=1\nB2=2\nC2=3\nA3=2*B2\nB3=B2+C2\nC3=6");
assert.equal(X.utils.sheet_to_formulae(ws, {values: false}).join("\n"), "A3=2*B2\nB3=B2+C2");
});
it('decode_range', function() {
var _c = "ABC", _r = "123", _C = "DEF", _R = "456";
@ -1889,6 +1900,32 @@ describe('roundtrip features', function() {
assert.ok(wb7.Workbook.WBProps.date1904);
}); });
it('should handle numeric NaN and Infinity', function() {[
"xlsx", "xlsm", "xlsb", "xls", "biff5", "biff4", "biff3", "biff2", "xlml", "csv", "txt", "sylk", "html", "rtf", "prn", "eth", "ods", "fods"
].forEach(function(ext) {
var ws = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var buf = X.write(wb, { type: TYPE, bookType: ext, numbers: XLSX_ZAHL });
var wb2 = X.read(buf, { type: TYPE, PRN: true });
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
}); });
});
//function password_file(x){return x.match(/^password.*\.xls$/); }
@ -2176,7 +2213,7 @@ function plaintext_test(wb, raw) {
var sheet = wb.Sheets[wb.SheetNames[0]];
plaintext_val.forEach(function(x) {
var cell = get_cell(sheet, x[0]);
var tcval = x[2+(raw ? 1 : 0)];
var tcval = x[2+(!!raw ? 1 : 0)];
var type = raw ? 's' : x[1];
if(x.length == 1) { if(cell) { assert.equal(cell.t, 'z'); assert.ok(!cell.v); } return; }
assert.equal(cell.v, tcval); assert.equal(cell.t, type);
@ -2535,6 +2572,8 @@ function get_dom_element(html) {
domelt.innerHTML = html;
if(document.body) document.body.appendChild(domelt);
inserted_dom_elements.push(domelt);
var elts = domelt.getElementsByTagName("TABLE");
if(elts && elts[0]) return elts[0];
return domelt.children[0];
}
if(!JSDOM) throw new Error("Browser test fail");
@ -2668,6 +2707,30 @@ describe('HTML', function() {
assert.equal(range.e.c, expectedCellCount - 1);
});
});
if(domtest) it('should handle numeric NaN and Infinity', function() {
var ws = {
"!data": [
[ { t: "s", v: "Inf+" }, { t: "n", v: Infinity } ],
[ { t: "s", v: "Inf-" }, { t: "n", v: -Infinity } ],
[ { t: "s", v: "NaN" }, { t: "n", v: NaN } ],
],
"!ref": "A1:B3"
};
var wb = X.utils.book_new(ws, "Sheet1");
var str = X.write(wb, { type: "string", bookType: "html" });
var wb2 = X.utils.table_to_book(get_dom_element(str));
var csv = X.utils.sheet_to_csv(wb2.Sheets.Sheet1).split(/[\r\n]+/);
assert.equal(csv.length, 3);
assert.equal(csv[0], "Inf+,#DIV/0!");
assert.equal(csv[1], "Inf-,#DIV/0!");
assert.equal(csv[2], "NaN,#NUM!");
assert.equal(wb2.Sheets.Sheet1.B1.t, "e");
assert.equal(wb2.Sheets.Sheet1.B2.t, "e");
assert.equal(wb2.Sheets.Sheet1.B3.t, "e");
assert.equal(wb2.Sheets.Sheet1.B1.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B2.v, 0x07);
assert.equal(wb2.Sheets.Sheet1.B3.v, 0x24);
});
});
describe('js -> file -> js', function() {
@ -2792,7 +2855,29 @@ describe('dense mode', function() {
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A1").v, "SheetJS");
assert.equal(get_cell(newwb.Sheets["Sheet1"], "A2").v, 5433795);
}); });
;});
it('sheet_to_formulae', function() {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_formulae(wb1.Sheets[n]).sort().join("\n"),
X.utils.sheet_to_formulae(wb2.Sheets[n]).sort().join("\n")
);
});
});
it('sheet_to_csv', function() {
var w = ['xlsx', paths.fstxlsx];
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: false});
var wb2 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true, WTF:true, dense: true});
wb1.SheetNames.forEach(function(n) {
assert.equal(
X.utils.sheet_to_csv(wb1.Sheets[n]),
X.utils.sheet_to_csv(wb2.Sheets[n])
);
});
});
});
describe('corner cases', function() {
it('output functions', function() {
@ -3017,6 +3102,11 @@ describe('corner cases', function() {
}
});
});
(fs.existsSync(dir + 'shared_formula.xlsx') ? it : it.skip)('should properly handle defined names in shared formulae', function() {
var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE});
var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]);
assert.equal(formulae[4], 'A5=nvRTX6090');
});
});
describe('encryption', function() {

2
tests/fixtures.js generated

File diff suppressed because one or more lines are too long

69
types/index.d.ts vendored

@ -24,12 +24,12 @@ export function readFile(filename: string, opts?: ParsingOptions): WorkBook;
/** Attempts to parse data */
export function read(data: any, opts?: ParsingOptions): WorkBook;
/** Attempts to write or download workbook data to file */
export function writeFile(data: WorkBook, filename: string, opts?: WritingOptions): any;
export function writeFile(data: WorkBook, filename: string, opts?: WritingOptions): void;
/** Attempts to write or download workbook data to XLSX file */
export function writeFileXLSX(data: WorkBook, filename: string, opts?: WritingOptions): any;
export function writeFileXLSX(data: WorkBook, filename: string, opts?: WritingOptions): void;
/** Attempts to write or download workbook data to file asynchronously */
type CBFunc = () => void;
export function writeFileAsync(filename: string, data: WorkBook, opts: WritingOptions | CBFunc, cb?: CBFunc): any;
export function writeFileAsync(filename: string, data: WorkBook, opts: WritingOptions | CBFunc, cb?: CBFunc): void;
/** Attempts to write the workbook data */
export function write(data: WorkBook, opts: WritingOptions): any;
/** Attempts to write the workbook data as XLSX */
@ -277,7 +277,7 @@ export interface WritingOptions extends CommonOptions {
*/
compression?: boolean;
/** Overwride theme XML when exporting to XLSX/XLSM/XLSB */
/** Override theme XML when exporting to XLSX/XLSM/XLSB */
themeXLSX?: string;
/**
@ -317,6 +317,9 @@ export interface WritingOptions extends CommonOptions {
/** Record Separator ("row separator") for CSV / Text output */
RS?: string;
/** Skip certain validity checks (NOTE: generated files may not open in Excel) */
unsafe?: boolean;
}
/** Workbook Object */
@ -575,14 +578,14 @@ export interface Sheet {
* Dense-mode store cells in the '!data' key
* Special keys start with '!'
*/
[cell: string]: CellObject | CellObject[][] | SheetKeys | any;
[cell: string]: CellObject | DenseSheetData | SheetKeys | any;
/**
* Dense-mode worksheets store data in an array of arrays
*
* Cells are accessed with sheet['!data'][R][C] (where R and C are 0-indexed)
*/
'!data'?: CellObject[][];
'!data'?: DenseSheetData;
/** Sheet type */
'!type'?: SheetType;
@ -599,15 +602,16 @@ export interface DenseSheet extends Sheet {
* Special keys start with '!'
* Dense-mode worksheets store data in the '!data' key
*/
[cell: string]: CellObject[][] | SheetKeys | any;
[cell: string]: DenseSheetData | SheetKeys | any;
/**
* Dense-mode worksheets store data in an array of arrays
*
* Cells are accessed with sheet['!data'][R][C] (where R and C are 0-indexed)
*/
'!data': CellObject[][];
'!data': DenseSheetData;
}
export type DenseSheetData = ((CellObject|undefined)[]|undefined)[];
/** General object representing a sparse Sheet (worksheet or chartsheet) */
export interface SparseSheet extends Sheet {
/**
@ -650,14 +654,7 @@ export interface WorkSheet extends Sheet {
'!autofilter'?: AutoFilterInfo;
}
/** Dense Worksheet Object */
export interface DenseWorkSheet extends DenseSheet {
/**
* Dense-mode worksheets store data in an array of arrays
*
* Cells are accessed with sheet['!data'][R][C] (where R and C are 0-indexed)
*/
'!data': CellObject[][];
}
export interface DenseWorkSheet extends DenseSheet {}
/**
* Worksheet Object with CellObject type
@ -836,6 +833,14 @@ export interface Sheet2JSONOpts extends DateNFOption {
UTC?: boolean;
}
export interface Sheet2FormulaOpts {
/**
* If false, only export cells with formulae.
* By default, synthetic formulae are generated for each cell.
*/
values?: boolean;
}
export interface UTCDateOption {
/**
* If true, dates are interpreted using the UTC methods
@ -934,7 +939,7 @@ export interface XLSX$Utils {
sheet_to_html(worksheet: WorkSheet, options?: Sheet2HTMLOpts): string;
/** Generates a list of the formulae (with value fallbacks) */
sheet_to_formulae(worksheet: WorkSheet): string[];
sheet_to_formulae(worksheet: WorkSheet, options?: Sheet2FormulaOpts): string[];
/* --- Cell Address Utilities --- */
@ -1020,14 +1025,38 @@ export interface XLSX$Consts {
SHEET_VERYHIDDEN: 2;
}
/** NODE ONLY! these return Readable Streams */
export interface StrideOption {
/** Number of rows to write per step */
stride?: number;
}
export interface XLMLStreamOpts extends WritingOptions, StrideOption {}
/**
* Streaming write methods
*
* These methods are directly compatible with NodeJS `stream.Readable` API
*
* Web Streams (modern browsers) can play nice with NodeJS streams. See the Web
* Demo at https://docs.sheetjs.com/docs/demos/bigdata/worker#streaming-write
*
* NOTE: These methods are not included in the `xlsx.mini.min.js` build!
*/
export interface StreamUtils {
/** Set `Readable` (for environments that do not support NodeJS Streams) */
set_readable(Readable: any): void;
/* --- Worksheet writers --- */
/** CSV output stream, generate one line at a time */
to_csv(sheet: WorkSheet, opts?: Sheet2CSVOpts): any;
/** HTML output stream, generate one line at a time */
to_html(sheet: WorkSheet, opts?: Sheet2HTMLOpts): any;
/** JSON object stream, generate one row at a time */
to_json(sheet: WorkSheet, opts?: Sheet2JSONOpts): any;
/** Set `Readable` (internal) */
set_readable(Readable: any): void;
/* --- Workbook writers --- */
/** XLML output string stream (bookType `xlml`) */
to_xlml(data: WorkBook, opts?: XLMLStreamOpts): any;
}

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false */
var XLSX = {};
function make_xlsx_lib(XLSX){
XLSX.version = '0.20.2';
XLSX.version = '0.20.3';
var current_codepage = 1200, current_ansi = 1252;
/*:: declare var cptable:any; */
/*global cptable:true, window */
@ -559,6 +559,7 @@ function SSF_large_exp(v/*:number*/)/*:string*/ {
}
function SSF_general_num(v/*:number*/)/*:string*/ {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -1256,6 +1257,8 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -1292,6 +1295,8 @@ function SSF_format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt/*:string*/, idx/*:?number*/)/*:number*/ {
@ -1451,7 +1456,9 @@ type CFBFiles = {[n:string]:CFBEntry};
var CRC32 = /*#__PURE__*/(function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*::
type CRC32TableType = Array<number> | Int32Array;
*/
/*global Int32Array */
function signed_crc_table()/*:any*/ {
var c = 0, table/*:Array<number>*/ = new Array(256);
@ -1489,7 +1496,7 @@ var TT = slice_by_16_tables(T0);
var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4];
var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9];
var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
function crc32_bstr(bstr/*:string*/, seed/*:number*/)/*:number*/ {
function crc32_bstr(bstr/*:string*/, seed/*:?number*/)/*:number*/ {
var C = seed/*:: ? 0 : 0 */ ^ -1;
for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF];
return ~C;
@ -2855,8 +2862,8 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -2867,7 +2874,7 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -2902,9 +2909,10 @@ function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
@ -3803,6 +3811,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);
@ -3873,6 +3884,26 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*
}
return z;
}
function parsexmltagraw(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*/)/*:any*/ {
var z = ({}/*:any*/);
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x/*:string*/)/*:string*/ { return x.replace(nsregex2, "<$1"); }
var encodings = {
@ -4385,7 +4416,8 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
/* control buffer usage for fixed-length buffers */
function buf_array()/*:BufArray*/ {
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 256 : 2048;
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 16384 : 2048;
var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function");
var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ {
var o/*:Block*/ = (new_buf(sz)/*:any*/);
prep_blob(o, 0);
@ -4414,10 +4446,15 @@ function buf_array()/*:BufArray*/ {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz);
};
return ({ next:next, push:push, end:end, _bufs:bufs }/*:any*/);
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 }/*:any*/);
}
function write_record(ba/*:BufArray*/, type/*:number*/, payload, length/*:?number*/) {
@ -4609,7 +4646,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
var ws/*:Worksheet*/ = _ws || (dense ? ({"!data": []}) : ({}/*:any*/));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -4634,31 +4671,35 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data[R][C] }/*:any*/);
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data_R[C], t:"" }/*:any*/);
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
else if(!o.sheetStubs) continue;
else cell.t = 'z';
}
else if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'number') {
if(isFinite(cell.v)) cell.t = 'n';
else if(isNaN(cell.v)) { cell.t = 'e'; cell.v = 0x0F; /* #VALUE! */ }
else { cell.t = 'e'; cell.v = 0x07; /*# DIV/0 */ }
}
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.z = o.dateNF || table_fmt[14];
@ -4672,7 +4713,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr/*:any*/;
var cell_ref = encode_col(__C) + (__R + 1)/*:any*/;
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}
@ -4682,7 +4723,6 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
return ws;
}
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
function parse_Int32LE(data) {
return data.read_shift(4, 'i');
}
@ -6266,8 +6306,8 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
case 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,'');
case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob);
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
@ -8562,7 +8602,7 @@ var SYLK = /*#__PURE__*/(function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -8791,7 +8831,7 @@ var ETH = /*#__PURE__*/(function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -8834,11 +8874,7 @@ var ETH = /*#__PURE__*/(function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -8848,6 +8884,19 @@ var ETH = /*#__PURE__*/(function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -8879,6 +8928,7 @@ var PRN = /*#__PURE__*/(function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -8996,6 +9046,8 @@ var PRN = /*#__PURE__*/(function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;
@ -9695,7 +9747,6 @@ var WK_ = /*#__PURE__*/(function() {
else console.error("WK1 bad formula parse |" + out.join("|") + "|");
}
function parse_cell_3(blob/*::, length*/) {
var o = [{c:0,r:0}, {t:'n',v:0}, 0];
o[0].r = blob.read_shift(2); o[3] = blob[blob.l++]; o[0].c = blob[blob.l++];
@ -10931,6 +10982,10 @@ function rtf_to_sheet_str(str, opts) {
if (o.cellText !== false)
cell.w = cell.v;
cell.v = fuzzynum(cell.v);
} else if (RBErr[cell.v] != null) {
cell.t = "e";
cell.w = cell.v;
cell.v = RBErr[cell.v];
}
if (dense)
row[C] = cell;
@ -11266,10 +11321,12 @@ function parse_fonts(t, styles, themes, opts) {
/* 18.8.2 b CT_BooleanProperty */
case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
case '<b/>': font.bold = 1; break;
case '</b>': case '</b': break;
/* 18.8.26 i CT_BooleanProperty */
case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
case '<i/>': font.italic = 1; break;
case '</i>': case '</i': break;
/* 18.4.13 u CT_UnderlineProperty */
case '<u':
@ -11281,48 +11338,55 @@ function parse_fonts(t, styles, themes, opts) {
case "doubleAccounting": font.underline = 0x22; break;
} break;
case '<u/>': font.underline = 1; break;
case '</u>': case '</u': break;
/* 18.4.10 strike CT_BooleanProperty */
case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
case '<strike/>': font.strike = 1; break;
case '</strike>': case '</strike': break;
/* 18.4.2 outline CT_BooleanProperty */
case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
case '<outline/>': font.outline = 1; break;
case '</outline>': case '</outline': break;
/* 18.8.36 shadow CT_BooleanProperty */
case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
case '<shadow/>': font.shadow = 1; break;
case '</shadow>': case '</shadow': break;
/* 18.8.12 condense CT_BooleanProperty */
case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
case '<condense/>': font.condense = 1; break;
case '</condense>': case '</condense': break;
/* 18.8.17 extend CT_BooleanProperty */
case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
case '<extend/>': font.extend = 1; break;
case '</extend>': case '</extend': break;
/* 18.4.11 sz CT_FontSize */
case '<sz': if(y.val) font.sz = +y.val; break;
case '<sz/>': case '</sz>': break;
case '<sz/>': case '</sz>': case '</sz': break;
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<vertAlign/>': case '</vertAlign>': case '</vertAlign': break;
/* 18.8.18 family CT_FontFamily */
case '<family': if(y.val) font.family = parseInt(y.val,10); break;
case '<family/>': case '</family>': break;
case '<family/>': case '</family>': case '</family': break;
/* 18.8.35 scheme CT_FontScheme */
case '<scheme': if(y.val) font.scheme = y.val; break;
case '<scheme/>': case '</scheme>': break;
case '<scheme/>': case '</scheme>': case '</scheme': break;
/* 18.4.1 charset CT_IntProperty */
case '<charset':
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': case '</charset': break;
/* 18.?.? color CT_Color */
case '<color':
@ -11345,11 +11409,11 @@ function parse_fonts(t, styles, themes, opts) {
}
break;
case '<color/>': case '</color>': break;
case '<color/>': case '</color>': case '</color': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
case '</AlternateContent>': case '</AlternateContent': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -15855,7 +15919,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
var merges/*:Array<Range>*/ = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -16314,16 +16378,17 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*//*::, rels*/)/*:string*/ {
var o/*:Array<string>*/ = [], r/*:Array<string>*/ = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols/*:Array<string>*/ = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
var data_R = dense ? data[R] : [];
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}
@ -17325,12 +17390,15 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) {
if(last_seen) write_record(ba, 0x000D /* BrtShortRk */, write_BrtShortRk(cell, o));
else write_record(ba, 0x0002 /* BrtCellRk */, write_BrtCellRk(cell, o));
} else if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else if(!isFinite(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
o.t = "e";
if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
}
} else {
if(last_seen) write_record(ba, 0x0010 /* BrtShortReal */, write_BrtShortReal(cell, o));
else write_record(ba, 0x0005 /* BrtCellReal */, write_BrtCellReal(cell, o));
@ -17352,23 +17420,24 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
}
function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols/*:Array<string>*/ = [];
var range = safe_decode_range(ws['!ref'] || "A1"), rr = "", cols/*:Array<string>*/ = [];
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
write_record(ba, 0x0091 /* BrtBeginSheetData */);
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, row = dense ? ws["!data"][range.s.r] : [];
var cap = range.e.r;
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
for(var R = range.s.r; R <= cap; ++R) {
rr = encode_row(R);
if(dense) row = ws["!data"][R];
/* [ACCELLTABLE] */
/* BrtRowHdr */
write_row_header(ba, ws, range, R);
if(dense && !row) continue;
var last_seen = false;
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
var cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) { last_seen = false; continue; }
/* write cell */
last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904);
@ -19640,7 +19709,13 @@ function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb,
var t = "", p = "";
switch(cell.t) {
case 'z': if(!opts.sheetStubs) return ""; break;
case 'n': t = 'Number'; p = String(cell.v); break;
case 'n': {
if(!isFinite(cell.v)) {
t = 'Error'; p = BErr[isNaN(cell.v) ? 0x24 : 0x07];
} else {
t = 'Number'; p = String(cell.v);
}
} break;
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
case 'e': t = 'Error'; p = BErr[cell.v]; break;
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || table_fmt[14]; break;
@ -19682,9 +19757,12 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
o.push(writextag("Column",null,k));
});
var dense = ws["!data"] != null;
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
@ -19695,7 +19773,6 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
break;
}
if(skip) continue;
var addr = {r:R,c:C};
var ref = encode_col(C) + encode_row(R), cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr));
}
@ -19719,7 +19796,7 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
/* WorksheetOptions */
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
if(ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
if(ws && ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
return o.join("");
}
@ -19738,11 +19815,10 @@ function write_xlml(wb, opts)/*:string*/ {
d.push(write_props_xlml(wb, opts));
d.push(write_wb_xlml(wb, opts));
d.push("");
d.push("");
d.push(write_names_xlml(wb, opts));
for(var i = 0; i < wb.SheetNames.length; ++i)
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
d[2] = write_sty_xlml(wb, opts);
d[3] = write_names_xlml(wb, opts);
return XML_HEADER + writextag("Workbook", d.join(""), {
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
@ -21928,7 +22004,7 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts,
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, 0x3FFF);
range.e.r = Math.min(range.e.r, 0x3FFF);
}
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
var row = [], comments = [];
@ -22338,9 +22414,9 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
var range = safe_decode_range(ws['!ref'] || "A1");
var MAX_ROWS = b8 ? 65536 : 16384;
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV" + MAX_ROWS);
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
range.e.r = Math.min(range.e.r, MAX_ROWS-1);
}
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
@ -22375,12 +22451,11 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
if(dense) row = ws["!data"][R] || [];
rr = encode_row(R);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var cell = dense ? row[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) continue;
/* write cell */
write_ws_biff8_cell(ba, cell, R, C, opts, date1904);
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
if(b8 && cell.l) ws['!links'].push([cols[C] + rr, cell.l]);
if(cell.c) comments.push([cell.c, R, C]);
}
}
@ -22524,6 +22599,9 @@ function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
if(range.e.c > 255) { // note: 255 is IV
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond column IV (255). Data may be lost.");
}
if(range.e.r > 65535) {
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond row 65536. Data may be lost.");
}
}
var o = opts || {};
@ -22583,6 +22661,8 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
if(opts.UTC === false) o.v = utc_to_local(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
} else if(m.charCodeAt(0) == 35 /* # */ && RBErr[m] != null) {
o.t = 'e'; o.w = m; o.v = RBErr[m];
}
if(o.cellText !== false) o.w = m;
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
@ -22610,6 +22690,10 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
if(RS < 0) continue;
var coord = encode_col(C) + encode_row(R);
var cell = dense ? (ws["!data"][R]||[])[C] : ws[coord];
if(cell && cell.t == 'n' && cell.v != null && !isFinite(cell.v)) {
if(isNaN(cell.v)) cell = ({t:'e', v:0x24, w:BErr[0x24]});
else cell = ({t:'e', v:0x07, w:BErr[0x07]});
}
/* TODO: html entities */
var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
sp = ({}/*:any*/);
@ -22720,6 +22804,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(v != null) {
if(v.length == 0) o.t = _t || 'z';
else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(_t == "e" && BErr[+v]) o = {t:'e', v:+v, w: BErr[+v]};
else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -22728,7 +22813,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(opts.UTC) o.v = local_to_utc(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
}
} else if(v.charCodeAt(0) == 35 /* # */ && RBErr[v] != null) o = ({t:'e', v: RBErr[v], w: v});
}
if(o.z === undefined && z != null) o.z = z;
/* The first link is used. Links are assumed to be fully specified.
@ -23029,7 +23114,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
var Sheets = {}, SheetNames/*:Array<string>*/ = [];
var ws = ({}/*:any*/); if(opts.dense) ws["!data"] = [];
var Rn, q/*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
var ctag = ({value:""}/*:any*/);
var ctag = ({value:""}/*:any*/), ctag2 = ({}/*:any*/);
var textp = "", textpidx = 0, textptag/*:: = {}*/, oldtextp = "", oldtextpidx = 0;
var textR = [], oldtextR = [];
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
@ -23088,10 +23173,18 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
C = -1; break;
case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
if(Rn[1] !== '/') ++C;
if(opts.sheetStubs) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
if(Rn[1] !== '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1",10) || 1;
if(opts.sheetStubs) {
while(colpeat-- > 0) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
++C;
} --C;
}
else C += colpeat - 1;
}
textp = ""; textR = [];
break; /* stub */
@ -23099,7 +23192,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(Rn[0].charAt(Rn[0].length-2) === '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10)||1;
q = ({t:'z', v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -23123,6 +23216,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(R < range.s.r) range.s.r = R;
if(rptR > range.e.r) range.e.r = rptR;
ctag = parsexmltag(Rn[0], false);
ctag2 = parsexmltagraw(Rn[0], true);
comments = []; comment = ({}/*:any*/);
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -23142,10 +23236,12 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
q.F = arrayf[i][1];
}
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
mC = parseInt(ctag['number-columns-spanned'],10) || 0;
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
mR = parseInt(ctag['number-rows-spanned']||"1",10) || 1;
mC = parseInt(ctag['number-columns-spanned']||"1",10) || 1;
if(mR * mC > 1) {
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
}
}
/* 19.675.2 table:number-columns-repeated */
@ -23176,6 +23272,9 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
}
} else {
isstub = false;
if(ctag2['calcext:value-type'] == "error" && RBErr[textp] != null) {
q.t = 'e'; q.w = textp; q.v = RBErr[textp];
}
if(q.t === 's') {
q.v = textp || '';
if(textR.length) q.R = textR;
@ -23574,7 +23673,6 @@ function parse_fods(data/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
wb.bookType = "fods";
return wb;
}
/* OpenDocument */
var write_styles_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function() {
var master_styles = [
@ -23839,9 +23937,22 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
break;
case 'n':
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
if(!isFinite(cell.v)) {
if(isNaN(cell.v)) {
textp = "#NUM!";
ct['table:formula'] = "of:=#NUM!";
} else {
textp = "#DIV/0!";
ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
}
ct['office:string-value'] = "";
ct['office:value-type'] = "string";
ct['calcext:value-type'] = "error";
} else {
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
}
break;
case 's': case 'str':
textp = cell.v == null ? "" : cell.v;
@ -25193,7 +25304,7 @@ function s5s_to_iwa_comment(s5s) {
return out;
}
function parse_TST_TableModelArchive(M, root, ws, opts) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
var pb = parse_shallow(root.data);
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
@ -25272,6 +25383,38 @@ function parse_TST_TableModelArchive(M, root, ws, opts) {
};
});
}
if (!((_k = ws["!merges"]) == null ? void 0 : _k.length) && ((_l = pb[47]) == null ? void 0 : _l[0])) {
var merge_owner = parse_shallow(pb[47][0].data);
if ((_m = merge_owner[2]) == null ? void 0 : _m[0]) {
var formula_store = parse_shallow(merge_owner[2][0].data);
if ((_n = formula_store[3]) == null ? void 0 : _n[0]) {
ws["!merges"] = mappa(formula_store[3], function(u) {
var _a2, _b2, _c2, _d2, _e2;
var formula_pair = parse_shallow(u);
var formula = parse_shallow(formula_pair[2][0].data);
var AST_node_array = parse_shallow(formula[1][0].data);
if (!((_a2 = AST_node_array[1]) == null ? void 0 : _a2[0]))
return;
var AST_node0 = parse_shallow(AST_node_array[1][0].data);
var AST_node_type = varint_to_i32(AST_node0[1][0].data);
if (AST_node_type != 67)
return;
var AST_colon_tract = parse_shallow(AST_node0[40][0].data);
if (!((_b2 = AST_colon_tract[3]) == null ? void 0 : _b2[0]) || !((_c2 = AST_colon_tract[4]) == null ? void 0 : _c2[0]))
return;
var colrange = parse_shallow(AST_colon_tract[3][0].data);
var rowrange = parse_shallow(AST_colon_tract[4][0].data);
var c = varint_to_i32(colrange[1][0].data);
var C = ((_d2 = colrange[2]) == null ? void 0 : _d2[0]) ? varint_to_i32(colrange[2][0].data) : c;
var r = varint_to_i32(rowrange[1][0].data);
var R = ((_e2 = rowrange[2]) == null ? void 0 : _e2[0]) ? varint_to_i32(rowrange[2][0].data) : r;
return { s: { r: r, c: c }, e: { r: R, c: C } };
}).filter(function(x) {
return x != null;
});
}
}
}
}
function parse_TST_TableInfoArchive(M, root, opts) {
var pb = parse_shallow(root.data);
@ -27082,6 +27225,8 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var o = opts||{};
if(o.codepage && typeof $cptable === "undefined") console.error("Codepage tables are not loaded. Non-ASCII characters may not give expected results");
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
/* Javet projects `byte[]` to `Int8Array` */
if(typeof Int8Array !== 'undefined' && data instanceof Int8Array) return readSync(new Uint8Array(data.buffer, data.byteOffset, data.length), 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; }
@ -27444,7 +27589,7 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) {
}
var qreg = /"/g;
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, w/*:number*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
var isempty = true;
var row/*:Array<string>*/ = [], txt = "", rr = encode_row(R);
var dense = sheet["!data"] != null;
@ -27457,7 +27602,7 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr
isempty = false;
txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
if(txt == "ID") txt = '"ID"';
if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"';
} else if(val.f != null && !val.F) {
isempty = false;
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
@ -27484,7 +27629,7 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
var w = 0;
for(var R = r.s.r; R <= r.e.r; ++R) {
if ((rowinfo[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o);
if(row == null) { continue; }
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
}
@ -27499,7 +27644,7 @@ function sheet_to_txt(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
function sheet_to_formulae(sheet/*:Worksheet*/, opts/*:?Sheet2FormulaOpts*/)/*:Array<string>*/ {
var y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols/*:Array<string>*/ = [], C;
@ -27520,6 +27665,7 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
if(y.indexOf(":") == -1) y = y + ":" + y;
}
if(x.f != null) val = x.f;
else if(opts && opts.values === false) continue;
else if(x.t == 'z') continue;
else if(x.t == 'n' && x.v != null) val = "" + x.v;
else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";
@ -27788,7 +27934,7 @@ function write_csv_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
while(R <= r.e.r) {
++R;
if ((rowinfo[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, w, o);
if(row != null) {
if(row || (o.blankrows !== false)) return stream.push((w++ ? RS : "") + row);
}
@ -27885,10 +28031,165 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
return stream;
}
function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
var stream = _Readable();
var opts = o == null ? {} : o;
var stride = +opts.stride || 10;
if(!wb.SSF) wb.SSF = dup(table_fmt);
if(wb.SSF) {
make_ssf(); SSF_load_table(wb.SSF);
// $FlowIgnore
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
opts.ssf = wb.SSF;
opts.cellXfs = [];
get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
}
/* do one pass to determine styles since they must be added before tables */
wb.SheetNames.forEach(function(n) {
var ws = wb.Sheets[n];
if(!ws || !ws["!ref"]) return;
var range = decode_range(ws["!ref"]);
var dense = ws["!data"] != null;
var ddata = dense ? ws["!data"] : [];
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
addr.r = R;
if(dense && !ddata[R]) continue;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var cell = dense ? ddata[R][C] : ws[encode_col(C) + encode_row(R)];
if(!cell) continue;
if(cell.t == "d" && cell.z == null) { cell = dup(cell); cell.z = table_fmt[14]; }
void get_cell_style(opts.cellXfs, cell, opts);
}
}
});
var sty = write_sty_xlml(wb, opts);
var stage = 0, wsidx = 0, ws = wb.Sheets[wb.SheetNames[wsidx]], range = safe_decode_range(ws), R = -1, T = false;
var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
stream._read = function() { switch(stage) {
/* header */
case 0: {
stage = 1;
stream.push(XML_HEADER);
stream.push("<Workbook" + wxt_helper({
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
'xmlns:x': XLMLNS.x,
'xmlns:ss': XLMLNS.ss,
'xmlns:dt': XLMLNS.dt,
'xmlns:html': XLMLNS.html
}) + ">");
} break;
/* preamble */
case 1: {
stage = 2;
stream.push(write_props_xlml(wb, opts));
stream.push(write_wb_xlml(wb, opts));
} break;
/* style and name tables */
case 2: {
stage = 3;
stream.push(sty);
stream.push(write_names_xlml(wb, opts));
} break;
/* worksheet preamble */
case 3: {
T = false;
if(wsidx >= wb.SheetNames.length) { stage = -1; stream.push(""); break; }
stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
ws = wb.Sheets[wb.SheetNames[wsidx]];
if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
var names = write_ws_xlml_names(ws, opts, wsidx, wb);
if(names.length) stream.push("<Names>" + names + "</Names>");
if(!ws["!ref"]) return (stage = 5);
range = safe_decode_range(ws["!ref"]);
R = range.s.r;
stage = 4;
} break;
/* worksheet intramble */
case 4: {
if(R < 0 || R > range.e.r) { if(T) stream.push("</Table>"); return void (stage = 5); }
if(R <= range.s.r) {
if(ws['!cols']) ws['!cols'].forEach(function(n, i) {
process_col(n);
var w = !!n.width;
var p = col_obj_w(i, n);
var k/*:any*/ = {"ss:Index":i+1};
if(w) k['ss:Width'] = width2px(p.width);
if(n.hidden) k['ss:Hidden']="1";
if(!T) { T = true; stream.push("<Table>"); }
stream.push(writextag("Column",null,k));
});
dense = ws["!data"] != null;
if(dense) darr = ws["!data"];
addr.r = addr.c = 0;
}
/* process `stride` rows per invocation */
for(var cnt = 0; R <= range.e.r && cnt < stride; ++R, ++cnt) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
if(!(dense && !darr[R])) for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
if(marr[mi].s.r > R) continue;
if(marr[mi].e.c < C) continue;
if(marr[mi].e.r < R) continue;
if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
break;
}
if(skip) continue;
var ref = encode_col(C) + encode_row(R), cell = dense ? darr[R][C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, wsidx, wb, addr));
}
row.push("</Row>");
if(!T) { T = true; stream.push("<Table>"); }
stream.push(row.join(""));
}
} break;
/* worksheet postamble */
case 5: {
stream.push(write_ws_xlml_wsopts(ws, opts, wsidx, wb));
if(ws && ws["!autofilter"]) stream.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
stream.push("</Worksheet>");
wsidx++; R = -1;
return void (stage = 3);
}
/* footer */
case -1: {
stage = -2;
stream.push("</Workbook>");
} break;
/* exeunt */
case -2: stream.push(null); break;
}};
return stream;
}
var __stream = {
to_json: write_json_stream,
to_html: write_html_stream,
to_csv: write_csv_stream,
to_xlml: write_xlml_stream,
set_readable: set_readable
};
if(typeof parse_xlscfb !== "undefined") XLSX.parse_xlscfb = parse_xlscfb;

458
xlsx.js generated

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false */
var XLSX = {};
function make_xlsx_lib(XLSX){
XLSX.version = '0.20.2';
XLSX.version = '0.20.3';
var current_codepage = 1200, current_ansi = 1252;
/*global cptable:true, window */
var $cptable;
@ -539,6 +539,7 @@ function SSF_large_exp(v) {
}
function SSF_general_num(v) {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -1232,6 +1233,8 @@ function choose_fmt(f, v) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -1268,6 +1271,8 @@ function SSF_format(fmt,v,o) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt, idx) {
@ -1391,7 +1396,6 @@ function SSF__load(fmt, idx) {
var CRC32 = (function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*global Int32Array */
function signed_crc_table() {
var c = 0, table = new Array(256);
@ -2790,8 +2794,8 @@ function parse_local_file(blob, csz, usz, o, EF) {
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -2802,7 +2806,7 @@ function parse_local_file(blob, csz, usz, o, EF) {
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -2837,9 +2841,10 @@ function write_zip(cfb, options) {
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
@ -3732,6 +3737,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);
@ -3802,6 +3810,26 @@ function parsexmltag(tag, skip_root, skip_LC) {
}
return z;
}
function parsexmltagraw(tag, skip_root, skip_LC) {
var z = ({});
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x) { return x.replace(nsregex2, "<$1"); }
var encodings = {
@ -4308,7 +4336,8 @@ function recordhopper(data, cb, opts) {
/* control buffer usage for fixed-length buffers */
function buf_array() {
var bufs = [], blksz = has_buf ? 256 : 2048;
var bufs = [], blksz = has_buf ? 16384 : 2048;
var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function");
var newblk = function ba_newblk(sz) {
var o = (new_buf(sz));
prep_blob(o, 0);
@ -4337,10 +4366,15 @@ function buf_array() {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz);
};
return ({ next:next, push:push, end:end, _bufs:bufs });
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 });
}
function write_record(ba, type, payload, length) {
@ -4527,7 +4561,7 @@ function sheet_add_aoa(_ws, data, opts) {
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws = _ws || ({});
var ws = _ws || (dense ? ({"!data": []}) : ({}));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -4552,31 +4586,35 @@ function sheet_add_aoa(_ws, data, opts) {
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell = ({v: data[R][C] });
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell = ({v: data_R[C], t:"" });
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
else if(!o.sheetStubs) continue;
else cell.t = 'z';
}
else if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'number') {
if(isFinite(cell.v)) cell.t = 'n';
else if(isNaN(cell.v)) { cell.t = 'e'; cell.v = 0x0F; /* #VALUE! */ }
else { cell.t = 'e'; cell.v = 0x07; }
}
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.z = o.dateNF || table_fmt[14];
@ -4590,7 +4628,7 @@ function sheet_add_aoa(_ws, data, opts) {
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr;
var cell_ref = encode_col(__C) + (__R + 1);
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}
@ -4600,7 +4638,6 @@ function sheet_add_aoa(_ws, data, opts) {
return ws;
}
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
function parse_Int32LE(data) {
return data.read_shift(4, 'i');
}
@ -6182,8 +6219,8 @@ function parse_TypedPropertyValue(blob, type, _opts) {
case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
case 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,'');
case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob);
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
@ -8475,7 +8512,7 @@ var SYLK = (function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -8704,7 +8741,7 @@ var ETH = (function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -8747,11 +8784,7 @@ var ETH = (function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -8761,6 +8794,19 @@ var ETH = (function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -8792,6 +8838,7 @@ var PRN = (function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -8909,6 +8956,8 @@ var PRN = (function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;
@ -9608,7 +9657,6 @@ var WK_ = (function() {
else console.error("WK1 bad formula parse |" + out.join("|") + "|");
}
function parse_cell_3(blob) {
var o = [{c:0,r:0}, {t:'n',v:0}, 0];
o[0].r = blob.read_shift(2); o[3] = blob[blob.l++]; o[0].c = blob[blob.l++];
@ -10843,6 +10891,10 @@ function rtf_to_sheet_str(str, opts) {
if (o.cellText !== false)
cell.w = cell.v;
cell.v = fuzzynum(cell.v);
} else if (RBErr[cell.v] != null) {
cell.t = "e";
cell.w = cell.v;
cell.v = RBErr[cell.v];
}
if (dense)
row[C] = cell;
@ -11178,10 +11230,12 @@ function parse_fonts(t, styles, themes, opts) {
/* 18.8.2 b CT_BooleanProperty */
case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
case '<b/>': font.bold = 1; break;
case '</b>': case '</b': break;
/* 18.8.26 i CT_BooleanProperty */
case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
case '<i/>': font.italic = 1; break;
case '</i>': case '</i': break;
/* 18.4.13 u CT_UnderlineProperty */
case '<u':
@ -11193,48 +11247,55 @@ function parse_fonts(t, styles, themes, opts) {
case "doubleAccounting": font.underline = 0x22; break;
} break;
case '<u/>': font.underline = 1; break;
case '</u>': case '</u': break;
/* 18.4.10 strike CT_BooleanProperty */
case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
case '<strike/>': font.strike = 1; break;
case '</strike>': case '</strike': break;
/* 18.4.2 outline CT_BooleanProperty */
case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
case '<outline/>': font.outline = 1; break;
case '</outline>': case '</outline': break;
/* 18.8.36 shadow CT_BooleanProperty */
case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
case '<shadow/>': font.shadow = 1; break;
case '</shadow>': case '</shadow': break;
/* 18.8.12 condense CT_BooleanProperty */
case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
case '<condense/>': font.condense = 1; break;
case '</condense>': case '</condense': break;
/* 18.8.17 extend CT_BooleanProperty */
case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
case '<extend/>': font.extend = 1; break;
case '</extend>': case '</extend': break;
/* 18.4.11 sz CT_FontSize */
case '<sz': if(y.val) font.sz = +y.val; break;
case '<sz/>': case '</sz>': break;
case '<sz/>': case '</sz>': case '</sz': break;
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<vertAlign/>': case '</vertAlign>': case '</vertAlign': break;
/* 18.8.18 family CT_FontFamily */
case '<family': if(y.val) font.family = parseInt(y.val,10); break;
case '<family/>': case '</family>': break;
case '<family/>': case '</family>': case '</family': break;
/* 18.8.35 scheme CT_FontScheme */
case '<scheme': if(y.val) font.scheme = y.val; break;
case '<scheme/>': case '</scheme>': break;
case '<scheme/>': case '</scheme>': case '</scheme': break;
/* 18.4.1 charset CT_IntProperty */
case '<charset':
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': case '</charset': break;
/* 18.?.? color CT_Color */
case '<color':
@ -11257,11 +11318,11 @@ function parse_fonts(t, styles, themes, opts) {
}
break;
case '<color/>': case '</color>': break;
case '<color/>': case '</color>': case '</color': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
case '</AlternateContent>': case '</AlternateContent': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -15764,7 +15825,7 @@ function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
var merges = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -16223,16 +16284,17 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles, wb) {
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}), row, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
var data_R = dense ? data[R] : [];
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}
@ -17233,12 +17295,15 @@ function write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904) {
if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) {
if(last_seen) write_record(ba, 0x000D /* BrtShortRk */, write_BrtShortRk(cell, o));
else write_record(ba, 0x0002 /* BrtCellRk */, write_BrtCellRk(cell, o));
} else if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else if(!isFinite(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
o.t = "e";
if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
}
} else {
if(last_seen) write_record(ba, 0x0010 /* BrtShortReal */, write_BrtShortReal(cell, o));
else write_record(ba, 0x0005 /* BrtCellReal */, write_BrtCellReal(cell, o));
@ -17260,23 +17325,24 @@ function write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904) {
}
function write_CELLTABLE(ba, ws, idx, opts, wb) {
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
var range = safe_decode_range(ws['!ref'] || "A1"), rr = "", cols = [];
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
write_record(ba, 0x0091 /* BrtBeginSheetData */);
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, row = dense ? ws["!data"][range.s.r] : [];
var cap = range.e.r;
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
for(var R = range.s.r; R <= cap; ++R) {
rr = encode_row(R);
if(dense) row = ws["!data"][R];
/* [ACCELLTABLE] */
/* BrtRowHdr */
write_row_header(ba, ws, range, R);
if(dense && !row) continue;
var last_seen = false;
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
var cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) { last_seen = false; continue; }
/* write cell */
last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904);
@ -19539,7 +19605,13 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
var t = "", p = "";
switch(cell.t) {
case 'z': if(!opts.sheetStubs) return ""; break;
case 'n': t = 'Number'; p = String(cell.v); break;
case 'n': {
if(!isFinite(cell.v)) {
t = 'Error'; p = BErr[isNaN(cell.v) ? 0x24 : 0x07];
} else {
t = 'Number'; p = String(cell.v);
}
} break;
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
case 'e': t = 'Error'; p = BErr[cell.v]; break;
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || table_fmt[14]; break;
@ -19581,9 +19653,12 @@ function write_ws_xlml_table(ws, opts, idx, wb) {
o.push(writextag("Column",null,k));
});
var dense = ws["!data"] != null;
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
@ -19594,7 +19669,6 @@ function write_ws_xlml_table(ws, opts, idx, wb) {
break;
}
if(skip) continue;
var addr = {r:R,c:C};
var ref = encode_col(C) + encode_row(R), cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr));
}
@ -19618,7 +19692,7 @@ function write_ws_xlml(idx, opts, wb) {
/* WorksheetOptions */
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
if(ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
if(ws && ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
return o.join("");
}
@ -19637,11 +19711,10 @@ function write_xlml(wb, opts) {
d.push(write_props_xlml(wb, opts));
d.push(write_wb_xlml(wb, opts));
d.push("");
d.push("");
d.push(write_names_xlml(wb, opts));
for(var i = 0; i < wb.SheetNames.length; ++i)
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
d[2] = write_sty_xlml(wb, opts);
d[3] = write_names_xlml(wb, opts);
return XML_HEADER + writextag("Workbook", d.join(""), {
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
@ -21822,7 +21895,7 @@ function write_ws_biff2(ba, ws, idx, opts, wb) {
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, 0x3FFF);
range.e.r = Math.min(range.e.r, 0x3FFF);
}
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
var row = [], comments = [];
@ -22231,9 +22304,9 @@ function write_ws_biff8(idx, opts, wb) {
var range = safe_decode_range(ws['!ref'] || "A1");
var MAX_ROWS = b8 ? 65536 : 16384;
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV" + MAX_ROWS);
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
range.e.r = Math.min(range.e.r, MAX_ROWS-1);
}
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
@ -22268,12 +22341,11 @@ function write_ws_biff8(idx, opts, wb) {
if(dense) row = ws["!data"][R] || [];
rr = encode_row(R);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var cell = dense ? row[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) continue;
/* write cell */
write_ws_biff8_cell(ba, cell, R, C, opts, date1904);
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
if(b8 && cell.l) ws['!links'].push([cols[C] + rr, cell.l]);
if(cell.c) comments.push([cell.c, R, C]);
}
}
@ -22417,6 +22489,9 @@ function write_biff_buf(wb, opts) {
if(range.e.c > 255) { // note: 255 is IV
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond column IV (255). Data may be lost.");
}
if(range.e.r > 65535) {
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond row 65536. Data may be lost.");
}
}
var o = opts || {};
@ -22476,6 +22551,8 @@ function html_to_sheet(str, _opts) {
if(opts.UTC === false) o.v = utc_to_local(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
o.z = opts.dateNF || table_fmt[14];
} else if(m.charCodeAt(0) == 35 /* # */ && RBErr[m] != null) {
o.t = 'e'; o.w = m; o.v = RBErr[m];
}
if(o.cellText !== false) o.w = m;
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
@ -22503,6 +22580,10 @@ function make_html_row(ws, r, R, o) {
if(RS < 0) continue;
var coord = encode_col(C) + encode_row(R);
var cell = dense ? (ws["!data"][R]||[])[C] : ws[coord];
if(cell && cell.t == 'n' && cell.v != null && !isFinite(cell.v)) {
if(isNaN(cell.v)) cell = ({t:'e', v:0x24, w:BErr[0x24]});
else cell = ({t:'e', v:0x07, w:BErr[0x07]});
}
/* TODO: html entities */
var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
sp = ({});
@ -22613,6 +22694,7 @@ function sheet_add_dom(ws, table, _opts) {
if(v != null) {
if(v.length == 0) o.t = _t || 'z';
else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(_t == "e" && BErr[+v]) o = {t:'e', v:+v, w: BErr[+v]};
else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -22621,7 +22703,7 @@ function sheet_add_dom(ws, table, _opts) {
if(opts.UTC) o.v = local_to_utc(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
o.z = opts.dateNF || table_fmt[14];
}
} else if(v.charCodeAt(0) == 35 /* # */ && RBErr[v] != null) o = ({t:'e', v: RBErr[v], w: v});
}
if(o.z === undefined && z != null) o.z = z;
/* The first link is used. Links are assumed to be fully specified.
@ -22922,7 +23004,7 @@ function parse_content_xml(d, _opts, _nfm) {
var Sheets = {}, SheetNames = [];
var ws = ({}); if(opts.dense) ws["!data"] = [];
var Rn, q;
var ctag = ({value:""});
var ctag = ({value:""}), ctag2 = ({});
var textp = "", textpidx = 0, textptag, oldtextp = "", oldtextpidx = 0;
var textR = [], oldtextR = [];
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
@ -22981,10 +23063,18 @@ function parse_content_xml(d, _opts, _nfm) {
if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
C = -1; break;
case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
if(Rn[1] !== '/') ++C;
if(opts.sheetStubs) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
if(Rn[1] !== '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1",10) || 1;
if(opts.sheetStubs) {
while(colpeat-- > 0) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
++C;
} --C;
}
else C += colpeat - 1;
}
textp = ""; textR = [];
break; /* stub */
@ -22992,7 +23082,7 @@ function parse_content_xml(d, _opts, _nfm) {
if(Rn[0].charAt(Rn[0].length-2) === '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10)||1;
q = ({t:'z', v:null});
if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -23016,6 +23106,7 @@ function parse_content_xml(d, _opts, _nfm) {
if(R < range.s.r) range.s.r = R;
if(rptR > range.e.r) range.e.r = rptR;
ctag = parsexmltag(Rn[0], false);
ctag2 = parsexmltagraw(Rn[0], true);
comments = []; comment = ({});
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null});
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -23035,10 +23126,12 @@ function parse_content_xml(d, _opts, _nfm) {
q.F = arrayf[i][1];
}
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
mC = parseInt(ctag['number-columns-spanned'],10) || 0;
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
mR = parseInt(ctag['number-rows-spanned']||"1",10) || 1;
mC = parseInt(ctag['number-columns-spanned']||"1",10) || 1;
if(mR * mC > 1) {
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
}
}
/* 19.675.2 table:number-columns-repeated */
@ -23069,6 +23162,9 @@ function parse_content_xml(d, _opts, _nfm) {
}
} else {
isstub = false;
if(ctag2['calcext:value-type'] == "error" && RBErr[textp] != null) {
q.t = 'e'; q.w = textp; q.v = RBErr[textp];
}
if(q.t === 's') {
q.v = textp || '';
if(textR.length) q.R = textR;
@ -23467,7 +23563,6 @@ function parse_fods(data, opts) {
wb.bookType = "fods";
return wb;
}
/* OpenDocument */
var write_styles_ods = /* @__PURE__ */(function() {
var master_styles = [
@ -23732,9 +23827,22 @@ var write_content_ods = /* @__PURE__ */(function() {
ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
break;
case 'n':
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
if(!isFinite(cell.v)) {
if(isNaN(cell.v)) {
textp = "#NUM!";
ct['table:formula'] = "of:=#NUM!";
} else {
textp = "#DIV/0!";
ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
}
ct['office:string-value'] = "";
ct['office:value-type'] = "string";
ct['calcext:value-type'] = "error";
} else {
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
}
break;
case 's': case 'str':
textp = cell.v == null ? "" : cell.v;
@ -25086,7 +25194,7 @@ function s5s_to_iwa_comment(s5s) {
return out;
}
function parse_TST_TableModelArchive(M, root, ws, opts) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
var pb = parse_shallow(root.data);
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
@ -25165,6 +25273,38 @@ function parse_TST_TableModelArchive(M, root, ws, opts) {
};
});
}
if (!((_k = ws["!merges"]) == null ? void 0 : _k.length) && ((_l = pb[47]) == null ? void 0 : _l[0])) {
var merge_owner = parse_shallow(pb[47][0].data);
if ((_m = merge_owner[2]) == null ? void 0 : _m[0]) {
var formula_store = parse_shallow(merge_owner[2][0].data);
if ((_n = formula_store[3]) == null ? void 0 : _n[0]) {
ws["!merges"] = mappa(formula_store[3], function(u) {
var _a2, _b2, _c2, _d2, _e2;
var formula_pair = parse_shallow(u);
var formula = parse_shallow(formula_pair[2][0].data);
var AST_node_array = parse_shallow(formula[1][0].data);
if (!((_a2 = AST_node_array[1]) == null ? void 0 : _a2[0]))
return;
var AST_node0 = parse_shallow(AST_node_array[1][0].data);
var AST_node_type = varint_to_i32(AST_node0[1][0].data);
if (AST_node_type != 67)
return;
var AST_colon_tract = parse_shallow(AST_node0[40][0].data);
if (!((_b2 = AST_colon_tract[3]) == null ? void 0 : _b2[0]) || !((_c2 = AST_colon_tract[4]) == null ? void 0 : _c2[0]))
return;
var colrange = parse_shallow(AST_colon_tract[3][0].data);
var rowrange = parse_shallow(AST_colon_tract[4][0].data);
var c = varint_to_i32(colrange[1][0].data);
var C = ((_d2 = colrange[2]) == null ? void 0 : _d2[0]) ? varint_to_i32(colrange[2][0].data) : c;
var r = varint_to_i32(rowrange[1][0].data);
var R = ((_e2 = rowrange[2]) == null ? void 0 : _e2[0]) ? varint_to_i32(rowrange[2][0].data) : r;
return { s: { r: r, c: c }, e: { r: R, c: C } };
}).filter(function(x) {
return x != null;
});
}
}
}
}
function parse_TST_TableInfoArchive(M, root, opts) {
var pb = parse_shallow(root.data);
@ -26971,6 +27111,8 @@ function readSync(data, opts) {
var o = opts||{};
if(o.codepage && typeof $cptable === "undefined") console.error("Codepage tables are not loaded. Non-ASCII characters may not give expected results");
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
/* Javet projects `byte[]` to `Int8Array` */
if(typeof Int8Array !== 'undefined' && data instanceof Int8Array) return readSync(new Uint8Array(data.buffer, data.byteOffset, data.length), 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; }
@ -27326,7 +27468,7 @@ function sheet_to_json(sheet, opts) {
}
var qreg = /"/g;
function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
function make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o) {
var isempty = true;
var row = [], txt = "", rr = encode_row(R);
var dense = sheet["!data"] != null;
@ -27339,7 +27481,7 @@ function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
isempty = false;
txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
if(txt == "ID") txt = '"ID"';
if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"';
} else if(val.f != null && !val.F) {
isempty = false;
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
@ -27366,7 +27508,7 @@ function sheet_to_csv(sheet, opts) {
var w = 0;
for(var R = r.s.r; R <= r.e.r; ++R) {
if ((rowinfo[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o);
if(row == null) { continue; }
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
}
@ -27381,7 +27523,7 @@ function sheet_to_txt(sheet, opts) {
return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet) {
function sheet_to_formulae(sheet, opts) {
var y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C;
@ -27402,6 +27544,7 @@ function sheet_to_formulae(sheet) {
if(y.indexOf(":") == -1) y = y + ":" + y;
}
if(x.f != null) val = x.f;
else if(opts && opts.values === false) continue;
else if(x.t == 'z') continue;
else if(x.t == 'n' && x.v != null) val = "" + x.v;
else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";
@ -27670,7 +27813,7 @@ function write_csv_stream(sheet, opts) {
while(R <= r.e.r) {
++R;
if ((rowinfo[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, w, o);
if(row != null) {
if(row || (o.blankrows !== false)) return stream.push((w++ ? RS : "") + row);
}
@ -27767,10 +27910,165 @@ function write_json_stream(sheet, opts) {
return stream;
}
function write_xlml_stream(wb, o) {
var stream = _Readable();
var opts = o == null ? {} : o;
var stride = +opts.stride || 10;
if(!wb.SSF) wb.SSF = dup(table_fmt);
if(wb.SSF) {
make_ssf(); SSF_load_table(wb.SSF);
// $FlowIgnore
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
opts.ssf = wb.SSF;
opts.cellXfs = [];
get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
}
/* do one pass to determine styles since they must be added before tables */
wb.SheetNames.forEach(function(n) {
var ws = wb.Sheets[n];
if(!ws || !ws["!ref"]) return;
var range = decode_range(ws["!ref"]);
var dense = ws["!data"] != null;
var ddata = dense ? ws["!data"] : [];
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
addr.r = R;
if(dense && !ddata[R]) continue;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var cell = dense ? ddata[R][C] : ws[encode_col(C) + encode_row(R)];
if(!cell) continue;
if(cell.t == "d" && cell.z == null) { cell = dup(cell); cell.z = table_fmt[14]; }
void get_cell_style(opts.cellXfs, cell, opts);
}
}
});
var sty = write_sty_xlml(wb, opts);
var stage = 0, wsidx = 0, ws = wb.Sheets[wb.SheetNames[wsidx]], range = safe_decode_range(ws), R = -1, T = false;
var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
stream._read = function() { switch(stage) {
/* header */
case 0: {
stage = 1;
stream.push(XML_HEADER);
stream.push("<Workbook" + wxt_helper({
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
'xmlns:x': XLMLNS.x,
'xmlns:ss': XLMLNS.ss,
'xmlns:dt': XLMLNS.dt,
'xmlns:html': XLMLNS.html
}) + ">");
} break;
/* preamble */
case 1: {
stage = 2;
stream.push(write_props_xlml(wb, opts));
stream.push(write_wb_xlml(wb, opts));
} break;
/* style and name tables */
case 2: {
stage = 3;
stream.push(sty);
stream.push(write_names_xlml(wb, opts));
} break;
/* worksheet preamble */
case 3: {
T = false;
if(wsidx >= wb.SheetNames.length) { stage = -1; stream.push(""); break; }
stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
ws = wb.Sheets[wb.SheetNames[wsidx]];
if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
var names = write_ws_xlml_names(ws, opts, wsidx, wb);
if(names.length) stream.push("<Names>" + names + "</Names>");
if(!ws["!ref"]) return (stage = 5);
range = safe_decode_range(ws["!ref"]);
R = range.s.r;
stage = 4;
} break;
/* worksheet intramble */
case 4: {
if(R < 0 || R > range.e.r) { if(T) stream.push("</Table>"); return void (stage = 5); }
if(R <= range.s.r) {
if(ws['!cols']) ws['!cols'].forEach(function(n, i) {
process_col(n);
var w = !!n.width;
var p = col_obj_w(i, n);
var k = {"ss:Index":i+1};
if(w) k['ss:Width'] = width2px(p.width);
if(n.hidden) k['ss:Hidden']="1";
if(!T) { T = true; stream.push("<Table>"); }
stream.push(writextag("Column",null,k));
});
dense = ws["!data"] != null;
if(dense) darr = ws["!data"];
addr.r = addr.c = 0;
}
/* process `stride` rows per invocation */
for(var cnt = 0; R <= range.e.r && cnt < stride; ++R, ++cnt) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
if(!(dense && !darr[R])) for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
if(marr[mi].s.r > R) continue;
if(marr[mi].e.c < C) continue;
if(marr[mi].e.r < R) continue;
if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
break;
}
if(skip) continue;
var ref = encode_col(C) + encode_row(R), cell = dense ? darr[R][C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, wsidx, wb, addr));
}
row.push("</Row>");
if(!T) { T = true; stream.push("<Table>"); }
stream.push(row.join(""));
}
} break;
/* worksheet postamble */
case 5: {
stream.push(write_ws_xlml_wsopts(ws, opts, wsidx, wb));
if(ws && ws["!autofilter"]) stream.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
stream.push("</Worksheet>");
wsidx++; R = -1;
return void (stage = 3);
}
/* footer */
case -1: {
stage = -2;
stream.push("</Workbook>");
} break;
/* exeunt */
case -2: stream.push(null); break;
}};
return stream;
}
var __stream = {
to_json: write_json_stream,
to_html: write_html_stream,
to_csv: write_csv_stream,
to_xlml: write_xlml_stream,
set_readable: set_readable
};
if(typeof parse_xlscfb !== "undefined") XLSX.parse_xlscfb = parse_xlscfb;

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false */
var XLSX = {};
function make_xlsx_lib(XLSX){
XLSX.version = '0.20.2';
XLSX.version = '0.20.3';
var current_codepage = 1200, current_ansi = 1252;
/*:: declare var cptable:any; */
/*global cptable:true, window */
@ -559,6 +559,7 @@ function SSF_large_exp(v/*:number*/)/*:string*/ {
}
function SSF_general_num(v/*:number*/)/*:string*/ {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -1256,6 +1257,8 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -1292,6 +1295,8 @@ function SSF_format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt/*:string*/, idx/*:?number*/)/*:number*/ {
@ -1451,7 +1456,9 @@ type CFBFiles = {[n:string]:CFBEntry};
var CRC32 = /*#__PURE__*/(function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*::
type CRC32TableType = Array<number> | Int32Array;
*/
/*global Int32Array */
function signed_crc_table()/*:any*/ {
var c = 0, table/*:Array<number>*/ = new Array(256);
@ -1489,7 +1496,7 @@ var TT = slice_by_16_tables(T0);
var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4];
var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9];
var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
function crc32_bstr(bstr/*:string*/, seed/*:number*/)/*:number*/ {
function crc32_bstr(bstr/*:string*/, seed/*:?number*/)/*:number*/ {
var C = seed/*:: ? 0 : 0 */ ^ -1;
for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF];
return ~C;
@ -2855,8 +2862,8 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -2867,7 +2874,7 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -2902,9 +2909,10 @@ function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
@ -3803,6 +3811,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);
@ -3873,6 +3884,26 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*
}
return z;
}
function parsexmltagraw(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*/)/*:any*/ {
var z = ({}/*:any*/);
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x/*:string*/)/*:string*/ { return x.replace(nsregex2, "<$1"); }
var encodings = {
@ -4385,7 +4416,8 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
/* control buffer usage for fixed-length buffers */
function buf_array()/*:BufArray*/ {
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 256 : 2048;
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 16384 : 2048;
var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function");
var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ {
var o/*:Block*/ = (new_buf(sz)/*:any*/);
prep_blob(o, 0);
@ -4414,10 +4446,15 @@ function buf_array()/*:BufArray*/ {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz);
};
return ({ next:next, push:push, end:end, _bufs:bufs }/*:any*/);
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 }/*:any*/);
}
function write_record(ba/*:BufArray*/, type/*:number*/, payload, length/*:?number*/) {
@ -4605,7 +4642,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
var ws/*:Worksheet*/ = _ws || (dense ? ({"!data": []}) : ({}/*:any*/));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -4630,31 +4667,35 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data[R][C] }/*:any*/);
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data_R[C], t:"" }/*:any*/);
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
else if(!o.sheetStubs) continue;
else cell.t = 'z';
}
else if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'number') {
if(isFinite(cell.v)) cell.t = 'n';
else if(isNaN(cell.v)) { cell.t = 'e'; cell.v = 0x0F; /* #VALUE! */ }
else { cell.t = 'e'; cell.v = 0x07; /*# DIV/0 */ }
}
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.z = o.dateNF || table_fmt[14];
@ -4668,7 +4709,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr/*:any*/;
var cell_ref = encode_col(__C) + (__R + 1)/*:any*/;
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}
@ -4678,7 +4719,6 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
return ws;
}
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
/* [MS-OLEPS] 2.2 PropertyType */
// Note: some tree shakers cannot handle VT_VECTOR | $CONST, hence extra vars
//var VT_EMPTY = 0x0000;
@ -6329,7 +6369,7 @@ var SYLK = /*#__PURE__*/(function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -6558,7 +6598,7 @@ var ETH = /*#__PURE__*/(function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -6601,11 +6641,7 @@ var ETH = /*#__PURE__*/(function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -6615,6 +6651,19 @@ var ETH = /*#__PURE__*/(function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -6646,6 +6695,7 @@ var PRN = /*#__PURE__*/(function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -6763,6 +6813,8 @@ var PRN = /*#__PURE__*/(function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;
@ -7383,10 +7435,12 @@ function parse_fonts(t, styles, themes, opts) {
/* 18.8.2 b CT_BooleanProperty */
case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
case '<b/>': font.bold = 1; break;
case '</b>': case '</b': break;
/* 18.8.26 i CT_BooleanProperty */
case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
case '<i/>': font.italic = 1; break;
case '</i>': case '</i': break;
/* 18.4.13 u CT_UnderlineProperty */
case '<u':
@ -7398,48 +7452,55 @@ function parse_fonts(t, styles, themes, opts) {
case "doubleAccounting": font.underline = 0x22; break;
} break;
case '<u/>': font.underline = 1; break;
case '</u>': case '</u': break;
/* 18.4.10 strike CT_BooleanProperty */
case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
case '<strike/>': font.strike = 1; break;
case '</strike>': case '</strike': break;
/* 18.4.2 outline CT_BooleanProperty */
case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
case '<outline/>': font.outline = 1; break;
case '</outline>': case '</outline': break;
/* 18.8.36 shadow CT_BooleanProperty */
case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
case '<shadow/>': font.shadow = 1; break;
case '</shadow>': case '</shadow': break;
/* 18.8.12 condense CT_BooleanProperty */
case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
case '<condense/>': font.condense = 1; break;
case '</condense>': case '</condense': break;
/* 18.8.17 extend CT_BooleanProperty */
case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
case '<extend/>': font.extend = 1; break;
case '</extend>': case '</extend': break;
/* 18.4.11 sz CT_FontSize */
case '<sz': if(y.val) font.sz = +y.val; break;
case '<sz/>': case '</sz>': break;
case '<sz/>': case '</sz>': case '</sz': break;
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<vertAlign/>': case '</vertAlign>': case '</vertAlign': break;
/* 18.8.18 family CT_FontFamily */
case '<family': if(y.val) font.family = parseInt(y.val,10); break;
case '<family/>': case '</family>': break;
case '<family/>': case '</family>': case '</family': break;
/* 18.8.35 scheme CT_FontScheme */
case '<scheme': if(y.val) font.scheme = y.val; break;
case '<scheme/>': case '</scheme>': break;
case '<scheme/>': case '</scheme>': case '</scheme': break;
/* 18.4.1 charset CT_IntProperty */
case '<charset':
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': case '</charset': break;
/* 18.?.? color CT_Color */
case '<color':
@ -7462,11 +7523,11 @@ function parse_fonts(t, styles, themes, opts) {
}
break;
case '<color/>': case '</color>': break;
case '<color/>': case '</color>': case '</color': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
case '</AlternateContent>': case '</AlternateContent': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -8710,7 +8771,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
var merges/*:Array<Range>*/ = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -9169,16 +9230,17 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*//*::, rels*/)/*:string*/ {
var o/*:Array<string>*/ = [], r/*:Array<string>*/ = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols/*:Array<string>*/ = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
var data_R = dense ? data[R] : [];
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}
@ -9916,6 +9978,8 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
if(opts.UTC === false) o.v = utc_to_local(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
} else if(m.charCodeAt(0) == 35 /* # */ && RBErr[m] != null) {
o.t = 'e'; o.w = m; o.v = RBErr[m];
}
if(o.cellText !== false) o.w = m;
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
@ -9943,6 +10007,10 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
if(RS < 0) continue;
var coord = encode_col(C) + encode_row(R);
var cell = dense ? (ws["!data"][R]||[])[C] : ws[coord];
if(cell && cell.t == 'n' && cell.v != null && !isFinite(cell.v)) {
if(isNaN(cell.v)) cell = ({t:'e', v:0x24, w:BErr[0x24]});
else cell = ({t:'e', v:0x07, w:BErr[0x07]});
}
/* TODO: html entities */
var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
sp = ({}/*:any*/);
@ -10053,6 +10121,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(v != null) {
if(v.length == 0) o.t = _t || 'z';
else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(_t == "e" && BErr[+v]) o = {t:'e', v:+v, w: BErr[+v]};
else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -10061,7 +10130,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(opts.UTC) o.v = local_to_utc(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
}
} else if(v.charCodeAt(0) == 35 /* # */ && RBErr[v] != null) o = ({t:'e', v: RBErr[v], w: v});
}
if(o.z === undefined && z != null) o.z = z;
/* The first link is used. Links are assumed to be fully specified.
@ -10362,7 +10431,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
var Sheets = {}, SheetNames/*:Array<string>*/ = [];
var ws = ({}/*:any*/); if(opts.dense) ws["!data"] = [];
var Rn, q/*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
var ctag = ({value:""}/*:any*/);
var ctag = ({value:""}/*:any*/), ctag2 = ({}/*:any*/);
var textp = "", textpidx = 0, textptag/*:: = {}*/, oldtextp = "", oldtextpidx = 0;
var textR = [], oldtextR = [];
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
@ -10421,10 +10490,18 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
C = -1; break;
case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
if(Rn[1] !== '/') ++C;
if(opts.sheetStubs) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
if(Rn[1] !== '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1",10) || 1;
if(opts.sheetStubs) {
while(colpeat-- > 0) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
++C;
} --C;
}
else C += colpeat - 1;
}
textp = ""; textR = [];
break; /* stub */
@ -10432,7 +10509,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(Rn[0].charAt(Rn[0].length-2) === '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10)||1;
q = ({t:'z', v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -10456,6 +10533,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(R < range.s.r) range.s.r = R;
if(rptR > range.e.r) range.e.r = rptR;
ctag = parsexmltag(Rn[0], false);
ctag2 = parsexmltagraw(Rn[0], true);
comments = []; comment = ({}/*:any*/);
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -10475,10 +10553,12 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
q.F = arrayf[i][1];
}
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
mC = parseInt(ctag['number-columns-spanned'],10) || 0;
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
mR = parseInt(ctag['number-rows-spanned']||"1",10) || 1;
mC = parseInt(ctag['number-columns-spanned']||"1",10) || 1;
if(mR * mC > 1) {
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
}
}
/* 19.675.2 table:number-columns-repeated */
@ -10509,6 +10589,9 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
}
} else {
isstub = false;
if(ctag2['calcext:value-type'] == "error" && RBErr[textp] != null) {
q.t = 'e'; q.w = textp; q.v = RBErr[textp];
}
if(q.t === 's') {
q.v = textp || '';
if(textR.length) q.R = textR;
@ -10907,7 +10990,6 @@ function parse_fods(data/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
wb.bookType = "fods";
return wb;
}
/* OpenDocument */
var write_styles_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function() {
var master_styles = [
@ -11172,9 +11254,22 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
break;
case 'n':
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
if(!isFinite(cell.v)) {
if(isNaN(cell.v)) {
textp = "#NUM!";
ct['table:formula'] = "of:=#NUM!";
} else {
textp = "#DIV/0!";
ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
}
ct['office:string-value'] = "";
ct['office:value-type'] = "string";
ct['calcext:value-type'] = "error";
} else {
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
}
break;
case 's': case 'str':
textp = cell.v == null ? "" : cell.v;
@ -12151,6 +12246,8 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var o = opts||{};
if(o.codepage && typeof $cptable === "undefined") console.error("Codepage tables are not loaded. Non-ASCII characters may not give expected results");
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
/* Javet projects `byte[]` to `Int8Array` */
if(typeof Int8Array !== 'undefined' && data instanceof Int8Array) return readSync(new Uint8Array(data.buffer, data.byteOffset, data.length), 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; }
@ -12513,7 +12610,7 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) {
}
var qreg = /"/g;
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, w/*:number*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
var isempty = true;
var row/*:Array<string>*/ = [], txt = "", rr = encode_row(R);
var dense = sheet["!data"] != null;
@ -12526,7 +12623,7 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr
isempty = false;
txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
if(txt == "ID") txt = '"ID"';
if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"';
} else if(val.f != null && !val.F) {
isempty = false;
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
@ -12553,7 +12650,7 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
var w = 0;
for(var R = r.s.r; R <= r.e.r; ++R) {
if ((rowinfo[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o);
if(row == null) { continue; }
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
}
@ -12568,7 +12665,7 @@ function sheet_to_txt(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
function sheet_to_formulae(sheet/*:Worksheet*/, opts/*:?Sheet2FormulaOpts*/)/*:Array<string>*/ {
var y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols/*:Array<string>*/ = [], C;
@ -12589,6 +12686,7 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
if(y.indexOf(":") == -1) y = y + ":" + y;
}
if(x.f != null) val = x.f;
else if(opts && opts.values === false) continue;
else if(x.t == 'z') continue;
else if(x.t == 'n' && x.v != null) val = "" + x.v;
else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false */
var XLSX = {};
function make_xlsx_lib(XLSX){
XLSX.version = '0.20.2';
XLSX.version = '0.20.3';
var current_codepage = 1200, current_ansi = 1252;
/*global cptable:true, window */
var $cptable;
@ -539,6 +539,7 @@ function SSF_large_exp(v) {
}
function SSF_general_num(v) {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -1232,6 +1233,8 @@ function choose_fmt(f, v) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -1268,6 +1271,8 @@ function SSF_format(fmt,v,o) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt, idx) {
@ -1391,7 +1396,6 @@ function SSF__load(fmt, idx) {
var CRC32 = (function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*global Int32Array */
function signed_crc_table() {
var c = 0, table = new Array(256);
@ -2790,8 +2794,8 @@ function parse_local_file(blob, csz, usz, o, EF) {
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -2802,7 +2806,7 @@ function parse_local_file(blob, csz, usz, o, EF) {
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -2837,9 +2841,10 @@ function write_zip(cfb, options) {
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
@ -3732,6 +3737,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);
@ -3802,6 +3810,26 @@ function parsexmltag(tag, skip_root, skip_LC) {
}
return z;
}
function parsexmltagraw(tag, skip_root, skip_LC) {
var z = ({});
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x) { return x.replace(nsregex2, "<$1"); }
var encodings = {
@ -4308,7 +4336,8 @@ function recordhopper(data, cb, opts) {
/* control buffer usage for fixed-length buffers */
function buf_array() {
var bufs = [], blksz = has_buf ? 256 : 2048;
var bufs = [], blksz = has_buf ? 16384 : 2048;
var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function");
var newblk = function ba_newblk(sz) {
var o = (new_buf(sz));
prep_blob(o, 0);
@ -4337,10 +4366,15 @@ function buf_array() {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz);
};
return ({ next:next, push:push, end:end, _bufs:bufs });
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 });
}
function write_record(ba, type, payload, length) {
@ -4523,7 +4557,7 @@ function sheet_add_aoa(_ws, data, opts) {
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws = _ws || ({});
var ws = _ws || (dense ? ({"!data": []}) : ({}));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -4548,31 +4582,35 @@ function sheet_add_aoa(_ws, data, opts) {
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell = ({v: data[R][C] });
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell = ({v: data_R[C], t:"" });
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
else if(!o.sheetStubs) continue;
else cell.t = 'z';
}
else if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'number') {
if(isFinite(cell.v)) cell.t = 'n';
else if(isNaN(cell.v)) { cell.t = 'e'; cell.v = 0x0F; /* #VALUE! */ }
else { cell.t = 'e'; cell.v = 0x07; }
}
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.z = o.dateNF || table_fmt[14];
@ -4586,7 +4624,7 @@ function sheet_add_aoa(_ws, data, opts) {
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr;
var cell_ref = encode_col(__C) + (__R + 1);
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}
@ -4596,7 +4634,6 @@ function sheet_add_aoa(_ws, data, opts) {
return ws;
}
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
/* [MS-OLEPS] 2.2 PropertyType */
// Note: some tree shakers cannot handle VT_VECTOR | $CONST, hence extra vars
//var VT_EMPTY = 0x0000;
@ -6246,7 +6283,7 @@ var SYLK = (function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -6475,7 +6512,7 @@ var ETH = (function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -6518,11 +6555,7 @@ var ETH = (function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -6532,6 +6565,19 @@ var ETH = (function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -6563,6 +6609,7 @@ var PRN = (function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -6680,6 +6727,8 @@ var PRN = (function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;
@ -7300,10 +7349,12 @@ function parse_fonts(t, styles, themes, opts) {
/* 18.8.2 b CT_BooleanProperty */
case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
case '<b/>': font.bold = 1; break;
case '</b>': case '</b': break;
/* 18.8.26 i CT_BooleanProperty */
case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
case '<i/>': font.italic = 1; break;
case '</i>': case '</i': break;
/* 18.4.13 u CT_UnderlineProperty */
case '<u':
@ -7315,48 +7366,55 @@ function parse_fonts(t, styles, themes, opts) {
case "doubleAccounting": font.underline = 0x22; break;
} break;
case '<u/>': font.underline = 1; break;
case '</u>': case '</u': break;
/* 18.4.10 strike CT_BooleanProperty */
case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
case '<strike/>': font.strike = 1; break;
case '</strike>': case '</strike': break;
/* 18.4.2 outline CT_BooleanProperty */
case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
case '<outline/>': font.outline = 1; break;
case '</outline>': case '</outline': break;
/* 18.8.36 shadow CT_BooleanProperty */
case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
case '<shadow/>': font.shadow = 1; break;
case '</shadow>': case '</shadow': break;
/* 18.8.12 condense CT_BooleanProperty */
case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
case '<condense/>': font.condense = 1; break;
case '</condense>': case '</condense': break;
/* 18.8.17 extend CT_BooleanProperty */
case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
case '<extend/>': font.extend = 1; break;
case '</extend>': case '</extend': break;
/* 18.4.11 sz CT_FontSize */
case '<sz': if(y.val) font.sz = +y.val; break;
case '<sz/>': case '</sz>': break;
case '<sz/>': case '</sz>': case '</sz': break;
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<vertAlign/>': case '</vertAlign>': case '</vertAlign': break;
/* 18.8.18 family CT_FontFamily */
case '<family': if(y.val) font.family = parseInt(y.val,10); break;
case '<family/>': case '</family>': break;
case '<family/>': case '</family>': case '</family': break;
/* 18.8.35 scheme CT_FontScheme */
case '<scheme': if(y.val) font.scheme = y.val; break;
case '<scheme/>': case '</scheme>': break;
case '<scheme/>': case '</scheme>': case '</scheme': break;
/* 18.4.1 charset CT_IntProperty */
case '<charset':
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': case '</charset': break;
/* 18.?.? color CT_Color */
case '<color':
@ -7379,11 +7437,11 @@ function parse_fonts(t, styles, themes, opts) {
}
break;
case '<color/>': case '</color>': break;
case '<color/>': case '</color>': case '</color': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
case '</AlternateContent>': case '</AlternateContent': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -8627,7 +8685,7 @@ function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
var merges = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -9086,16 +9144,17 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles, wb) {
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}), row, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
var data_R = dense ? data[R] : [];
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}
@ -9831,6 +9890,8 @@ function html_to_sheet(str, _opts) {
if(opts.UTC === false) o.v = utc_to_local(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
o.z = opts.dateNF || table_fmt[14];
} else if(m.charCodeAt(0) == 35 /* # */ && RBErr[m] != null) {
o.t = 'e'; o.w = m; o.v = RBErr[m];
}
if(o.cellText !== false) o.w = m;
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
@ -9858,6 +9919,10 @@ function make_html_row(ws, r, R, o) {
if(RS < 0) continue;
var coord = encode_col(C) + encode_row(R);
var cell = dense ? (ws["!data"][R]||[])[C] : ws[coord];
if(cell && cell.t == 'n' && cell.v != null && !isFinite(cell.v)) {
if(isNaN(cell.v)) cell = ({t:'e', v:0x24, w:BErr[0x24]});
else cell = ({t:'e', v:0x07, w:BErr[0x07]});
}
/* TODO: html entities */
var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
sp = ({});
@ -9968,6 +10033,7 @@ function sheet_add_dom(ws, table, _opts) {
if(v != null) {
if(v.length == 0) o.t = _t || 'z';
else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(_t == "e" && BErr[+v]) o = {t:'e', v:+v, w: BErr[+v]};
else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -9976,7 +10042,7 @@ function sheet_add_dom(ws, table, _opts) {
if(opts.UTC) o.v = local_to_utc(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
o.z = opts.dateNF || table_fmt[14];
}
} else if(v.charCodeAt(0) == 35 /* # */ && RBErr[v] != null) o = ({t:'e', v: RBErr[v], w: v});
}
if(o.z === undefined && z != null) o.z = z;
/* The first link is used. Links are assumed to be fully specified.
@ -10277,7 +10343,7 @@ function parse_content_xml(d, _opts, _nfm) {
var Sheets = {}, SheetNames = [];
var ws = ({}); if(opts.dense) ws["!data"] = [];
var Rn, q;
var ctag = ({value:""});
var ctag = ({value:""}), ctag2 = ({});
var textp = "", textpidx = 0, textptag, oldtextp = "", oldtextpidx = 0;
var textR = [], oldtextR = [];
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
@ -10336,10 +10402,18 @@ function parse_content_xml(d, _opts, _nfm) {
if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
C = -1; break;
case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
if(Rn[1] !== '/') ++C;
if(opts.sheetStubs) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
if(Rn[1] !== '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1",10) || 1;
if(opts.sheetStubs) {
while(colpeat-- > 0) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
++C;
} --C;
}
else C += colpeat - 1;
}
textp = ""; textR = [];
break; /* stub */
@ -10347,7 +10421,7 @@ function parse_content_xml(d, _opts, _nfm) {
if(Rn[0].charAt(Rn[0].length-2) === '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10)||1;
q = ({t:'z', v:null});
if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -10371,6 +10445,7 @@ function parse_content_xml(d, _opts, _nfm) {
if(R < range.s.r) range.s.r = R;
if(rptR > range.e.r) range.e.r = rptR;
ctag = parsexmltag(Rn[0], false);
ctag2 = parsexmltagraw(Rn[0], true);
comments = []; comment = ({});
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null});
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -10390,10 +10465,12 @@ function parse_content_xml(d, _opts, _nfm) {
q.F = arrayf[i][1];
}
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
mC = parseInt(ctag['number-columns-spanned'],10) || 0;
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
mR = parseInt(ctag['number-rows-spanned']||"1",10) || 1;
mC = parseInt(ctag['number-columns-spanned']||"1",10) || 1;
if(mR * mC > 1) {
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
}
}
/* 19.675.2 table:number-columns-repeated */
@ -10424,6 +10501,9 @@ function parse_content_xml(d, _opts, _nfm) {
}
} else {
isstub = false;
if(ctag2['calcext:value-type'] == "error" && RBErr[textp] != null) {
q.t = 'e'; q.w = textp; q.v = RBErr[textp];
}
if(q.t === 's') {
q.v = textp || '';
if(textR.length) q.R = textR;
@ -10822,7 +10902,6 @@ function parse_fods(data, opts) {
wb.bookType = "fods";
return wb;
}
/* OpenDocument */
var write_styles_ods = /* @__PURE__ */(function() {
var master_styles = [
@ -11087,9 +11166,22 @@ var write_content_ods = /* @__PURE__ */(function() {
ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
break;
case 'n':
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
if(!isFinite(cell.v)) {
if(isNaN(cell.v)) {
textp = "#NUM!";
ct['table:formula'] = "of:=#NUM!";
} else {
textp = "#DIV/0!";
ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
}
ct['office:string-value'] = "";
ct['office:value-type'] = "string";
ct['calcext:value-type'] = "error";
} else {
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
}
break;
case 's': case 'str':
textp = cell.v == null ? "" : cell.v;
@ -12062,6 +12154,8 @@ function readSync(data, opts) {
var o = opts||{};
if(o.codepage && typeof $cptable === "undefined") console.error("Codepage tables are not loaded. Non-ASCII characters may not give expected results");
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
/* Javet projects `byte[]` to `Int8Array` */
if(typeof Int8Array !== 'undefined' && data instanceof Int8Array) return readSync(new Uint8Array(data.buffer, data.byteOffset, data.length), 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; }
@ -12417,7 +12511,7 @@ function sheet_to_json(sheet, opts) {
}
var qreg = /"/g;
function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
function make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o) {
var isempty = true;
var row = [], txt = "", rr = encode_row(R);
var dense = sheet["!data"] != null;
@ -12430,7 +12524,7 @@ function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
isempty = false;
txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
if(txt == "ID") txt = '"ID"';
if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"';
} else if(val.f != null && !val.F) {
isempty = false;
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
@ -12457,7 +12551,7 @@ function sheet_to_csv(sheet, opts) {
var w = 0;
for(var R = r.s.r; R <= r.e.r; ++R) {
if ((rowinfo[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o);
if(row == null) { continue; }
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
}
@ -12472,7 +12566,7 @@ function sheet_to_txt(sheet, opts) {
return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet) {
function sheet_to_formulae(sheet, opts) {
var y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C;
@ -12493,6 +12587,7 @@ function sheet_to_formulae(sheet) {
if(y.indexOf(":") == -1) y = y + ":" + y;
}
if(x.f != null) val = x.f;
else if(opts && opts.values === false) continue;
else if(x.t == 'z') continue;
else if(x.t == 'n' && x.v != null) val = "" + x.v;
else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";

463
xlsx.mjs generated

@ -3,7 +3,7 @@
/*exported XLSX */
/*global process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
var XLSX = {};
XLSX.version = '0.20.2';
XLSX.version = '0.20.3';
var current_codepage = 1200, current_ansi = 1252;
/*:: declare var cptable:any; */
/*global cptable:true, window */
@ -558,6 +558,7 @@ function SSF_large_exp(v/*:number*/)/*:string*/ {
}
function SSF_general_num(v/*:number*/)/*:string*/ {
if(!isFinite(v)) return isNaN(v) ? "#NUM!" : "#DIV/0!";
var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
@ -1255,6 +1256,8 @@ function choose_fmt(f/*:string*/, v/*:any*/) {
if(l<4 && lat>-1) --l;
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
/* NOTE: most spreadsheet software do not support NaN or infinities */
if(typeof v === "number" && !isFinite(v)) v = 0;
switch(fmt.length) {
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
@ -1291,6 +1294,8 @@ function SSF_format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
if(SSF_isgeneral(f[1])) return SSF_general(v, o);
if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
else if(v === "" || v == null) return "";
else if(isNaN(v) && f[1].indexOf("0") > -1) return "#NUM!";
else if(!isFinite(v) && f[1].indexOf("0") > -1) return "#DIV/0!";
return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt/*:string*/, idx/*:?number*/)/*:number*/ {
@ -1450,7 +1455,9 @@ type CFBFiles = {[n:string]:CFBEntry};
var CRC32 = /*#__PURE__*/(function() {
var CRC32 = {};
CRC32.version = '1.2.0';
/* see perf/crc32table.js */
/*::
type CRC32TableType = Array<number> | Int32Array;
*/
/*global Int32Array */
function signed_crc_table()/*:any*/ {
var c = 0, table/*:Array<number>*/ = new Array(256);
@ -1488,7 +1495,7 @@ var TT = slice_by_16_tables(T0);
var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4];
var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9];
var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
function crc32_bstr(bstr/*:string*/, seed/*:number*/)/*:number*/ {
function crc32_bstr(bstr/*:string*/, seed/*:?number*/)/*:number*/ {
var C = seed/*:: ? 0 : 0 */ ^ -1;
for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF];
return ~C;
@ -2854,8 +2861,8 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
if((ef[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if(EF) {
if((EF[0x5455]||{}).mt) date = EF[0x5455].mt;
if((EF[0x0001]||{}).usz) _usz = ef[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = ef[0x0001].csz;
if((EF[0x0001]||{}).usz) _usz = EF[0x0001].usz;
if((EF[0x0001]||{}).csz) _csz = EF[0x0001].csz;
}
}
blob.l += efsz;
@ -2866,7 +2873,7 @@ function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:C
var data = blob.slice(blob.l, blob.l + _csz);
switch(meth) {
case 8: data = _inflateRawSync(blob, _usz); break;
case 0: break; // TODO: scan for magic number
case 0: blob.l += _csz; break; // TODO: scan for magic number
default: throw new Error("Unsupported ZIP Compression method " + meth);
}
@ -2901,9 +2908,10 @@ function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/
for(i = 1; i < cfb.FullPaths.length; ++i) {
fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
if(!fi.size || !fi.content || (Array.isArray(fi.content) && fi.content.length == 0) || fp == "\u0001Sh33tJ5") continue;
var start = start_cd;
/* TODO: CP437 filename */
var namebuf = new_buf(fp.length);
for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
@ -3802,6 +3810,9 @@ function zipentries(zip) {
function zip_add_file(zip, path, content) {
if(zip.FullPaths) {
if(Array.isArray(content) && typeof content[0] == "string") {
content = content.join("");
}
if(typeof content == "string") {
var res;
if(has_buf) res = Buffer_from(content);
@ -3872,6 +3883,26 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*
}
return z;
}
function parsexmltagraw(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*/)/*:any*/ {
var z = ({}/*:any*/);
var eq = 0, c = 0;
for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
if(!skip_root) z[0] = tag.slice(0, eq);
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
v = cc.slice(c+1+quot, cc.length-quot);
if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
z[q] = v;
if(!skip_LC) z[q.toLowerCase()] = v;
}
return z;
}
function strip_ns(x/*:string*/)/*:string*/ { return x.replace(nsregex2, "<$1"); }
var encodings = {
@ -4384,7 +4415,8 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
/* control buffer usage for fixed-length buffers */
function buf_array()/*:BufArray*/ {
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 256 : 2048;
var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 16384 : 2048;
var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function");
var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ {
var o/*:Block*/ = (new_buf(sz)/*:any*/);
prep_blob(o, 0);
@ -4413,10 +4445,15 @@ function buf_array()/*:BufArray*/ {
endbuf();
return bconcat(bufs);
};
var end2 = function() {
endbuf(); return bufs;
};
var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
var push = function ba_push(buf) {
endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz);
};
return ({ next:next, push:push, end:end, _bufs:bufs }/*:any*/);
return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 }/*:any*/);
}
function write_record(ba/*:BufArray*/, type/*:number*/, payload, length/*:?number*/) {
@ -4604,7 +4641,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
var o = opts || {};
var dense = _ws ? (_ws["!data"] != null) : o.dense;
if(DENSE != null && dense == null) dense = DENSE;
var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
var ws/*:Worksheet*/ = _ws || (dense ? ({"!data": []}) : ({}/*:any*/));
if(dense && !ws["!data"]) ws["!data"] = [];
var _R = 0, _C = 0;
if(ws && o.origin != null) {
@ -4629,31 +4666,35 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
var __R = _R + R;
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
}
for(var C = 0; C != data[R].length; ++C) {
if(typeof data[R][C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data[R][C] }/*:any*/);
var data_R = data[R];
for(var C = 0; C != data_R.length; ++C) {
if(typeof data_R[C] === 'undefined') continue;
var cell/*:Cell*/ = ({v: data_R[C], t:"" }/*:any*/);
var __C = _C + C;
if(range.s.r > __R) range.s.r = __R;
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
if(data_R[C] && typeof data_R[C] === 'object' && !Array.isArray(data_R[C]) && !(data_R[C] instanceof Date)) cell = data_R[C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
if(Array.isArray(cell.v)) { cell.f = data_R[C][1]; cell.v = cell.v[0]; }
if(cell.v === null) {
if(cell.f) cell.t = 'n';
else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
else if(!o.sheetStubs) continue;
else cell.t = 'z';
}
else if(typeof cell.v === 'number') cell.t = 'n';
else if(typeof cell.v === 'number') {
if(isFinite(cell.v)) cell.t = 'n';
else if(isNaN(cell.v)) { cell.t = 'e'; cell.v = 0x0F; /* #VALUE! */ }
else { cell.t = 'e'; cell.v = 0x07; /*# DIV/0 */ }
}
else if(typeof cell.v === 'boolean') cell.t = 'b';
else if(cell.v instanceof Date) {
cell.z = o.dateNF || table_fmt[14];
@ -4667,7 +4708,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
if(row[__C] && row[__C].z) cell.z = row[__C].z;
row[__C] = cell;
} else {
var cell_ref = encode_col(__C) + __Rstr/*:any*/;
var cell_ref = encode_col(__C) + (__R + 1)/*:any*/;
if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
ws[cell_ref] = cell;
}
@ -4677,7 +4718,6 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
return ws;
}
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
function parse_Int32LE(data) {
return data.read_shift(4, 'i');
}
@ -6261,8 +6301,8 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
case 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,'');
case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob);
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
@ -8557,7 +8597,7 @@ var SYLK = /*#__PURE__*/(function() {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
case 'n':
o += (cell.v||0);
o += isFinite(cell.v) ? (cell.v||0) : BErr[isNaN(cell.v) ? 0x24 : 0x07];
if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
@ -8786,7 +8826,7 @@ var ETH = /*#__PURE__*/(function() {
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
default: arr[R][C] = record[record.length-1].charAt(0) == "#" ? ({t: "e", v: RBErr[record[record.length-1]] }) : +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
@ -8829,11 +8869,7 @@ var ETH = /*#__PURE__*/(function() {
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 's': oo.push(encode(cell.v)); break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
@ -8843,6 +8879,19 @@ var ETH = /*#__PURE__*/(function() {
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
break;
case 'n':
if(isFinite(cell.v)) {
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
} else {
oo[2] = 'vt' + (cell.f ? 'f' : 'c');
oo[3] = "e" + BErr[isNaN(cell.v) ? 0x24 : 0x07];
oo[4] = "0";
oo[5] = cell.f || oo[3].slice(1);
oo[6] = "e";
oo[7] = oo[3].slice(1);
}
break;
case 'e': continue;
}
o.push(oo.join(":"));
@ -8874,6 +8923,7 @@ var PRN = /*#__PURE__*/(function() {
else if(data === 'FALSE') arr[R][C] = false;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else if(data.charCodeAt(0) == 35 /* # */ && RBErr[data] != null) arr[R][C] = ({ t: 'e', v: RBErr[data], w: data });
else arr[R][C] = data;
}
@ -8991,6 +9041,8 @@ var PRN = /*#__PURE__*/(function() {
if(o.cellDates) { cell.t = 'd'; cell.v = v; }
else { cell.t = 'n'; cell.v = datenum(v); }
if(!o.cellNF) delete cell.z;
} else if(s.charCodeAt(0) == 35 /* # */ && RBErr[s] != null) {
cell.t = 'e'; cell.w = s; cell.v = RBErr[s];
} else {
cell.t = 's';
cell.v = s;
@ -9690,7 +9742,6 @@ var WK_ = /*#__PURE__*/(function() {
else console.error("WK1 bad formula parse |" + out.join("|") + "|");
}
function parse_cell_3(blob/*::, length*/) {
var o = [{c:0,r:0}, {t:'n',v:0}, 0];
o[0].r = blob.read_shift(2); o[3] = blob[blob.l++]; o[0].c = blob[blob.l++];
@ -10926,6 +10977,10 @@ function rtf_to_sheet_str(str, opts) {
if (o.cellText !== false)
cell.w = cell.v;
cell.v = fuzzynum(cell.v);
} else if (RBErr[cell.v] != null) {
cell.t = "e";
cell.w = cell.v;
cell.v = RBErr[cell.v];
}
if (dense)
row[C] = cell;
@ -11261,10 +11316,12 @@ function parse_fonts(t, styles, themes, opts) {
/* 18.8.2 b CT_BooleanProperty */
case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
case '<b/>': font.bold = 1; break;
case '</b>': case '</b': break;
/* 18.8.26 i CT_BooleanProperty */
case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
case '<i/>': font.italic = 1; break;
case '</i>': case '</i': break;
/* 18.4.13 u CT_UnderlineProperty */
case '<u':
@ -11276,48 +11333,55 @@ function parse_fonts(t, styles, themes, opts) {
case "doubleAccounting": font.underline = 0x22; break;
} break;
case '<u/>': font.underline = 1; break;
case '</u>': case '</u': break;
/* 18.4.10 strike CT_BooleanProperty */
case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
case '<strike/>': font.strike = 1; break;
case '</strike>': case '</strike': break;
/* 18.4.2 outline CT_BooleanProperty */
case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
case '<outline/>': font.outline = 1; break;
case '</outline>': case '</outline': break;
/* 18.8.36 shadow CT_BooleanProperty */
case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
case '<shadow/>': font.shadow = 1; break;
case '</shadow>': case '</shadow': break;
/* 18.8.12 condense CT_BooleanProperty */
case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
case '<condense/>': font.condense = 1; break;
case '</condense>': case '</condense': break;
/* 18.8.17 extend CT_BooleanProperty */
case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
case '<extend/>': font.extend = 1; break;
case '</extend>': case '</extend': break;
/* 18.4.11 sz CT_FontSize */
case '<sz': if(y.val) font.sz = +y.val; break;
case '<sz/>': case '</sz>': break;
case '<sz/>': case '</sz>': case '</sz': break;
/* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
case '<vertAlign/>': case '</vertAlign>': break;
case '<vertAlign/>': case '</vertAlign>': case '</vertAlign': break;
/* 18.8.18 family CT_FontFamily */
case '<family': if(y.val) font.family = parseInt(y.val,10); break;
case '<family/>': case '</family>': break;
case '<family/>': case '</family>': case '</family': break;
/* 18.8.35 scheme CT_FontScheme */
case '<scheme': if(y.val) font.scheme = y.val; break;
case '<scheme/>': case '</scheme>': break;
case '<scheme/>': case '</scheme>': case '</scheme': break;
/* 18.4.1 charset CT_IntProperty */
case '<charset':
if(y.val == '1') break;
y.codepage = CS2CP[parseInt(y.val, 10)];
break;
case '<charset/>': case '</charset>': case '</charset': break;
/* 18.?.? color CT_Color */
case '<color':
@ -11340,11 +11404,11 @@ function parse_fonts(t, styles, themes, opts) {
}
break;
case '<color/>': case '</color>': break;
case '<color/>': case '</color>': case '</color': break;
/* note: sometimes mc:AlternateContent appears bare */
case '<AlternateContent': pass = true; break;
case '</AlternateContent>': pass = false; break;
case '</AlternateContent>': case '</AlternateContent': pass = false; break;
/* 18.2.10 extLst CT_ExtensionList ? */
case '<extLst': case '<extLst>': case '</extLst>': break;
@ -15850,7 +15914,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
var merges/*:Array<Range>*/ = [];
var _merge = data2.match(mergecregex);
if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("=")+2));
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
var hlink = data2.match(hlinkregex);
@ -16309,16 +16373,17 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*//*::, rels*/)/*:string*/ {
var o/*:Array<string>*/ = [], r/*:Array<string>*/ = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols/*:Array<string>*/ = [], R=0, C=0, rows = ws['!rows'];
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, data = dense ? ws["!data"] : [];
var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
var data_R = dense ? data[R] : [];
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var _cell = dense ? (ws["!data"][R]||[])[C]: ws[ref];
var _cell = dense ? data_R[C] : ws[ref];
if(_cell === undefined) continue;
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb, date1904)) != null) r.push(cell);
}
@ -17320,12 +17385,15 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) {
if(last_seen) write_record(ba, 0x000D /* BrtShortRk */, write_BrtShortRk(cell, o));
else write_record(ba, 0x0002 /* BrtCellRk */, write_BrtCellRk(cell, o));
} else if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else if(!isFinite(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
o.t = "e";
if(isNaN(cell.v)) {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x24}, o)); // #NUM!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x24}, o)); // #NUM!
} else {
if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError({t:"e", v: 0x07}, o)); // #DIV/0!
else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError({t:"e", v: 0x07}, o)); // #DIV/0!
}
} else {
if(last_seen) write_record(ba, 0x0010 /* BrtShortReal */, write_BrtShortReal(cell, o));
else write_record(ba, 0x0005 /* BrtCellReal */, write_BrtCellReal(cell, o));
@ -17347,23 +17415,24 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
}
function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols/*:Array<string>*/ = [];
var range = safe_decode_range(ws['!ref'] || "A1"), rr = "", cols/*:Array<string>*/ = [];
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
write_record(ba, 0x0091 /* BrtBeginSheetData */);
var dense = ws["!data"] != null;
var dense = ws["!data"] != null, row = dense ? ws["!data"][range.s.r] : [];
var cap = range.e.r;
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
for(var R = range.s.r; R <= cap; ++R) {
rr = encode_row(R);
if(dense) row = ws["!data"][R];
/* [ACCELLTABLE] */
/* BrtRowHdr */
write_row_header(ba, ws, range, R);
if(dense && !row) continue;
var last_seen = false;
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
var cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) { last_seen = false; continue; }
/* write cell */
last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen, date1904);
@ -19635,7 +19704,13 @@ function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb,
var t = "", p = "";
switch(cell.t) {
case 'z': if(!opts.sheetStubs) return ""; break;
case 'n': t = 'Number'; p = String(cell.v); break;
case 'n': {
if(!isFinite(cell.v)) {
t = 'Error'; p = BErr[isNaN(cell.v) ? 0x24 : 0x07];
} else {
t = 'Number'; p = String(cell.v);
}
} break;
case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
case 'e': t = 'Error'; p = BErr[cell.v]; break;
case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || table_fmt[14]; break;
@ -19677,9 +19752,12 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
o.push(writextag("Column",null,k));
});
var dense = ws["!data"] != null;
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
@ -19690,7 +19768,6 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo
break;
}
if(skip) continue;
var addr = {r:R,c:C};
var ref = encode_col(C) + encode_row(R), cell = dense ? (ws["!data"][R]||[])[C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr));
}
@ -19714,7 +19791,7 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
/* WorksheetOptions */
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
if(ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
if(ws && ws["!autofilter"]) o.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
return o.join("");
}
@ -19733,11 +19810,10 @@ function write_xlml(wb, opts)/*:string*/ {
d.push(write_props_xlml(wb, opts));
d.push(write_wb_xlml(wb, opts));
d.push("");
d.push("");
d.push(write_names_xlml(wb, opts));
for(var i = 0; i < wb.SheetNames.length; ++i)
d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
d[2] = write_sty_xlml(wb, opts);
d[3] = write_names_xlml(wb, opts);
return XML_HEADER + writextag("Workbook", d.join(""), {
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
@ -21923,7 +21999,7 @@ function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts,
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, 0x3FFF);
range.e.r = Math.min(range.e.r, 0x3FFF);
}
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
var row = [], comments = [];
@ -22333,9 +22409,9 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
var range = safe_decode_range(ws['!ref'] || "A1");
var MAX_ROWS = b8 ? 65536 : 16384;
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV" + MAX_ROWS);
range.e.c = Math.min(range.e.c, 0xFF);
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
range.e.r = Math.min(range.e.r, MAX_ROWS-1);
}
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
@ -22370,12 +22446,11 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
if(dense) row = ws["!data"][R] || [];
rr = encode_row(R);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
var cell = dense ? row[C] : ws[ref];
var cell = dense ? row[C] : ws[cols[C] + rr];
if(!cell) continue;
/* write cell */
write_ws_biff8_cell(ba, cell, R, C, opts, date1904);
if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
if(b8 && cell.l) ws['!links'].push([cols[C] + rr, cell.l]);
if(cell.c) comments.push([cell.c, R, C]);
}
}
@ -22519,6 +22594,9 @@ function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
if(range.e.c > 255) { // note: 255 is IV
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond column IV (255). Data may be lost.");
}
if(range.e.r > 65535) {
if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond row 65536. Data may be lost.");
}
}
var o = opts || {};
@ -22578,6 +22656,8 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
if(opts.UTC === false) o.v = utc_to_local(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
} else if(m.charCodeAt(0) == 35 /* # */ && RBErr[m] != null) {
o.t = 'e'; o.w = m; o.v = RBErr[m];
}
if(o.cellText !== false) o.w = m;
if(dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = o; }
@ -22605,6 +22685,10 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
if(RS < 0) continue;
var coord = encode_col(C) + encode_row(R);
var cell = dense ? (ws["!data"][R]||[])[C] : ws[coord];
if(cell && cell.t == 'n' && cell.v != null && !isFinite(cell.v)) {
if(isNaN(cell.v)) cell = ({t:'e', v:0x24, w:BErr[0x24]});
else cell = ({t:'e', v:0x07, w:BErr[0x07]});
}
/* TODO: html entities */
var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
sp = ({}/*:any*/);
@ -22715,6 +22799,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(v != null) {
if(v.length == 0) o.t = _t || 'z';
else if(opts.raw || v.trim().length == 0 || _t == "s"){}
else if(_t == "e" && BErr[+v]) o = {t:'e', v:+v, w: BErr[+v]};
else if(v === 'TRUE') o = {t:'b', v:true};
else if(v === 'FALSE') o = {t:'b', v:false};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
@ -22723,7 +22808,7 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/
if(opts.UTC) o.v = local_to_utc(o.v);
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
o.z = opts.dateNF || table_fmt[14];
}
} else if(v.charCodeAt(0) == 35 /* # */ && RBErr[v] != null) o = ({t:'e', v: RBErr[v], w: v});
}
if(o.z === undefined && z != null) o.z = z;
/* The first link is used. Links are assumed to be fully specified.
@ -23024,7 +23109,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
var Sheets = {}, SheetNames/*:Array<string>*/ = [];
var ws = ({}/*:any*/); if(opts.dense) ws["!data"] = [];
var Rn, q/*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
var ctag = ({value:""}/*:any*/);
var ctag = ({value:""}/*:any*/), ctag2 = ({}/*:any*/);
var textp = "", textpidx = 0, textptag/*:: = {}*/, oldtextp = "", oldtextpidx = 0;
var textR = [], oldtextR = [];
var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
@ -23083,10 +23168,18 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
C = -1; break;
case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
if(Rn[1] !== '/') ++C;
if(opts.sheetStubs) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
if(Rn[1] !== '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1",10) || 1;
if(opts.sheetStubs) {
while(colpeat-- > 0) {
if(opts.dense) { if(!ws["!data"][R]) ws["!data"][R] = []; ws["!data"][R][C] = {t:'z'}; }
else ws[encode_cell({r:R,c:C})] = {t:'z'};
++C;
} --C;
}
else C += colpeat - 1;
}
textp = ""; textR = [];
break; /* stub */
@ -23094,7 +23187,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(Rn[0].charAt(Rn[0].length-2) === '/') {
++C;
ctag = parsexmltag(Rn[0], false);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
colpeat = parseInt(ctag['number-columns-repeated']||"1", 10)||1;
q = ({t:'z', v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -23118,6 +23211,7 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
if(R < range.s.r) range.s.r = R;
if(rptR > range.e.r) range.e.r = rptR;
ctag = parsexmltag(Rn[0], false);
ctag2 = parsexmltagraw(Rn[0], true);
comments = []; comment = ({}/*:any*/);
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
if(ctag["style-name"] && styles[ctag["style-name"]]) q.z = styles[ctag["style-name"]];
@ -23137,10 +23231,12 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
q.F = arrayf[i][1];
}
if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
mR = parseInt(ctag['number-rows-spanned'],10) || 0;
mC = parseInt(ctag['number-columns-spanned'],10) || 0;
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
mR = parseInt(ctag['number-rows-spanned']||"1",10) || 1;
mC = parseInt(ctag['number-columns-spanned']||"1",10) || 1;
if(mR * mC > 1) {
mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
merges.push(mrange);
}
}
/* 19.675.2 table:number-columns-repeated */
@ -23171,6 +23267,9 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
}
} else {
isstub = false;
if(ctag2['calcext:value-type'] == "error" && RBErr[textp] != null) {
q.t = 'e'; q.w = textp; q.v = RBErr[textp];
}
if(q.t === 's') {
q.v = textp || '';
if(textR.length) q.R = textR;
@ -23569,7 +23668,6 @@ function parse_fods(data/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
wb.bookType = "fods";
return wb;
}
/* OpenDocument */
var write_styles_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function() {
var master_styles = [
@ -23834,9 +23932,22 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
break;
case 'n':
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
if(!isFinite(cell.v)) {
if(isNaN(cell.v)) {
textp = "#NUM!";
ct['table:formula'] = "of:=#NUM!";
} else {
textp = "#DIV/0!";
ct['table:formula'] = "of:=" + (cell.v < 0 ? "-" : "") + "1/0";
}
ct['office:string-value'] = "";
ct['office:value-type'] = "string";
ct['calcext:value-type'] = "error";
} else {
textp = (cell.w||String(cell.v||0));
ct['office:value-type'] = "float";
ct['office:value'] = (cell.v||0);
}
break;
case 's': case 'str':
textp = cell.v == null ? "" : cell.v;
@ -25188,7 +25299,7 @@ function s5s_to_iwa_comment(s5s) {
return out;
}
function parse_TST_TableModelArchive(M, root, ws, opts) {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
var pb = parse_shallow(root.data);
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
@ -25267,6 +25378,38 @@ function parse_TST_TableModelArchive(M, root, ws, opts) {
};
});
}
if (!((_k = ws["!merges"]) == null ? void 0 : _k.length) && ((_l = pb[47]) == null ? void 0 : _l[0])) {
var merge_owner = parse_shallow(pb[47][0].data);
if ((_m = merge_owner[2]) == null ? void 0 : _m[0]) {
var formula_store = parse_shallow(merge_owner[2][0].data);
if ((_n = formula_store[3]) == null ? void 0 : _n[0]) {
ws["!merges"] = mappa(formula_store[3], function(u) {
var _a2, _b2, _c2, _d2, _e2;
var formula_pair = parse_shallow(u);
var formula = parse_shallow(formula_pair[2][0].data);
var AST_node_array = parse_shallow(formula[1][0].data);
if (!((_a2 = AST_node_array[1]) == null ? void 0 : _a2[0]))
return;
var AST_node0 = parse_shallow(AST_node_array[1][0].data);
var AST_node_type = varint_to_i32(AST_node0[1][0].data);
if (AST_node_type != 67)
return;
var AST_colon_tract = parse_shallow(AST_node0[40][0].data);
if (!((_b2 = AST_colon_tract[3]) == null ? void 0 : _b2[0]) || !((_c2 = AST_colon_tract[4]) == null ? void 0 : _c2[0]))
return;
var colrange = parse_shallow(AST_colon_tract[3][0].data);
var rowrange = parse_shallow(AST_colon_tract[4][0].data);
var c = varint_to_i32(colrange[1][0].data);
var C = ((_d2 = colrange[2]) == null ? void 0 : _d2[0]) ? varint_to_i32(colrange[2][0].data) : c;
var r = varint_to_i32(rowrange[1][0].data);
var R = ((_e2 = rowrange[2]) == null ? void 0 : _e2[0]) ? varint_to_i32(rowrange[2][0].data) : r;
return { s: { r: r, c: c }, e: { r: R, c: C } };
}).filter(function(x) {
return x != null;
});
}
}
}
}
function parse_TST_TableInfoArchive(M, root, opts) {
var pb = parse_shallow(root.data);
@ -27077,6 +27220,8 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
var o = opts||{};
if(o.codepage && typeof $cptable === "undefined") console.error("Codepage tables are not loaded. Non-ASCII characters may not give expected results");
if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
/* Javet projects `byte[]` to `Int8Array` */
if(typeof Int8Array !== 'undefined' && data instanceof Int8Array) return readSync(new Uint8Array(data.buffer, data.byteOffset, data.length), 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; }
@ -27439,7 +27584,7 @@ function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) {
}
var qreg = /"/g;
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, w/*:number*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
var isempty = true;
var row/*:Array<string>*/ = [], txt = "", rr = encode_row(R);
var dense = sheet["!data"] != null;
@ -27452,7 +27597,7 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr
isempty = false;
txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
if(txt == "ID") txt = '"ID"';
if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"';
} else if(val.f != null && !val.F) {
isempty = false;
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
@ -27479,7 +27624,7 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
var w = 0;
for(var R = r.s.r; R <= r.e.r; ++R) {
if ((rowinfo[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, w, o);
if(row == null) { continue; }
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
}
@ -27494,7 +27639,7 @@ function sheet_to_txt(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
function sheet_to_formulae(sheet/*:Worksheet*/, opts/*:?Sheet2FormulaOpts*/)/*:Array<string>*/ {
var y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols/*:Array<string>*/ = [], C;
@ -27515,6 +27660,7 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
if(y.indexOf(":") == -1) y = y + ":" + y;
}
if(x.f != null) val = x.f;
else if(opts && opts.values === false) continue;
else if(x.t == 'z') continue;
else if(x.t == 'n' && x.v != null) val = "" + x.v;
else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";
@ -27783,7 +27929,7 @@ function write_csv_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
while(R <= r.e.r) {
++R;
if ((rowinfo[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, w, o);
if(row != null) {
if(row || (o.blankrows !== false)) return stream.push((w++ ? RS : "") + row);
}
@ -27880,10 +28026,165 @@ function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
return stream;
}
function write_xlml_stream(wb/*:Workbook*/, o/*:?Sheet2XLMLOpts*/) {
var stream = _Readable();
var opts = o == null ? {} : o;
var stride = +opts.stride || 10;
if(!wb.SSF) wb.SSF = dup(table_fmt);
if(wb.SSF) {
make_ssf(); SSF_load_table(wb.SSF);
// $FlowIgnore
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
opts.ssf = wb.SSF;
opts.cellXfs = [];
get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
}
/* do one pass to determine styles since they must be added before tables */
wb.SheetNames.forEach(function(n) {
var ws = wb.Sheets[n];
if(!ws || !ws["!ref"]) return;
var range = decode_range(ws["!ref"]);
var dense = ws["!data"] != null;
var ddata = dense ? ws["!data"] : [];
var addr = {r:0,c:0};
for(var R = range.s.r; R <= range.e.r; ++R) {
addr.r = R;
if(dense && !ddata[R]) continue;
for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var cell = dense ? ddata[R][C] : ws[encode_col(C) + encode_row(R)];
if(!cell) continue;
if(cell.t == "d" && cell.z == null) { cell = dup(cell); cell.z = table_fmt[14]; }
void get_cell_style(opts.cellXfs, cell, opts);
}
}
});
var sty = write_sty_xlml(wb, opts);
var stage = 0, wsidx = 0, ws = wb.Sheets[wb.SheetNames[wsidx]], range = safe_decode_range(ws), R = -1, T = false;
var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
stream._read = function() { switch(stage) {
/* header */
case 0: {
stage = 1;
stream.push(XML_HEADER);
stream.push("<Workbook" + wxt_helper({
'xmlns': XLMLNS.ss,
'xmlns:o': XLMLNS.o,
'xmlns:x': XLMLNS.x,
'xmlns:ss': XLMLNS.ss,
'xmlns:dt': XLMLNS.dt,
'xmlns:html': XLMLNS.html
}) + ">");
} break;
/* preamble */
case 1: {
stage = 2;
stream.push(write_props_xlml(wb, opts));
stream.push(write_wb_xlml(wb, opts));
} break;
/* style and name tables */
case 2: {
stage = 3;
stream.push(sty);
stream.push(write_names_xlml(wb, opts));
} break;
/* worksheet preamble */
case 3: {
T = false;
if(wsidx >= wb.SheetNames.length) { stage = -1; stream.push(""); break; }
stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
ws = wb.Sheets[wb.SheetNames[wsidx]];
if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
var names = write_ws_xlml_names(ws, opts, wsidx, wb);
if(names.length) stream.push("<Names>" + names + "</Names>");
if(!ws["!ref"]) return (stage = 5);
range = safe_decode_range(ws["!ref"]);
R = range.s.r;
stage = 4;
} break;
/* worksheet intramble */
case 4: {
if(R < 0 || R > range.e.r) { if(T) stream.push("</Table>"); return void (stage = 5); }
if(R <= range.s.r) {
if(ws['!cols']) ws['!cols'].forEach(function(n, i) {
process_col(n);
var w = !!n.width;
var p = col_obj_w(i, n);
var k/*:any*/ = {"ss:Index":i+1};
if(w) k['ss:Width'] = width2px(p.width);
if(n.hidden) k['ss:Hidden']="1";
if(!T) { T = true; stream.push("<Table>"); }
stream.push(writextag("Column",null,k));
});
dense = ws["!data"] != null;
if(dense) darr = ws["!data"];
addr.r = addr.c = 0;
}
/* process `stride` rows per invocation */
for(var cnt = 0; R <= range.e.r && cnt < stride; ++R, ++cnt) {
var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
addr.r = R;
if(!(dense && !darr[R])) for(var C = range.s.c; C <= range.e.c; ++C) {
addr.c = C;
var skip = false;
for(mi = 0; mi != marr.length; ++mi) {
if(marr[mi].s.c > C) continue;
if(marr[mi].s.r > R) continue;
if(marr[mi].e.c < C) continue;
if(marr[mi].e.r < R) continue;
if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
break;
}
if(skip) continue;
var ref = encode_col(C) + encode_row(R), cell = dense ? darr[R][C] : ws[ref];
row.push(write_ws_xlml_cell(cell, ref, ws, opts, wsidx, wb, addr));
}
row.push("</Row>");
if(!T) { T = true; stream.push("<Table>"); }
stream.push(row.join(""));
}
} break;
/* worksheet postamble */
case 5: {
stream.push(write_ws_xlml_wsopts(ws, opts, wsidx, wb));
if(ws && ws["!autofilter"]) stream.push('<AutoFilter x:Range="' + a1_to_rc(fix_range(ws["!autofilter"].ref), {r:0,c:0}) + '" xmlns="urn:schemas-microsoft-com:office:excel"></AutoFilter>');
stream.push("</Worksheet>");
wsidx++; R = -1;
return void (stage = 3);
}
/* footer */
case -1: {
stage = -2;
stream.push("</Workbook>");
} break;
/* exeunt */
case -2: stream.push(null); break;
}};
return stream;
}
var __stream = {
to_json: write_json_stream,
to_html: write_html_stream,
to_csv: write_csv_stream,
to_xlml: write_xlml_stream,
set_readable: set_readable
};
export const version = XLSX.version;