forked from sheetjs/sheetjs
Compare commits
25 Commits
Author | SHA1 | Date | |
---|---|---|---|
4495a9253e | |||
0e4eb976e1 | |||
9c3853ba25 | |||
318e2319ee | |||
6c0f950f83 | |||
235ed7ccfb | |||
2d6c821261 | |||
36debb0eaa | |||
df48a059c3 | |||
647cdb89f5 | |||
6912bdb2d4 | |||
5550b90704 | |||
9368a85b5f | |||
2669c7cf1c | |||
b61eed74fc | |||
8a7cfd47bd | |||
f215b8f79f | |||
5a36cb423d | |||
5ef49e2b96 | |||
947a5178bd | |||
87a695747e | |||
a0bed2a97d | |||
0941ff97a3 | |||
e4a66516e4 | |||
d4d4ff3da2 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -39,3 +39,5 @@ tmp
|
||||
*.sheetjs
|
||||
*.exe
|
||||
*.img
|
||||
test_files.zip
|
||||
test_files/
|
||||
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,4 +0,0 @@
|
||||
[submodule "test_files"]
|
||||
path = test_files
|
||||
url = https://github.com/SheetJS/test_files
|
||||
ignore = dirty
|
19
CHANGELOG.md
19
CHANGELOG.md
@ -4,6 +4,25 @@ 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)
|
||||
* HTML properly encode data-v attribute
|
||||
* SYLK read and write error cells
|
||||
|
||||
## v0.20.1
|
||||
|
||||
* `init` use packaged test files to work around GitHub breaking changes
|
||||
|
@ -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.
|
||||
|
4
Makefile
4
Makefile
@ -152,8 +152,8 @@ 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")' > $@
|
||||
|
||||
.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
|
||||
|
64
bin/xlsx.njs
64
bin/xlsx.njs
@ -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,6 +1,6 @@
|
||||
/*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*exported XLSX */
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Float32Array:false */
|
||||
/*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){
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.20.1';
|
||||
XLSX.version = '0.20.3';
|
||||
|
@ -6,26 +6,26 @@ var $cptable;
|
||||
var VALID_ANSI = [ 874, 932, 936, 949, 950, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 10000 ];
|
||||
/* ECMA-376 Part I 18.4.1 charset to codepage mapping */
|
||||
var CS2CP = ({
|
||||
/*::[*/0/*::]*/: 1252, /* ANSI */
|
||||
/*::[*/1/*::]*/: 65001, /* DEFAULT */
|
||||
/*::[*/2/*::]*/: 65001, /* SYMBOL */
|
||||
/*::[*/77/*::]*/: 10000, /* MAC */
|
||||
/*::[*/128/*::]*/: 932, /* SHIFTJIS */
|
||||
/*::[*/129/*::]*/: 949, /* HANGUL */
|
||||
/*::[*/130/*::]*/: 1361, /* JOHAB */
|
||||
/*::[*/134/*::]*/: 936, /* GB2312 */
|
||||
/*::[*/136/*::]*/: 950, /* CHINESEBIG5 */
|
||||
/*::[*/161/*::]*/: 1253, /* GREEK */
|
||||
/*::[*/162/*::]*/: 1254, /* TURKISH */
|
||||
/*::[*/163/*::]*/: 1258, /* VIETNAMESE */
|
||||
/*::[*/177/*::]*/: 1255, /* HEBREW */
|
||||
/*::[*/178/*::]*/: 1256, /* ARABIC */
|
||||
/*::[*/186/*::]*/: 1257, /* BALTIC */
|
||||
/*::[*/204/*::]*/: 1251, /* RUSSIAN */
|
||||
/*::[*/222/*::]*/: 874, /* THAI */
|
||||
/*::[*/238/*::]*/: 1250, /* EASTEUROPE */
|
||||
/*::[*/255/*::]*/: 1252, /* OEM */
|
||||
/*::[*/69/*::]*/: 6969 /* MISC */
|
||||
0: 1252, /* ANSI */
|
||||
1: 65001, /* DEFAULT */
|
||||
2: 65001, /* SYMBOL */
|
||||
77: 10000, /* MAC */
|
||||
128: 932, /* SHIFTJIS */
|
||||
129: 949, /* HANGUL */
|
||||
130: 1361, /* JOHAB */
|
||||
134: 936, /* GB2312 */
|
||||
136: 950, /* CHINESEBIG5 */
|
||||
161: 1253, /* GREEK */
|
||||
162: 1254, /* TURKISH */
|
||||
163: 1258, /* VIETNAMESE */
|
||||
177: 1255, /* HEBREW */
|
||||
178: 1256, /* ARABIC */
|
||||
186: 1257, /* BALTIC */
|
||||
204: 1251, /* RUSSIAN */
|
||||
222: 874, /* THAI */
|
||||
238: 1250, /* EASTEUROPE */
|
||||
255: 1252, /* OEM */
|
||||
69: 6969 /* MISC */
|
||||
}/*:any*/);
|
||||
|
||||
var set_ansi = function(cp/*:number*/) { if(VALID_ANSI.indexOf(cp) == -1) return; current_ansi = CS2CP[0] = cp; };
|
||||
|
@ -68,7 +68,12 @@ function Base64_encode_arr(input) {
|
||||
function Base64_decode(input) {
|
||||
var o = "";
|
||||
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
||||
input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/, "").replace(/[^\w\+\/\=]/g, "");
|
||||
if (input.slice(0, 5) == "data:") {
|
||||
var i = input.slice(0, 1024).indexOf(";base64,");
|
||||
if (i > -1)
|
||||
input = input.slice(i + 8);
|
||||
}
|
||||
input = input.replace(/[^\w\+\/\=]/g, "");
|
||||
for (var i = 0; i < input.length; ) {
|
||||
e1 = Base64_map.indexOf(input.charAt(i++));
|
||||
e2 = Base64_map.indexOf(input.charAt(i++));
|
||||
|
@ -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);
|
||||
@ -408,7 +409,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;
|
||||
@ -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;
|
||||
@ -769,9 +771,9 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|strin
|
||||
file = cfb.FileIndex[i];
|
||||
if(i === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;
|
||||
var _nm/*:string*/ = (i === 0 && _opts.root) || file.name;
|
||||
if(_nm.length > 32) {
|
||||
console.error("Name " + _nm + " will be truncated to " + _nm.slice(0,32));
|
||||
_nm = _nm.slice(0, 32);
|
||||
if(_nm.length > 31) {
|
||||
console.error("Name " + _nm + " will be truncated to " + _nm.slice(0,31));
|
||||
_nm = _nm.slice(0, 31);
|
||||
}
|
||||
flen = 2*(_nm.length+1);
|
||||
o.write_shift(64, _nm, "utf16le");
|
||||
@ -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);
|
||||
@ -1683,7 +1686,7 @@ function parse_mime(cfb/*:CFBContainer*/, data/*:Array<string>*/, root/*:string*
|
||||
for(;di < 10; ++di) {
|
||||
var line = data[di];
|
||||
if(!line || line.match(/^\s*$/)) break;
|
||||
var m = line.match(/^(.*?):\s*([^\s].*)$/);
|
||||
var m = line.match(/^([^:]*?):\s*([^\s].*)$/);
|
||||
if(m) switch(m[1].toLowerCase()) {
|
||||
case "content-location": fname = m[2].trim(); break;
|
||||
case "content-type": ctype = m[2].trim(); break;
|
||||
|
@ -57,7 +57,7 @@ function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
|
||||
var out = File(fname); out.open("w"); out.encoding = "binary";
|
||||
if(Array.isArray(payload)) payload = a2s(payload);
|
||||
out.write(payload); out.close(); return payload;
|
||||
} catch(e) { if(!e.message || !e.message.match(/onstruct/)) throw e; }
|
||||
} catch(e) { if(!e.message || e.message.indexOf("onstruct") == -1) throw e; }
|
||||
throw new Error("cannot save file " + fname);
|
||||
}
|
||||
|
||||
@ -71,6 +71,6 @@ function read_binary(path/*:string*/) {
|
||||
var infile = File(path); infile.open("r"); infile.encoding = "binary";
|
||||
var data = infile.read(); infile.close();
|
||||
return data;
|
||||
} catch(e) { if(!e.message || !e.message.match(/onstruct/)) throw e; }
|
||||
} catch(e) { if(!e.message || e.message.indexOf("onstruct") == -1) throw e; }
|
||||
throw new Error("Cannot access file " + path);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ function parseDate(str/*:string*/, date1904/*:boolean*/)/*:Date*/ {
|
||||
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
|
||||
/* TODO: 1900-02-29T00:00:00.000 should return a flag to treat as a date code (affects xlml) */
|
||||
m = str.match(pdre3);
|
||||
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
|
||||
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt((m[7] + "0000").slice(1,4), 10))||0)));
|
||||
var d = new Date(str);
|
||||
return d;
|
||||
}
|
||||
@ -154,7 +154,7 @@ function fuzzynum(s/*:string*/)/*:number*/ {
|
||||
var wt = 1;
|
||||
var ss = s.replace(/([\d]),([\d])/g,"$1$2").replace(/[$]/g,"").replace(/[%]/g, function() { wt *= 100; return "";});
|
||||
if(!isNaN(v = Number(ss))) return v / wt;
|
||||
ss = ss.replace(/[(](.*)[)]/,function($$, $1) { wt = -wt; return $1;});
|
||||
ss = ss.replace(/[(]([^()]*)[)]/,function($$, $1) { wt = -wt; return $1;});
|
||||
if(!isNaN(v = Number(ss))) return v / wt;
|
||||
return v;
|
||||
}
|
||||
@ -195,7 +195,7 @@ function fuzzydate(s/*:string*/)/*:Date*/ {
|
||||
M = lnos.match(FDRE2);
|
||||
if(M) return fuzzytime2(M);
|
||||
M = lnos.match(pdre3);
|
||||
if(M) return new Date(Date.UTC(+M[1], +M[2]-1, +M[3], +M[4], +M[5], ((M[6] && parseInt(M[6].slice(1), 10))|| 0), ((M[7] && parseInt(M[7].slice(1), 10))||0)));
|
||||
if(M) return new Date(Date.UTC(+M[1], +M[2]-1, +M[3], +M[4], +M[5], ((M[6] && parseInt(M[6].slice(1), 10))|| 0), ((M[7] && parseInt((M[7] + "0000").slice(1,4), 10))||0)));
|
||||
var o = new Date(utc_append_works && s.indexOf("UTC") == -1 ? s + " UTC": s), n = new Date(NaN);
|
||||
var y = o.getYear(), m = o.getMonth(), d = o.getDate();
|
||||
if(isNaN(d)) return n;
|
||||
@ -223,3 +223,158 @@ function utc_to_local(utc) {
|
||||
function local_to_utc(local) {
|
||||
return new Date(Date.UTC(local.getFullYear(), local.getMonth(), local.getDate(), local.getHours(), local.getMinutes(), local.getSeconds(), local.getMilliseconds()));
|
||||
}
|
||||
|
||||
function remove_doctype(str) {
|
||||
var preamble = str.slice(0, 1024);
|
||||
var si = preamble.indexOf("<!DOCTYPE");
|
||||
if(si == -1) return str;
|
||||
var m = str.match(/<[\w]/);
|
||||
if(!m) return str;
|
||||
return str.slice(0, si) + str.slice(m.index);
|
||||
}
|
||||
|
||||
/* str.match(/<!--[\s\S]*?-->/g) --> str_match_ng(str, "<!--", "-->") */
|
||||
function str_match_ng(str, s, e) {
|
||||
var out = [];
|
||||
|
||||
var si = str.indexOf(s);
|
||||
while(si > -1) {
|
||||
var ei = str.indexOf(e, si + s.length);
|
||||
if(ei == -1) break;
|
||||
|
||||
out.push(str.slice(si, ei + e.length));
|
||||
si = str.indexOf(s, ei + e.length);
|
||||
}
|
||||
|
||||
return out.length > 0 ? out : null;
|
||||
}
|
||||
|
||||
/* str.replace(/<!--[\s\S]*?-->/g, "") --> str_remove_ng(str, "<!--", "-->") */
|
||||
function str_remove_ng(str, s, e) {
|
||||
var out = [], last = 0;
|
||||
|
||||
var si = str.indexOf(s);
|
||||
if(si == -1) return str;
|
||||
while(si > -1) {
|
||||
out.push(str.slice(last, si));
|
||||
var ei = str.indexOf(e, si + s.length);
|
||||
if(ei == -1) break;
|
||||
|
||||
if((si = str.indexOf(s, (last = ei + e.length))) == -1) out.push(str.slice(last));
|
||||
}
|
||||
|
||||
return out.join("");
|
||||
}
|
||||
|
||||
/* str.match(/<tag\b[^>]*?>([\s\S]*?)</tag>/) --> str_match_xml(str, "tag") */
|
||||
var xml_boundary = { " ": 1, "\t": 1, "\r": 1, "\n": 1, ">": 1 };
|
||||
function str_match_xml(str, tag) {
|
||||
var si = str.indexOf('<' + tag), w = tag.length + 1, L = str.length;
|
||||
while(si >= 0 && si <= L - w && !xml_boundary[str.charAt(si + w)]) si = str.indexOf('<' + tag, si+1);
|
||||
if(si === -1) return null;
|
||||
var sf = str.indexOf(">", si + tag.length);
|
||||
if(sf === -1) return null;
|
||||
var et = "</" + tag + ">";
|
||||
var ei = str.indexOf(et, sf);
|
||||
if(ei == -1) return null;
|
||||
return [str.slice(si, ei + et.length), str.slice(sf + 1, ei)];
|
||||
}
|
||||
|
||||
/* str.match(/<(?:\w+:)?tag\b[^<>]*?>([\s\S]*?)<\/(?:\w+:)?tag>/) --> str_match_xml(str, "tag") */
|
||||
var str_match_xml_ns = /*#__PURE__*/(function() {
|
||||
var str_match_xml_ns_cache = {};
|
||||
return function str_match_xml_ns(str, tag) {
|
||||
var res = str_match_xml_ns_cache[tag];
|
||||
if(!res) str_match_xml_ns_cache[tag] = res = [
|
||||
new RegExp('<(?:\\w+:)?'+tag+'\\b[^<>]*>', "g"),
|
||||
new RegExp('</(?:\\w+:)?'+tag+'>', "g")
|
||||
];
|
||||
res[0].lastIndex = res[1].lastIndex = 0;
|
||||
var m = res[0].exec(str);
|
||||
if(!m) return null;
|
||||
var si = m.index;
|
||||
var sf = res[0].lastIndex;
|
||||
res[1].lastIndex = res[0].lastIndex;
|
||||
m = res[1].exec(str);
|
||||
if(!m) return null;
|
||||
var ei = m.index;
|
||||
var ef = res[1].lastIndex;
|
||||
return [str.slice(si, ef), str.slice(sf, ei)];
|
||||
};
|
||||
})();
|
||||
|
||||
/* str.match(/<(?:\w+:)?tag\b[^<>]*?>([\s\S]*?)<\/(?:\w+:)?tag>/g) --> str_match_xml_ns_g(str, "tag") */
|
||||
var str_match_xml_ns_g = /*#__PURE__*/(function() {
|
||||
var str_match_xml_ns_cache = {};
|
||||
return function str_match_xml_ns(str, tag) {
|
||||
var out = [];
|
||||
var res = str_match_xml_ns_cache[tag];
|
||||
if(!res) str_match_xml_ns_cache[tag] = res = [
|
||||
new RegExp('<(?:\\w+:)?'+tag+'\\b[^<>]*>', "g"),
|
||||
new RegExp('</(?:\\w+:)?'+tag+'>', "g")
|
||||
];
|
||||
res[0].lastIndex = res[1].lastIndex = 0;
|
||||
var m;
|
||||
while((m = res[0].exec(str))) {
|
||||
var si = m.index;
|
||||
res[1].lastIndex = res[0].lastIndex;
|
||||
m = res[1].exec(str);
|
||||
if(!m) return null;
|
||||
var ef = res[1].lastIndex;
|
||||
out.push(str.slice(si, ef));
|
||||
res[0].lastIndex = res[1].lastIndex;
|
||||
}
|
||||
return out.length == 0 ? null : out;
|
||||
};
|
||||
})();
|
||||
var str_remove_xml_ns_g = /*#__PURE__*/(function() {
|
||||
var str_remove_xml_ns_cache = {};
|
||||
return function str_remove_xml_ns_g(str, tag) {
|
||||
var out = [];
|
||||
var res = str_remove_xml_ns_cache[tag];
|
||||
if(!res) str_remove_xml_ns_cache[tag] = res = [
|
||||
new RegExp('<(?:\\w+:)?'+tag+'\\b[^<>]*>', "g"),
|
||||
new RegExp('</(?:\\w+:)?'+tag+'>', "g")
|
||||
];
|
||||
res[0].lastIndex = res[1].lastIndex = 0;
|
||||
var m;
|
||||
var si = 0, ef = 0;
|
||||
while((m = res[0].exec(str))) {
|
||||
si = m.index;
|
||||
out.push(str.slice(ef, si));
|
||||
ef = si;
|
||||
res[1].lastIndex = res[0].lastIndex;
|
||||
m = res[1].exec(str);
|
||||
if(!m) return null;
|
||||
ef = res[1].lastIndex;
|
||||
res[0].lastIndex = res[1].lastIndex;
|
||||
}
|
||||
out.push(str.slice(ef));
|
||||
return out.length == 0 ? "" : out.join("");
|
||||
};
|
||||
})();
|
||||
|
||||
/* str.match(/<(?:\w+:)?tag\b[^>]*?>([\s\S]*?)<\/(?:\w+:)?tag>/gi) --> str_match_xml_ns_ig(str, "tag") */
|
||||
var str_match_xml_ig = /*#__PURE__*/(function() {
|
||||
var str_match_xml_ns_cache = {};
|
||||
return function str_match_xml_ns(str, tag) {
|
||||
var out = [];
|
||||
var res = str_match_xml_ns_cache[tag];
|
||||
if(!res) str_match_xml_ns_cache[tag] = res = [
|
||||
new RegExp('<'+tag+'\\b[^<>]*>', "ig"),
|
||||
new RegExp('</'+tag+'>', "ig")
|
||||
];
|
||||
res[0].lastIndex = res[1].lastIndex = 0;
|
||||
var m;
|
||||
while((m = res[0].exec(str))) {
|
||||
var si = m.index;
|
||||
res[1].lastIndex = res[0].lastIndex;
|
||||
m = res[1].exec(str);
|
||||
if(!m) return null;
|
||||
var ef = res[1].lastIndex;
|
||||
out.push(str.slice(si, ef));
|
||||
res[0].lastIndex = res[1].lastIndex;
|
||||
}
|
||||
return out.length == 0 ? null : out;
|
||||
};
|
||||
})();
|
||||
|
@ -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);
|
||||
|
@ -1,6 +1,6 @@
|
||||
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
|
||||
var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
|
||||
var tagregex1=/<[\/\?]?[a-zA-Z0-9:_-]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s=]+))*\s*[\/\?]?>/mg, tagregex2 = /<[^>]*>/g;
|
||||
var attregexg=/\s([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
|
||||
var tagregex1=/<[\/\?]?[a-zA-Z0-9:_-]+(?:\s+[^"\s?<>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'"<>\s=]+))*\s*[\/\?]?>/mg, tagregex2 = /<[^<>]*>/g;
|
||||
var tagregex = /*#__PURE__*/XML_HEADER.match(tagregex1) ? tagregex1 : tagregex2;
|
||||
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
|
||||
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*/)/*:any*/ {
|
||||
@ -11,7 +11,7 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*
|
||||
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];
|
||||
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;
|
||||
@ -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;
|
||||
@ -161,16 +187,6 @@ var utf8write/*:StringConv*/ = has_buf ? function(data) { return Buffer_from(dat
|
||||
return out.join("");
|
||||
};
|
||||
|
||||
// matches <foo>...</foo> extracts content
|
||||
var matchtag = /*#__PURE__*/(function() {
|
||||
var mtcache/*:{[k:string]:RegExp}*/ = ({}/*:any*/);
|
||||
return function matchtag(f/*:string*/,g/*:?string*/)/*:RegExp*/ {
|
||||
var t = f+"|"+(g||"");
|
||||
if(mtcache[t]) return mtcache[t];
|
||||
return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([\\s\\S]*?)</(?:\\w+:)?'+f+'>',((g||"")/*:any*/)));
|
||||
};
|
||||
})();
|
||||
|
||||
var htmldecode/*:{(s:string):string}*/ = /*#__PURE__*/(function() {
|
||||
var entities/*:Array<[RegExp, string]>*/ = [
|
||||
['nbsp', ' '], ['middot', '·'],
|
||||
@ -181,30 +197,25 @@ var htmldecode/*:{(s:string):string}*/ = /*#__PURE__*/(function() {
|
||||
// Remove new lines and spaces from start of content
|
||||
.replace(/^[\t\n\r ]+/, "")
|
||||
// Remove new lines and spaces from end of content
|
||||
.replace(/[\t\n\r ]+$/,"")
|
||||
.replace(/(^|[^\t\n\r ])[\t\n\r ]+$/,"$1")
|
||||
// Added line which removes any white space characters after and before html tags
|
||||
.replace(/>\s+/g,">").replace(/\s+</g,"<")
|
||||
.replace(/>\s+/g,">").replace(/\b\s+</g,"<")
|
||||
// Replace remaining new lines and spaces with space
|
||||
.replace(/[\t\n\r ]+/g, " ")
|
||||
// Replace <br> tags with new lines
|
||||
.replace(/<\s*[bB][rR]\s*\/?>/g,"\n")
|
||||
// Strip HTML elements
|
||||
.replace(/<[^>]*>/g,"");
|
||||
.replace(/<[^<>]*>/g,"");
|
||||
for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
|
||||
return o;
|
||||
};
|
||||
})();
|
||||
|
||||
var vtregex = /*#__PURE__*/(function(){ var vt_cache = {};
|
||||
return function vt_regex(bt) {
|
||||
if(vt_cache[bt] !== undefined) return vt_cache[bt];
|
||||
return (vt_cache[bt] = new RegExp("<(?:vt:)?" + bt + ">([\\s\\S]*?)</(?:vt:)?" + bt + ">", 'g') );
|
||||
};})();
|
||||
var vtvregex = /<\/?(?:vt:)?variant>/g, vtmregex = /<(?:vt:)([^>]*)>([\s\S]*)</;
|
||||
var vtvregex = /<\/?(?:vt:)?variant>/g, vtmregex = /<(?:vt:)([^<"'>]*)>([\s\S]*)</;
|
||||
function parseVector(data/*:string*/, opts)/*:Array<{v:string,t:string}>*/ {
|
||||
var h = parsexmltag(data);
|
||||
|
||||
var matches/*:Array<string>*/ = data.match(vtregex(h.baseType))||[];
|
||||
var matches/*:Array<string>*/ = str_match_xml_ns_g(data, h.baseType)||[];
|
||||
var res/*:Array<any>*/ = [];
|
||||
if(matches.length != h.size) {
|
||||
if(opts.WTF) throw new Error("unexpected vector length " + matches.length + " != " + h.size);
|
||||
@ -245,9 +256,8 @@ function xlml_normalize(d)/*:string*/ {
|
||||
if(typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
|
||||
throw new Error("Bad input format: expected Buffer or string");
|
||||
}
|
||||
/* UOS uses CJK in tags */
|
||||
var xlmlregex = /<(\/?)([^\s?><!\/:]*:|)([^\s?<>:\/]+)(?:[\s?:\/](?:[^>=]|="[^"]*?")*)?>/mg;
|
||||
//var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;
|
||||
/* UOS uses CJK in tags, ODS uses invalid XML */
|
||||
var xlmlregex = /<([\/]?)([^\s?><!\/:"]*:|)([^\s?<>:\/"]+)(?:\s+[^<>=?"'\s]+="[^"]*?")*\s*[\/]?>/mg;
|
||||
|
||||
var XMLNS = ({
|
||||
CORE_PROPS: 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties',
|
||||
|
@ -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) {
|
||||
@ -128,44 +128,51 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
|
||||
var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
|
||||
_R = _origin.r; _C = _origin.c;
|
||||
}
|
||||
if(!ws["!ref"]) ws["!ref"] = "A1:A1";
|
||||
}
|
||||
var range/*:Range*/ = ({s: {c:10000000, r:10000000}, e: {c:0, r:0}}/*:any*/);
|
||||
if(ws['!ref']) {
|
||||
if(ws["!ref"]){
|
||||
var _range = safe_decode_range(ws['!ref']);
|
||||
range.s.c = _range.s.c;
|
||||
range.s.r = _range.s.r;
|
||||
range.e.c = Math.max(range.e.c, _range.e.c);
|
||||
range.e.r = Math.max(range.e.r, _range.e.r);
|
||||
if(_R == -1) range.e.r = _R = _range.e.r + 1;
|
||||
if(_R == -1) range.e.r = _R = (ws["!ref"] ? _range.e.r + 1 : 0);
|
||||
} else {
|
||||
range.s.c = range.e.c = range.s.r = range.e.r = 0;
|
||||
}
|
||||
var row = [];
|
||||
var row = [], seen = false;
|
||||
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);
|
||||
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;
|
||||
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][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];
|
||||
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];
|
||||
@ -179,14 +186,13 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(range.s.c < 10000000) ws['!ref'] = encode_range(range);
|
||||
if(seen && range.s.c < 10400000) ws['!ref'] = encode_range(range);
|
||||
return ws;
|
||||
}
|
||||
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
|
||||
|
||||
|
@ -44,118 +44,118 @@ var VT_CUSTOM = [VT_STRING, VT_USTR];
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.2.2.1 Document Summary Information PIDDSI */
|
||||
var DocSummaryPIDDSI = {
|
||||
/*::[*/0x01/*::]*/: { n: 'CodePage', t: VT_I2 },
|
||||
/*::[*/0x02/*::]*/: { n: 'Category', t: VT_STRING },
|
||||
/*::[*/0x03/*::]*/: { n: 'PresentationFormat', t: VT_STRING },
|
||||
/*::[*/0x04/*::]*/: { n: 'ByteCount', t: VT_I4 },
|
||||
/*::[*/0x05/*::]*/: { n: 'LineCount', t: VT_I4 },
|
||||
/*::[*/0x06/*::]*/: { n: 'ParagraphCount', t: VT_I4 },
|
||||
/*::[*/0x07/*::]*/: { n: 'SlideCount', t: VT_I4 },
|
||||
/*::[*/0x08/*::]*/: { n: 'NoteCount', t: VT_I4 },
|
||||
/*::[*/0x09/*::]*/: { n: 'HiddenCount', t: VT_I4 },
|
||||
/*::[*/0x0a/*::]*/: { n: 'MultimediaClipCount', t: VT_I4 },
|
||||
/*::[*/0x0b/*::]*/: { n: 'ScaleCrop', t: VT_BOOL },
|
||||
/*::[*/0x0c/*::]*/: { n: 'HeadingPairs', t: VT_VECTOR_VARIANT /* VT_VECTOR | VT_VARIANT */ },
|
||||
/*::[*/0x0d/*::]*/: { n: 'TitlesOfParts', t: VT_VECTOR_LPSTR /* VT_VECTOR | VT_LPSTR */ },
|
||||
/*::[*/0x0e/*::]*/: { n: 'Manager', t: VT_STRING },
|
||||
/*::[*/0x0f/*::]*/: { n: 'Company', t: VT_STRING },
|
||||
/*::[*/0x10/*::]*/: { n: 'LinksUpToDate', t: VT_BOOL },
|
||||
/*::[*/0x11/*::]*/: { n: 'CharacterCount', t: VT_I4 },
|
||||
/*::[*/0x13/*::]*/: { n: 'SharedDoc', t: VT_BOOL },
|
||||
/*::[*/0x16/*::]*/: { n: 'HyperlinksChanged', t: VT_BOOL },
|
||||
/*::[*/0x17/*::]*/: { n: 'AppVersion', t: VT_I4, p: 'version' },
|
||||
/*::[*/0x18/*::]*/: { n: 'DigSig', t: VT_BLOB },
|
||||
/*::[*/0x1A/*::]*/: { n: 'ContentType', t: VT_STRING },
|
||||
/*::[*/0x1B/*::]*/: { n: 'ContentStatus', t: VT_STRING },
|
||||
/*::[*/0x1C/*::]*/: { n: 'Language', t: VT_STRING },
|
||||
/*::[*/0x1D/*::]*/: { n: 'Version', t: VT_STRING },
|
||||
/*::[*/0xFF/*::]*/: {},
|
||||
0x01: { n: 'CodePage', t: VT_I2 },
|
||||
0x02: { n: 'Category', t: VT_STRING },
|
||||
0x03: { n: 'PresentationFormat', t: VT_STRING },
|
||||
0x04: { n: 'ByteCount', t: VT_I4 },
|
||||
0x05: { n: 'LineCount', t: VT_I4 },
|
||||
0x06: { n: 'ParagraphCount', t: VT_I4 },
|
||||
0x07: { n: 'SlideCount', t: VT_I4 },
|
||||
0x08: { n: 'NoteCount', t: VT_I4 },
|
||||
0x09: { n: 'HiddenCount', t: VT_I4 },
|
||||
0x0a: { n: 'MultimediaClipCount', t: VT_I4 },
|
||||
0x0b: { n: 'ScaleCrop', t: VT_BOOL },
|
||||
0x0c: { n: 'HeadingPairs', t: VT_VECTOR_VARIANT /* VT_VECTOR | VT_VARIANT */ },
|
||||
0x0d: { n: 'TitlesOfParts', t: VT_VECTOR_LPSTR /* VT_VECTOR | VT_LPSTR */ },
|
||||
0x0e: { n: 'Manager', t: VT_STRING },
|
||||
0x0f: { n: 'Company', t: VT_STRING },
|
||||
0x10: { n: 'LinksUpToDate', t: VT_BOOL },
|
||||
0x11: { n: 'CharacterCount', t: VT_I4 },
|
||||
0x13: { n: 'SharedDoc', t: VT_BOOL },
|
||||
0x16: { n: 'HyperlinksChanged', t: VT_BOOL },
|
||||
0x17: { n: 'AppVersion', t: VT_I4, p: 'version' },
|
||||
0x18: { n: 'DigSig', t: VT_BLOB },
|
||||
0x1A: { n: 'ContentType', t: VT_STRING },
|
||||
0x1B: { n: 'ContentStatus', t: VT_STRING },
|
||||
0x1C: { n: 'Language', t: VT_STRING },
|
||||
0x1D: { n: 'Version', t: VT_STRING },
|
||||
0xFF: {},
|
||||
/* [MS-OLEPS] 2.18 */
|
||||
/*::[*/0x80000000/*::]*/: { n: 'Locale', t: VT_UI4 },
|
||||
/*::[*/0x80000003/*::]*/: { n: 'Behavior', t: VT_UI4 },
|
||||
/*::[*/0x72627262/*::]*/: {}
|
||||
0x80000000: { n: 'Locale', t: VT_UI4 },
|
||||
0x80000003: { n: 'Behavior', t: VT_UI4 },
|
||||
0x72627262: {}
|
||||
};
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.2.1.1 Summary Information Property Set PIDSI */
|
||||
var SummaryPIDSI = {
|
||||
/*::[*/0x01/*::]*/: { n: 'CodePage', t: VT_I2 },
|
||||
/*::[*/0x02/*::]*/: { n: 'Title', t: VT_STRING },
|
||||
/*::[*/0x03/*::]*/: { n: 'Subject', t: VT_STRING },
|
||||
/*::[*/0x04/*::]*/: { n: 'Author', t: VT_STRING },
|
||||
/*::[*/0x05/*::]*/: { n: 'Keywords', t: VT_STRING },
|
||||
/*::[*/0x06/*::]*/: { n: 'Comments', t: VT_STRING },
|
||||
/*::[*/0x07/*::]*/: { n: 'Template', t: VT_STRING },
|
||||
/*::[*/0x08/*::]*/: { n: 'LastAuthor', t: VT_STRING },
|
||||
/*::[*/0x09/*::]*/: { n: 'RevNumber', t: VT_STRING },
|
||||
/*::[*/0x0A/*::]*/: { n: 'EditTime', t: VT_FILETIME },
|
||||
/*::[*/0x0B/*::]*/: { n: 'LastPrinted', t: VT_FILETIME },
|
||||
/*::[*/0x0C/*::]*/: { n: 'CreatedDate', t: VT_FILETIME },
|
||||
/*::[*/0x0D/*::]*/: { n: 'ModifiedDate', t: VT_FILETIME },
|
||||
/*::[*/0x0E/*::]*/: { n: 'PageCount', t: VT_I4 },
|
||||
/*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 },
|
||||
/*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 },
|
||||
/*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF },
|
||||
/*::[*/0x12/*::]*/: { n: 'Application', t: VT_STRING },
|
||||
/*::[*/0x13/*::]*/: { n: 'DocSecurity', t: VT_I4 },
|
||||
/*::[*/0xFF/*::]*/: {},
|
||||
0x01: { n: 'CodePage', t: VT_I2 },
|
||||
0x02: { n: 'Title', t: VT_STRING },
|
||||
0x03: { n: 'Subject', t: VT_STRING },
|
||||
0x04: { n: 'Author', t: VT_STRING },
|
||||
0x05: { n: 'Keywords', t: VT_STRING },
|
||||
0x06: { n: 'Comments', t: VT_STRING },
|
||||
0x07: { n: 'Template', t: VT_STRING },
|
||||
0x08: { n: 'LastAuthor', t: VT_STRING },
|
||||
0x09: { n: 'RevNumber', t: VT_STRING },
|
||||
0x0A: { n: 'EditTime', t: VT_FILETIME },
|
||||
0x0B: { n: 'LastPrinted', t: VT_FILETIME },
|
||||
0x0C: { n: 'CreatedDate', t: VT_FILETIME },
|
||||
0x0D: { n: 'ModifiedDate', t: VT_FILETIME },
|
||||
0x0E: { n: 'PageCount', t: VT_I4 },
|
||||
0x0F: { n: 'WordCount', t: VT_I4 },
|
||||
0x10: { n: 'CharCount', t: VT_I4 },
|
||||
0x11: { n: 'Thumbnail', t: VT_CF },
|
||||
0x12: { n: 'Application', t: VT_STRING },
|
||||
0x13: { n: 'DocSecurity', t: VT_I4 },
|
||||
0xFF: {},
|
||||
/* [MS-OLEPS] 2.18 */
|
||||
/*::[*/0x80000000/*::]*/: { n: 'Locale', t: VT_UI4 },
|
||||
/*::[*/0x80000003/*::]*/: { n: 'Behavior', t: VT_UI4 },
|
||||
/*::[*/0x72627262/*::]*/: {}
|
||||
0x80000000: { n: 'Locale', t: VT_UI4 },
|
||||
0x80000003: { n: 'Behavior', t: VT_UI4 },
|
||||
0x72627262: {}
|
||||
};
|
||||
|
||||
/* [MS-XLS] 2.4.63 Country/Region codes */
|
||||
var CountryEnum = {
|
||||
/*::[*/0x0001/*::]*/: "US", // United States
|
||||
/*::[*/0x0002/*::]*/: "CA", // Canada
|
||||
/*::[*/0x0003/*::]*/: "", // Latin America (except Brazil)
|
||||
/*::[*/0x0007/*::]*/: "RU", // Russia
|
||||
/*::[*/0x0014/*::]*/: "EG", // Egypt
|
||||
/*::[*/0x001E/*::]*/: "GR", // Greece
|
||||
/*::[*/0x001F/*::]*/: "NL", // Netherlands
|
||||
/*::[*/0x0020/*::]*/: "BE", // Belgium
|
||||
/*::[*/0x0021/*::]*/: "FR", // France
|
||||
/*::[*/0x0022/*::]*/: "ES", // Spain
|
||||
/*::[*/0x0024/*::]*/: "HU", // Hungary
|
||||
/*::[*/0x0027/*::]*/: "IT", // Italy
|
||||
/*::[*/0x0029/*::]*/: "CH", // Switzerland
|
||||
/*::[*/0x002B/*::]*/: "AT", // Austria
|
||||
/*::[*/0x002C/*::]*/: "GB", // United Kingdom
|
||||
/*::[*/0x002D/*::]*/: "DK", // Denmark
|
||||
/*::[*/0x002E/*::]*/: "SE", // Sweden
|
||||
/*::[*/0x002F/*::]*/: "NO", // Norway
|
||||
/*::[*/0x0030/*::]*/: "PL", // Poland
|
||||
/*::[*/0x0031/*::]*/: "DE", // Germany
|
||||
/*::[*/0x0034/*::]*/: "MX", // Mexico
|
||||
/*::[*/0x0037/*::]*/: "BR", // Brazil
|
||||
/*::[*/0x003d/*::]*/: "AU", // Australia
|
||||
/*::[*/0x0040/*::]*/: "NZ", // New Zealand
|
||||
/*::[*/0x0042/*::]*/: "TH", // Thailand
|
||||
/*::[*/0x0051/*::]*/: "JP", // Japan
|
||||
/*::[*/0x0052/*::]*/: "KR", // Korea
|
||||
/*::[*/0x0054/*::]*/: "VN", // Viet Nam
|
||||
/*::[*/0x0056/*::]*/: "CN", // China
|
||||
/*::[*/0x005A/*::]*/: "TR", // Turkey
|
||||
/*::[*/0x0069/*::]*/: "JS", // Ramastan
|
||||
/*::[*/0x00D5/*::]*/: "DZ", // Algeria
|
||||
/*::[*/0x00D8/*::]*/: "MA", // Morocco
|
||||
/*::[*/0x00DA/*::]*/: "LY", // Libya
|
||||
/*::[*/0x015F/*::]*/: "PT", // Portugal
|
||||
/*::[*/0x0162/*::]*/: "IS", // Iceland
|
||||
/*::[*/0x0166/*::]*/: "FI", // Finland
|
||||
/*::[*/0x01A4/*::]*/: "CZ", // Czech Republic
|
||||
/*::[*/0x0376/*::]*/: "TW", // Taiwan
|
||||
/*::[*/0x03C1/*::]*/: "LB", // Lebanon
|
||||
/*::[*/0x03C2/*::]*/: "JO", // Jordan
|
||||
/*::[*/0x03C3/*::]*/: "SY", // Syria
|
||||
/*::[*/0x03C4/*::]*/: "IQ", // Iraq
|
||||
/*::[*/0x03C5/*::]*/: "KW", // Kuwait
|
||||
/*::[*/0x03C6/*::]*/: "SA", // Saudi Arabia
|
||||
/*::[*/0x03CB/*::]*/: "AE", // United Arab Emirates
|
||||
/*::[*/0x03CC/*::]*/: "IL", // Israel
|
||||
/*::[*/0x03CE/*::]*/: "QA", // Qatar
|
||||
/*::[*/0x03D5/*::]*/: "IR", // Iran
|
||||
/*::[*/0xFFFF/*::]*/: "US" // United States
|
||||
0x0001: "US", // United States
|
||||
0x0002: "CA", // Canada
|
||||
0x0003: "", // Latin America (except Brazil)
|
||||
0x0007: "RU", // Russia
|
||||
0x0014: "EG", // Egypt
|
||||
0x001E: "GR", // Greece
|
||||
0x001F: "NL", // Netherlands
|
||||
0x0020: "BE", // Belgium
|
||||
0x0021: "FR", // France
|
||||
0x0022: "ES", // Spain
|
||||
0x0024: "HU", // Hungary
|
||||
0x0027: "IT", // Italy
|
||||
0x0029: "CH", // Switzerland
|
||||
0x002B: "AT", // Austria
|
||||
0x002C: "GB", // United Kingdom
|
||||
0x002D: "DK", // Denmark
|
||||
0x002E: "SE", // Sweden
|
||||
0x002F: "NO", // Norway
|
||||
0x0030: "PL", // Poland
|
||||
0x0031: "DE", // Germany
|
||||
0x0034: "MX", // Mexico
|
||||
0x0037: "BR", // Brazil
|
||||
0x003d: "AU", // Australia
|
||||
0x0040: "NZ", // New Zealand
|
||||
0x0042: "TH", // Thailand
|
||||
0x0051: "JP", // Japan
|
||||
0x0052: "KR", // Korea
|
||||
0x0054: "VN", // Viet Nam
|
||||
0x0056: "CN", // China
|
||||
0x005A: "TR", // Turkey
|
||||
0x0069: "JS", // Ramastan
|
||||
0x00D5: "DZ", // Algeria
|
||||
0x00D8: "MA", // Morocco
|
||||
0x00DA: "LY", // Libya
|
||||
0x015F: "PT", // Portugal
|
||||
0x0162: "IS", // Iceland
|
||||
0x0166: "FI", // Finland
|
||||
0x01A4: "CZ", // Czech Republic
|
||||
0x0376: "TW", // Taiwan
|
||||
0x03C1: "LB", // Lebanon
|
||||
0x03C2: "JO", // Jordan
|
||||
0x03C3: "SY", // Syria
|
||||
0x03C4: "IQ", // Iraq
|
||||
0x03C5: "KW", // Kuwait
|
||||
0x03C6: "SA", // Saudi Arabia
|
||||
0x03CB: "AE", // United Arab Emirates
|
||||
0x03CC: "IL", // Israel
|
||||
0x03CE: "QA", // Qatar
|
||||
0x03D5: "IR", // Iran
|
||||
0xFFFF: "US" // United States
|
||||
};
|
||||
|
||||
/* [MS-XLS] 2.5.127 */
|
||||
@ -281,15 +281,15 @@ var XLSIcv = /*#__PURE__*/dup(_XLSIcv);
|
||||
|
||||
/* [MS-XLSB] 2.5.97.2 */
|
||||
var BErr = {
|
||||
/*::[*/0x00/*::]*/: "#NULL!",
|
||||
/*::[*/0x07/*::]*/: "#DIV/0!",
|
||||
/*::[*/0x0F/*::]*/: "#VALUE!",
|
||||
/*::[*/0x17/*::]*/: "#REF!",
|
||||
/*::[*/0x1D/*::]*/: "#NAME?",
|
||||
/*::[*/0x24/*::]*/: "#NUM!",
|
||||
/*::[*/0x2A/*::]*/: "#N/A",
|
||||
/*::[*/0x2B/*::]*/: "#GETTING_DATA",
|
||||
/*::[*/0xFF/*::]*/: "#WTF?"
|
||||
0x00: "#NULL!",
|
||||
0x07: "#DIV/0!",
|
||||
0x0F: "#VALUE!",
|
||||
0x17: "#REF!",
|
||||
0x1D: "#NAME?",
|
||||
0x24: "#NUM!",
|
||||
0x2A: "#N/A",
|
||||
0x2B: "#GETTING_DATA",
|
||||
0xFF: "#WTF?"
|
||||
};
|
||||
//var RBErr = evert_num(BErr);
|
||||
var RBErr = {
|
||||
|
@ -18,22 +18,12 @@ var CORE_PROPS/*:Array<Array<string> >*/ = [
|
||||
["dcterms:modified", "ModifiedDate", 'date']
|
||||
];
|
||||
|
||||
var CORE_PROPS_REGEX/*:Array<RegExp>*/ = /*#__PURE__*/(function() {
|
||||
var r = new Array(CORE_PROPS.length);
|
||||
for(var i = 0; i < CORE_PROPS.length; ++i) {
|
||||
var f = CORE_PROPS[i];
|
||||
var g = "(?:"+ f[0].slice(0,f[0].indexOf(":")) +":)"+ f[0].slice(f[0].indexOf(":")+1);
|
||||
r[i] = new RegExp("<" + g + "[^>]*>([\\s\\S]*?)<\/" + g + ">");
|
||||
}
|
||||
return r;
|
||||
})();
|
||||
|
||||
function parse_core_props(data) {
|
||||
var p = {};
|
||||
data = utf8read(data);
|
||||
|
||||
for(var i = 0; i < CORE_PROPS.length; ++i) {
|
||||
var f = CORE_PROPS[i], cur = data.match(CORE_PROPS_REGEX[i]);
|
||||
var f = CORE_PROPS[i], cur = str_match_xml(data, f[0]);
|
||||
if(cur != null && cur.length > 0) p[f[1]] = unescapexml(cur[1]);
|
||||
if(f[2] === 'date' && p[f[1]]) p[f[1]] = parseDate(p[f[1]]);
|
||||
}
|
||||
|
@ -71,12 +71,12 @@ function parse_ext_props(data, p, opts) {
|
||||
data = utf8read(data);
|
||||
|
||||
EXT_PROPS.forEach(function(f) {
|
||||
var xml = (data.match(matchtag(f[0]))||[])[1];
|
||||
var xml = (str_match_xml_ns(data, f[0])||[])[1];
|
||||
switch(f[2]) {
|
||||
case "string": if(xml) p[f[1]] = unescapexml(xml); break;
|
||||
case "bool": p[f[1]] = xml === "true"; break;
|
||||
case "raw":
|
||||
var cur = data.match(new RegExp("<" + f[0] + "[^>]*>([\\s\\S]*?)<\/" + f[0] + ">"));
|
||||
var cur = str_match_xml(data, f[0]);
|
||||
if(cur && cur.length > 0) q[f[1]] = cur[1];
|
||||
break;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 15.2.12.2 Custom File Properties Part */
|
||||
var custregex = /<[^>]+>[^<]*/g;
|
||||
var custregex = /<[^<>]+>[^<]*/g;
|
||||
function parse_cust_props(data/*:string*/, opts) {
|
||||
var p = {}, name = "";
|
||||
var m = data.match(custregex);
|
||||
|
@ -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);
|
||||
@ -233,8 +233,8 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
|
||||
switch(blob[blob.l]) {
|
||||
case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break;
|
||||
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
|
||||
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
|
||||
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 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break;
|
||||
case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break;
|
||||
case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break;
|
||||
|
@ -122,25 +122,25 @@ function parse_FtCf(blob) {
|
||||
/* [MS-XLS] 2.5.140 - 2.5.154 and friends */
|
||||
function parse_FtSkip(blob) { blob.l += 2; blob.l += blob.read_shift(2); }
|
||||
var FtTab = {
|
||||
/*::[*/0x00/*::]*/: parse_FtSkip, /* FtEnd */
|
||||
/*::[*/0x04/*::]*/: parse_FtSkip, /* FtMacro */
|
||||
/*::[*/0x05/*::]*/: parse_FtSkip, /* FtButton */
|
||||
/*::[*/0x06/*::]*/: parse_FtSkip, /* FtGmo */
|
||||
/*::[*/0x07/*::]*/: parse_FtCf, /* FtCf */
|
||||
/*::[*/0x08/*::]*/: parse_FtSkip, /* FtPioGrbit */
|
||||
/*::[*/0x09/*::]*/: parse_FtSkip, /* FtPictFmla */
|
||||
/*::[*/0x0A/*::]*/: parse_FtSkip, /* FtCbls */
|
||||
/*::[*/0x0B/*::]*/: parse_FtSkip, /* FtRbo */
|
||||
/*::[*/0x0C/*::]*/: parse_FtSkip, /* FtSbs */
|
||||
/*::[*/0x0D/*::]*/: parse_FtNts, /* FtNts */
|
||||
/*::[*/0x0E/*::]*/: parse_FtSkip, /* FtSbsFmla */
|
||||
/*::[*/0x0F/*::]*/: parse_FtSkip, /* FtGboData */
|
||||
/*::[*/0x10/*::]*/: parse_FtSkip, /* FtEdoData */
|
||||
/*::[*/0x11/*::]*/: parse_FtSkip, /* FtRboData */
|
||||
/*::[*/0x12/*::]*/: parse_FtSkip, /* FtCblsData */
|
||||
/*::[*/0x13/*::]*/: parse_FtSkip, /* FtLbsData */
|
||||
/*::[*/0x14/*::]*/: parse_FtSkip, /* FtCblsFmla */
|
||||
/*::[*/0x15/*::]*/: parse_FtCmo
|
||||
0x00: parse_FtSkip, /* FtEnd */
|
||||
0x04: parse_FtSkip, /* FtMacro */
|
||||
0x05: parse_FtSkip, /* FtButton */
|
||||
0x06: parse_FtSkip, /* FtGmo */
|
||||
0x07: parse_FtCf, /* FtCf */
|
||||
0x08: parse_FtSkip, /* FtPioGrbit */
|
||||
0x09: parse_FtSkip, /* FtPictFmla */
|
||||
0x0A: parse_FtSkip, /* FtCbls */
|
||||
0x0B: parse_FtSkip, /* FtRbo */
|
||||
0x0C: parse_FtSkip, /* FtSbs */
|
||||
0x0D: parse_FtNts, /* FtNts */
|
||||
0x0E: parse_FtSkip, /* FtSbsFmla */
|
||||
0x0F: parse_FtSkip, /* FtGboData */
|
||||
0x10: parse_FtSkip, /* FtEdoData */
|
||||
0x11: parse_FtSkip, /* FtRboData */
|
||||
0x12: parse_FtSkip, /* FtCblsData */
|
||||
0x13: parse_FtSkip, /* FtLbsData */
|
||||
0x14: parse_FtSkip, /* FtCblsFmla */
|
||||
0x15: parse_FtCmo
|
||||
};
|
||||
function parse_FtArray(blob, length/*::, ot*/) {
|
||||
var tgt = blob.l + length;
|
||||
|
169
bits/40_harb.js
169
bits/40_harb.js
@ -2,60 +2,60 @@ var DBF_SUPPORTED_VERSIONS = [0x02, 0x03, 0x30, 0x31, 0x83, 0x8B, 0x8C, 0xF5];
|
||||
var DBF = /*#__PURE__*/(function() {
|
||||
var dbf_codepage_map = {
|
||||
/* Code Pages Supported by Visual FoxPro */
|
||||
/*::[*/0x01/*::]*/: 437, /*::[*/0x02/*::]*/: 850,
|
||||
/*::[*/0x03/*::]*/: 1252, /*::[*/0x04/*::]*/: 10000,
|
||||
/*::[*/0x64/*::]*/: 852, /*::[*/0x65/*::]*/: 866,
|
||||
/*::[*/0x66/*::]*/: 865, /*::[*/0x67/*::]*/: 861,
|
||||
/*::[*/0x68/*::]*/: 895, /*::[*/0x69/*::]*/: 620,
|
||||
/*::[*/0x6A/*::]*/: 737, /*::[*/0x6B/*::]*/: 857,
|
||||
/*::[*/0x78/*::]*/: 950, /*::[*/0x79/*::]*/: 949,
|
||||
/*::[*/0x7A/*::]*/: 936, /*::[*/0x7B/*::]*/: 932,
|
||||
/*::[*/0x7C/*::]*/: 874, /*::[*/0x7D/*::]*/: 1255,
|
||||
/*::[*/0x7E/*::]*/: 1256, /*::[*/0x96/*::]*/: 10007,
|
||||
/*::[*/0x97/*::]*/: 10029, /*::[*/0x98/*::]*/: 10006,
|
||||
/*::[*/0xC8/*::]*/: 1250, /*::[*/0xC9/*::]*/: 1251,
|
||||
/*::[*/0xCA/*::]*/: 1254, /*::[*/0xCB/*::]*/: 1253,
|
||||
0x01: 437, 0x02: 850,
|
||||
0x03: 1252, 0x04: 10000,
|
||||
0x64: 852, 0x65: 866,
|
||||
0x66: 865, 0x67: 861,
|
||||
0x68: 895, 0x69: 620,
|
||||
0x6A: 737, 0x6B: 857,
|
||||
0x78: 950, 0x79: 949,
|
||||
0x7A: 936, 0x7B: 932,
|
||||
0x7C: 874, 0x7D: 1255,
|
||||
0x7E: 1256, 0x96: 10007,
|
||||
0x97: 10029, 0x98: 10006,
|
||||
0xC8: 1250, 0xC9: 1251,
|
||||
0xCA: 1254, 0xCB: 1253,
|
||||
|
||||
/* shapefile DBF extension */
|
||||
/*::[*/0x00/*::]*/: 20127, /*::[*/0x08/*::]*/: 865,
|
||||
/*::[*/0x09/*::]*/: 437, /*::[*/0x0A/*::]*/: 850,
|
||||
/*::[*/0x0B/*::]*/: 437, /*::[*/0x0D/*::]*/: 437,
|
||||
/*::[*/0x0E/*::]*/: 850, /*::[*/0x0F/*::]*/: 437,
|
||||
/*::[*/0x10/*::]*/: 850, /*::[*/0x11/*::]*/: 437,
|
||||
/*::[*/0x12/*::]*/: 850, /*::[*/0x13/*::]*/: 932,
|
||||
/*::[*/0x14/*::]*/: 850, /*::[*/0x15/*::]*/: 437,
|
||||
/*::[*/0x16/*::]*/: 850, /*::[*/0x17/*::]*/: 865,
|
||||
/*::[*/0x18/*::]*/: 437, /*::[*/0x19/*::]*/: 437,
|
||||
/*::[*/0x1A/*::]*/: 850, /*::[*/0x1B/*::]*/: 437,
|
||||
/*::[*/0x1C/*::]*/: 863, /*::[*/0x1D/*::]*/: 850,
|
||||
/*::[*/0x1F/*::]*/: 852, /*::[*/0x22/*::]*/: 852,
|
||||
/*::[*/0x23/*::]*/: 852, /*::[*/0x24/*::]*/: 860,
|
||||
/*::[*/0x25/*::]*/: 850, /*::[*/0x26/*::]*/: 866,
|
||||
/*::[*/0x37/*::]*/: 850, /*::[*/0x40/*::]*/: 852,
|
||||
/*::[*/0x4D/*::]*/: 936, /*::[*/0x4E/*::]*/: 949,
|
||||
/*::[*/0x4F/*::]*/: 950, /*::[*/0x50/*::]*/: 874,
|
||||
/*::[*/0x57/*::]*/: 1252, /*::[*/0x58/*::]*/: 1252,
|
||||
/*::[*/0x59/*::]*/: 1252, /*::[*/0x6C/*::]*/: 863,
|
||||
/*::[*/0x86/*::]*/: 737, /*::[*/0x87/*::]*/: 852,
|
||||
/*::[*/0x88/*::]*/: 857, /*::[*/0xCC/*::]*/: 1257,
|
||||
0x00: 20127, 0x08: 865,
|
||||
0x09: 437, 0x0A: 850,
|
||||
0x0B: 437, 0x0D: 437,
|
||||
0x0E: 850, 0x0F: 437,
|
||||
0x10: 850, 0x11: 437,
|
||||
0x12: 850, 0x13: 932,
|
||||
0x14: 850, 0x15: 437,
|
||||
0x16: 850, 0x17: 865,
|
||||
0x18: 437, 0x19: 437,
|
||||
0x1A: 850, 0x1B: 437,
|
||||
0x1C: 863, 0x1D: 850,
|
||||
0x1F: 852, 0x22: 852,
|
||||
0x23: 852, 0x24: 860,
|
||||
0x25: 850, 0x26: 866,
|
||||
0x37: 850, 0x40: 852,
|
||||
0x4D: 936, 0x4E: 949,
|
||||
0x4F: 950, 0x50: 874,
|
||||
0x57: 1252, 0x58: 1252,
|
||||
0x59: 1252, 0x6C: 863,
|
||||
0x86: 737, 0x87: 852,
|
||||
0x88: 857, 0xCC: 1257,
|
||||
|
||||
/*::[*/0xFF/*::]*/: 16969
|
||||
0xFF: 16969
|
||||
};
|
||||
var dbf_reverse_map = evert({
|
||||
/*::[*/0x01/*::]*/: 437, /*::[*/0x02/*::]*/: 850,
|
||||
/*::[*/0x03/*::]*/: 1252, /*::[*/0x04/*::]*/: 10000,
|
||||
/*::[*/0x64/*::]*/: 852, /*::[*/0x65/*::]*/: 866,
|
||||
/*::[*/0x66/*::]*/: 865, /*::[*/0x67/*::]*/: 861,
|
||||
/*::[*/0x68/*::]*/: 895, /*::[*/0x69/*::]*/: 620,
|
||||
/*::[*/0x6A/*::]*/: 737, /*::[*/0x6B/*::]*/: 857,
|
||||
/*::[*/0x78/*::]*/: 950, /*::[*/0x79/*::]*/: 949,
|
||||
/*::[*/0x7A/*::]*/: 936, /*::[*/0x7B/*::]*/: 932,
|
||||
/*::[*/0x7C/*::]*/: 874, /*::[*/0x7D/*::]*/: 1255,
|
||||
/*::[*/0x7E/*::]*/: 1256, /*::[*/0x96/*::]*/: 10007,
|
||||
/*::[*/0x97/*::]*/: 10029, /*::[*/0x98/*::]*/: 10006,
|
||||
/*::[*/0xC8/*::]*/: 1250, /*::[*/0xC9/*::]*/: 1251,
|
||||
/*::[*/0xCA/*::]*/: 1254, /*::[*/0xCB/*::]*/: 1253,
|
||||
/*::[*/0x00/*::]*/: 20127
|
||||
0x01: 437, 0x02: 850,
|
||||
0x03: 1252, 0x04: 10000,
|
||||
0x64: 852, 0x65: 866,
|
||||
0x66: 865, 0x67: 861,
|
||||
0x68: 895, 0x69: 620,
|
||||
0x6A: 737, 0x6B: 857,
|
||||
0x78: 950, 0x79: 949,
|
||||
0x7A: 936, 0x7B: 932,
|
||||
0x7C: 874, 0x7D: 1255,
|
||||
0x7E: 1256, 0x96: 10007,
|
||||
0x97: 10029, 0x98: 10006,
|
||||
0xC8: 1250, 0xC9: 1251,
|
||||
0xCA: 1254, 0xCB: 1253,
|
||||
0x00: 20127
|
||||
});
|
||||
/* TODO: find an actual specification */
|
||||
function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
||||
@ -118,7 +118,7 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
||||
var ww = l7 ? 32 : 11;
|
||||
while(d.l < hend && d[d.l] != 0x0d) {
|
||||
field = ({}/*:any*/);
|
||||
field.name = (typeof $cptable !== "undefined" ? $cptable.utils.decode(current_cp, d.slice(d.l, d.l+ww)) : a2s(d.slice(d.l, d.l + ww))).replace(/[\u0000\r\n].*$/g,"");
|
||||
field.name = (typeof $cptable !== "undefined" ? $cptable.utils.decode(current_cp, d.slice(d.l, d.l+ww)) : a2s(d.slice(d.l, d.l + ww))).replace(/[\u0000\r\n][\S\s]*$/g,"");
|
||||
d.l += ww;
|
||||
field.type = String.fromCharCode(d.read_shift(1));
|
||||
if(ft != 0x02 && !l7) field.offset = d.read_shift(4);
|
||||
@ -176,7 +176,7 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
|
||||
switch(fields[C].type) {
|
||||
case 'C':
|
||||
// NOTE: it is conventional to write ' / / ' for empty dates
|
||||
if(s.trim().length) out[R][C] = s.replace(/\s+$/,"");
|
||||
if(s.trim().length) out[R][C] = s.replace(/([^\s])\s+$/,"$1");
|
||||
break;
|
||||
case 'D':
|
||||
if(s.length === 8) {
|
||||
@ -404,9 +404,9 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
KC:'Ç', Kc:'ç', q:'æ', z:'œ', a:'Æ', j:'Œ',
|
||||
DN:209, Dn:241, Hy:255,
|
||||
S:169, c:170, R:174, "B ":180,
|
||||
/*::[*/0/*::]*/:176, /*::[*/1/*::]*/:177, /*::[*/2/*::]*/:178,
|
||||
/*::[*/3/*::]*/:179, /*::[*/5/*::]*/:181, /*::[*/6/*::]*/:182,
|
||||
/*::[*/7/*::]*/:183, Q:185, k:186, b:208, i:216, l:222, s:240, y:248,
|
||||
0:176, 1:177, 2:178,
|
||||
3:179, 5:181, 6:182,
|
||||
7:183, Q:185, k:186, b:208, i:216, l:222, s:240, y:248,
|
||||
"!":161, '"':162, "#":163, "(":164, "%":165, "'":167, "H ":168,
|
||||
"+":171, ";":187, "<":188, "=":189, ">":190, "?":191, "{":223
|
||||
}/*:any*/);
|
||||
@ -483,6 +483,7 @@ var SYLK = /*#__PURE__*/(function() {
|
||||
val = record[rj].slice(1);
|
||||
if(val.charAt(0) === '"') { val = val.slice(1,val.length - 1); cell_t = "s"; }
|
||||
else if(val === 'TRUE' || val === 'FALSE') { val = val === 'TRUE'; cell_t = "b"; }
|
||||
else if(val.charAt(0) == "#" && RBErr[val] != null) { cell_t = "e"; val = RBErr[val]; }
|
||||
else if(!isNaN(fuzzynum(val))) {
|
||||
val = fuzzynum(val); cell_t = "n";
|
||||
if(next_cell_format !== null && fmt_is_date(next_cell_format) && opts.cellDates) {
|
||||
@ -592,10 +593,10 @@ 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 || cell.v; break;
|
||||
case 'e': o += cell.w || BErr[cell.v] || cell.v; break;
|
||||
case 'd': o += datenum(parseDate(cell.v, date1904), date1904); break;
|
||||
case 's': o += '"' + (cell.v == null ? "" : String(cell.v)).replace(/"/g,"").replace(/;/g, ";;") + '"'; break;
|
||||
}
|
||||
@ -821,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];
|
||||
}
|
||||
@ -864,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'));
|
||||
@ -878,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(":"));
|
||||
@ -909,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;
|
||||
}
|
||||
|
||||
@ -940,18 +951,18 @@ var PRN = /*#__PURE__*/(function() {
|
||||
|
||||
// List of accepted CSV separators
|
||||
var guess_seps = {
|
||||
/*::[*/0x2C/*::]*/: ',',
|
||||
/*::[*/0x09/*::]*/: "\t",
|
||||
/*::[*/0x3B/*::]*/: ';',
|
||||
/*::[*/0x7C/*::]*/: '|'
|
||||
0x2C: ',',
|
||||
0x09: "\t",
|
||||
0x3B: ';',
|
||||
0x7C: '|'
|
||||
};
|
||||
|
||||
// CSV separator weights to be used in case of equal numbers
|
||||
var guess_sep_weights = {
|
||||
/*::[*/0x2C/*::]*/: 3,
|
||||
/*::[*/0x09/*::]*/: 2,
|
||||
/*::[*/0x3B/*::]*/: 1,
|
||||
/*::[*/0x7C/*::]*/: 0
|
||||
0x2C: 3,
|
||||
0x09: 2,
|
||||
0x3B: 1,
|
||||
0x7C: 0
|
||||
};
|
||||
|
||||
function guess_sep(str) {
|
||||
@ -1026,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;
|
||||
@ -1120,8 +1133,22 @@ function read_wb_ID(d, opts) {
|
||||
return out;
|
||||
} catch(e) {
|
||||
o.WTF = OLD_WTF;
|
||||
if(!e.message.match(/SYLK bad record ID/) && OLD_WTF) throw e;
|
||||
if((e.message.indexOf("SYLK bad record ID") == -1) && OLD_WTF) throw e;
|
||||
return PRN.to_workbook(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);
|
||||
}
|
||||
}
|
||||
|
411
bits/41_lotus.js
411
bits/41_lotus.js
@ -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++];
|
||||
@ -763,68 +762,68 @@ var WK_ = /*#__PURE__*/(function() {
|
||||
}
|
||||
|
||||
var WK1Enum = {
|
||||
/*::[*/0x0000/*::]*/: { n:"BOF", f:parseuint16 },
|
||||
/*::[*/0x0001/*::]*/: { n:"EOF" },
|
||||
/*::[*/0x0002/*::]*/: { n:"CALCMODE" },
|
||||
/*::[*/0x0003/*::]*/: { n:"CALCORDER" },
|
||||
/*::[*/0x0004/*::]*/: { n:"SPLIT" },
|
||||
/*::[*/0x0005/*::]*/: { n:"SYNC" },
|
||||
/*::[*/0x0006/*::]*/: { n:"RANGE", f:parse_RANGE },
|
||||
/*::[*/0x0007/*::]*/: { n:"WINDOW1" },
|
||||
/*::[*/0x0008/*::]*/: { n:"COLW1" },
|
||||
/*::[*/0x0009/*::]*/: { n:"WINTWO" },
|
||||
/*::[*/0x000A/*::]*/: { n:"COLW2" },
|
||||
/*::[*/0x000B/*::]*/: { n:"NAME" },
|
||||
/*::[*/0x000C/*::]*/: { n:"BLANK" },
|
||||
/*::[*/0x000D/*::]*/: { n:"INTEGER", f:parse_INTEGER },
|
||||
/*::[*/0x000E/*::]*/: { n:"NUMBER", f:parse_NUMBER },
|
||||
/*::[*/0x000F/*::]*/: { n:"LABEL", f:parse_LABEL },
|
||||
/*::[*/0x0010/*::]*/: { n:"FORMULA", f:parse_FORMULA },
|
||||
/*::[*/0x0018/*::]*/: { n:"TABLE" },
|
||||
/*::[*/0x0019/*::]*/: { n:"ORANGE" },
|
||||
/*::[*/0x001A/*::]*/: { n:"PRANGE" },
|
||||
/*::[*/0x001B/*::]*/: { n:"SRANGE" },
|
||||
/*::[*/0x001C/*::]*/: { n:"FRANGE" },
|
||||
/*::[*/0x001D/*::]*/: { n:"KRANGE1" },
|
||||
/*::[*/0x0020/*::]*/: { n:"HRANGE" },
|
||||
/*::[*/0x0023/*::]*/: { n:"KRANGE2" },
|
||||
/*::[*/0x0024/*::]*/: { n:"PROTEC" },
|
||||
/*::[*/0x0025/*::]*/: { n:"FOOTER" },
|
||||
/*::[*/0x0026/*::]*/: { n:"HEADER" },
|
||||
/*::[*/0x0027/*::]*/: { n:"SETUP" },
|
||||
/*::[*/0x0028/*::]*/: { n:"MARGINS" },
|
||||
/*::[*/0x0029/*::]*/: { n:"LABELFMT" },
|
||||
/*::[*/0x002A/*::]*/: { n:"TITLES" },
|
||||
/*::[*/0x002B/*::]*/: { n:"SHEETJS" },
|
||||
/*::[*/0x002D/*::]*/: { n:"GRAPH" },
|
||||
/*::[*/0x002E/*::]*/: { n:"NGRAPH" },
|
||||
/*::[*/0x002F/*::]*/: { n:"CALCCOUNT" },
|
||||
/*::[*/0x0030/*::]*/: { n:"UNFORMATTED" },
|
||||
/*::[*/0x0031/*::]*/: { n:"CURSORW12" },
|
||||
/*::[*/0x0032/*::]*/: { n:"WINDOW" },
|
||||
/*::[*/0x0033/*::]*/: { n:"STRING", f:parse_STRING },
|
||||
/*::[*/0x0037/*::]*/: { n:"PASSWORD" },
|
||||
/*::[*/0x0038/*::]*/: { n:"LOCKED" },
|
||||
/*::[*/0x003C/*::]*/: { n:"QUERY" },
|
||||
/*::[*/0x003D/*::]*/: { n:"QUERYNAME" },
|
||||
/*::[*/0x003E/*::]*/: { n:"PRINT" },
|
||||
/*::[*/0x003F/*::]*/: { n:"PRINTNAME" },
|
||||
/*::[*/0x0040/*::]*/: { n:"GRAPH2" },
|
||||
/*::[*/0x0041/*::]*/: { n:"GRAPHNAME" },
|
||||
/*::[*/0x0042/*::]*/: { n:"ZOOM" },
|
||||
/*::[*/0x0043/*::]*/: { n:"SYMSPLIT" },
|
||||
/*::[*/0x0044/*::]*/: { n:"NSROWS" },
|
||||
/*::[*/0x0045/*::]*/: { n:"NSCOLS" },
|
||||
/*::[*/0x0046/*::]*/: { n:"RULER" },
|
||||
/*::[*/0x0047/*::]*/: { n:"NNAME" },
|
||||
/*::[*/0x0048/*::]*/: { n:"ACOMM" },
|
||||
/*::[*/0x0049/*::]*/: { n:"AMACRO" },
|
||||
/*::[*/0x004A/*::]*/: { n:"PARSE" },
|
||||
0x0000: { n:"BOF", f:parseuint16 },
|
||||
0x0001: { n:"EOF" },
|
||||
0x0002: { n:"CALCMODE" },
|
||||
0x0003: { n:"CALCORDER" },
|
||||
0x0004: { n:"SPLIT" },
|
||||
0x0005: { n:"SYNC" },
|
||||
0x0006: { n:"RANGE", f:parse_RANGE },
|
||||
0x0007: { n:"WINDOW1" },
|
||||
0x0008: { n:"COLW1" },
|
||||
0x0009: { n:"WINTWO" },
|
||||
0x000A: { n:"COLW2" },
|
||||
0x000B: { n:"NAME" },
|
||||
0x000C: { n:"BLANK" },
|
||||
0x000D: { n:"INTEGER", f:parse_INTEGER },
|
||||
0x000E: { n:"NUMBER", f:parse_NUMBER },
|
||||
0x000F: { n:"LABEL", f:parse_LABEL },
|
||||
0x0010: { n:"FORMULA", f:parse_FORMULA },
|
||||
0x0018: { n:"TABLE" },
|
||||
0x0019: { n:"ORANGE" },
|
||||
0x001A: { n:"PRANGE" },
|
||||
0x001B: { n:"SRANGE" },
|
||||
0x001C: { n:"FRANGE" },
|
||||
0x001D: { n:"KRANGE1" },
|
||||
0x0020: { n:"HRANGE" },
|
||||
0x0023: { n:"KRANGE2" },
|
||||
0x0024: { n:"PROTEC" },
|
||||
0x0025: { n:"FOOTER" },
|
||||
0x0026: { n:"HEADER" },
|
||||
0x0027: { n:"SETUP" },
|
||||
0x0028: { n:"MARGINS" },
|
||||
0x0029: { n:"LABELFMT" },
|
||||
0x002A: { n:"TITLES" },
|
||||
0x002B: { n:"SHEETJS" },
|
||||
0x002D: { n:"GRAPH" },
|
||||
0x002E: { n:"NGRAPH" },
|
||||
0x002F: { n:"CALCCOUNT" },
|
||||
0x0030: { n:"UNFORMATTED" },
|
||||
0x0031: { n:"CURSORW12" },
|
||||
0x0032: { n:"WINDOW" },
|
||||
0x0033: { n:"STRING", f:parse_STRING },
|
||||
0x0037: { n:"PASSWORD" },
|
||||
0x0038: { n:"LOCKED" },
|
||||
0x003C: { n:"QUERY" },
|
||||
0x003D: { n:"QUERYNAME" },
|
||||
0x003E: { n:"PRINT" },
|
||||
0x003F: { n:"PRINTNAME" },
|
||||
0x0040: { n:"GRAPH2" },
|
||||
0x0041: { n:"GRAPHNAME" },
|
||||
0x0042: { n:"ZOOM" },
|
||||
0x0043: { n:"SYMSPLIT" },
|
||||
0x0044: { n:"NSROWS" },
|
||||
0x0045: { n:"NSCOLS" },
|
||||
0x0046: { n:"RULER" },
|
||||
0x0047: { n:"NNAME" },
|
||||
0x0048: { n:"ACOMM" },
|
||||
0x0049: { n:"AMACRO" },
|
||||
0x004A: { n:"PARSE" },
|
||||
// 0x0064
|
||||
/*::[*/0x0066/*::]*/: { n:"PRANGES??" },
|
||||
/*::[*/0x0067/*::]*/: { n:"RRANGES??" },
|
||||
/*::[*/0x0068/*::]*/: { n:"FNAME??" },
|
||||
/*::[*/0x0069/*::]*/: { n:"MRANGES??" },
|
||||
0x0066: { n:"PRANGES??" },
|
||||
0x0067: { n:"RRANGES??" },
|
||||
0x0068: { n:"FNAME??" },
|
||||
0x0069: { n:"MRANGES??" },
|
||||
// 0x0096
|
||||
// 0x0099
|
||||
// 0x009A
|
||||
@ -833,160 +832,160 @@ var WK_ = /*#__PURE__*/(function() {
|
||||
// 0x00C0
|
||||
// 0x00C7
|
||||
// 0x00C9
|
||||
/*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
|
||||
0x00CC: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
|
||||
// 0x00CD
|
||||
/*::[*/0x00DE/*::]*/: { n:"SHEETNAMELP", f:parse_SHEETNAMELP },
|
||||
/*::[*/0x00FF/*::]*/: { n:"BOF", f:parseuint16 },
|
||||
/*::[*/0x5402/*::]*/: { n:"WKSNF", f:parseuint16 },
|
||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||
0x00DE: { n:"SHEETNAMELP", f:parse_SHEETNAMELP },
|
||||
0x00FF: { n:"BOF", f:parseuint16 },
|
||||
0x5402: { n:"WKSNF", f:parseuint16 },
|
||||
0xFFFF: { n:"" }
|
||||
};
|
||||
|
||||
var WK3Enum = {
|
||||
/*::[*/0x0000/*::]*/: { n:"BOF" },
|
||||
/*::[*/0x0001/*::]*/: { n:"EOF" },
|
||||
/*::[*/0x0002/*::]*/: { n:"PASSWORD" },
|
||||
/*::[*/0x0003/*::]*/: { n:"CALCSET" },
|
||||
/*::[*/0x0004/*::]*/: { n:"WINDOWSET" },
|
||||
/*::[*/0x0005/*::]*/: { n:"SHEETCELLPTR" },
|
||||
/*::[*/0x0006/*::]*/: { n:"SHEETLAYOUT" },
|
||||
/*::[*/0x0007/*::]*/: { n:"COLUMNWIDTH" },
|
||||
/*::[*/0x0008/*::]*/: { n:"HIDDENCOLUMN" },
|
||||
/*::[*/0x0009/*::]*/: { n:"USERRANGE" },
|
||||
/*::[*/0x000A/*::]*/: { n:"SYSTEMRANGE" },
|
||||
/*::[*/0x000B/*::]*/: { n:"ZEROFORCE" },
|
||||
/*::[*/0x000C/*::]*/: { n:"SORTKEYDIR" },
|
||||
/*::[*/0x000D/*::]*/: { n:"FILESEAL" },
|
||||
/*::[*/0x000E/*::]*/: { n:"DATAFILLNUMS" },
|
||||
/*::[*/0x000F/*::]*/: { n:"PRINTMAIN" },
|
||||
/*::[*/0x0010/*::]*/: { n:"PRINTSTRING" },
|
||||
/*::[*/0x0011/*::]*/: { n:"GRAPHMAIN" },
|
||||
/*::[*/0x0012/*::]*/: { n:"GRAPHSTRING" },
|
||||
/*::[*/0x0013/*::]*/: { n:"??" },
|
||||
/*::[*/0x0014/*::]*/: { n:"ERRCELL" },
|
||||
/*::[*/0x0015/*::]*/: { n:"NACELL" },
|
||||
/*::[*/0x0016/*::]*/: { n:"LABEL16", f:parse_LABEL_16},
|
||||
/*::[*/0x0017/*::]*/: { n:"NUMBER17", f:parse_NUMBER_17 },
|
||||
/*::[*/0x0018/*::]*/: { n:"NUMBER18", f:parse_NUMBER_18 },
|
||||
/*::[*/0x0019/*::]*/: { n:"FORMULA19", f:parse_FORMULA_19},
|
||||
/*::[*/0x001A/*::]*/: { n:"FORMULA1A" },
|
||||
/*::[*/0x001B/*::]*/: { n:"XFORMAT", f:parse_XFORMAT },
|
||||
/*::[*/0x001C/*::]*/: { n:"DTLABELMISC" },
|
||||
/*::[*/0x001D/*::]*/: { n:"DTLABELCELL" },
|
||||
/*::[*/0x001E/*::]*/: { n:"GRAPHWINDOW" },
|
||||
/*::[*/0x001F/*::]*/: { n:"CPA" },
|
||||
/*::[*/0x0020/*::]*/: { n:"LPLAUTO" },
|
||||
/*::[*/0x0021/*::]*/: { n:"QUERY" },
|
||||
/*::[*/0x0022/*::]*/: { n:"HIDDENSHEET" },
|
||||
/*::[*/0x0023/*::]*/: { n:"??" },
|
||||
/*::[*/0x0025/*::]*/: { n:"NUMBER25", f:parse_NUMBER_25 },
|
||||
/*::[*/0x0026/*::]*/: { n:"??" },
|
||||
/*::[*/0x0027/*::]*/: { n:"NUMBER27", f:parse_NUMBER_27 },
|
||||
/*::[*/0x0028/*::]*/: { n:"FORMULA28", f:parse_FORMULA_28 },
|
||||
/*::[*/0x008E/*::]*/: { n:"??" },
|
||||
/*::[*/0x0093/*::]*/: { n:"??" },
|
||||
/*::[*/0x0096/*::]*/: { n:"??" },
|
||||
/*::[*/0x0097/*::]*/: { n:"??" },
|
||||
/*::[*/0x0098/*::]*/: { n:"??" },
|
||||
/*::[*/0x0099/*::]*/: { n:"??" },
|
||||
/*::[*/0x009A/*::]*/: { n:"??" },
|
||||
/*::[*/0x009B/*::]*/: { n:"??" },
|
||||
/*::[*/0x009C/*::]*/: { n:"??" },
|
||||
/*::[*/0x00A3/*::]*/: { n:"??" },
|
||||
/*::[*/0x00AE/*::]*/: { n:"??" },
|
||||
/*::[*/0x00AF/*::]*/: { n:"??" },
|
||||
/*::[*/0x00B0/*::]*/: { n:"??" },
|
||||
/*::[*/0x00B1/*::]*/: { n:"??" },
|
||||
/*::[*/0x00B8/*::]*/: { n:"??" },
|
||||
/*::[*/0x00B9/*::]*/: { n:"??" },
|
||||
/*::[*/0x00BA/*::]*/: { n:"??" },
|
||||
/*::[*/0x00BB/*::]*/: { n:"??" },
|
||||
/*::[*/0x00BC/*::]*/: { n:"??" },
|
||||
/*::[*/0x00C3/*::]*/: { n:"??" },
|
||||
/*::[*/0x00C9/*::]*/: { n:"??" },
|
||||
/*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
|
||||
/*::[*/0x00CD/*::]*/: { n:"??" },
|
||||
/*::[*/0x00CE/*::]*/: { n:"??" },
|
||||
/*::[*/0x00CF/*::]*/: { n:"??" },
|
||||
/*::[*/0x00D0/*::]*/: { n:"??" },
|
||||
/*::[*/0x0100/*::]*/: { n:"??" },
|
||||
/*::[*/0x0103/*::]*/: { n:"??" },
|
||||
/*::[*/0x0104/*::]*/: { n:"??" },
|
||||
/*::[*/0x0105/*::]*/: { n:"??" },
|
||||
/*::[*/0x0106/*::]*/: { n:"??" },
|
||||
/*::[*/0x0107/*::]*/: { n:"??" },
|
||||
/*::[*/0x0109/*::]*/: { n:"??" },
|
||||
/*::[*/0x010A/*::]*/: { n:"??" },
|
||||
/*::[*/0x010B/*::]*/: { n:"??" },
|
||||
/*::[*/0x010C/*::]*/: { n:"??" },
|
||||
/*::[*/0x010E/*::]*/: { n:"??" },
|
||||
/*::[*/0x010F/*::]*/: { n:"??" },
|
||||
/*::[*/0x0180/*::]*/: { n:"??" },
|
||||
/*::[*/0x0185/*::]*/: { n:"??" },
|
||||
/*::[*/0x0186/*::]*/: { n:"??" },
|
||||
/*::[*/0x0189/*::]*/: { n:"??" },
|
||||
/*::[*/0x018C/*::]*/: { n:"??" },
|
||||
/*::[*/0x0200/*::]*/: { n:"??" },
|
||||
/*::[*/0x0202/*::]*/: { n:"??" },
|
||||
/*::[*/0x0201/*::]*/: { n:"??" },
|
||||
/*::[*/0x0204/*::]*/: { n:"??" },
|
||||
/*::[*/0x0205/*::]*/: { n:"??" },
|
||||
/*::[*/0x0280/*::]*/: { n:"??" },
|
||||
/*::[*/0x0281/*::]*/: { n:"??" },
|
||||
/*::[*/0x0282/*::]*/: { n:"??" },
|
||||
/*::[*/0x0283/*::]*/: { n:"??" },
|
||||
/*::[*/0x0284/*::]*/: { n:"??" },
|
||||
/*::[*/0x0285/*::]*/: { n:"??" },
|
||||
/*::[*/0x0286/*::]*/: { n:"??" },
|
||||
/*::[*/0x0287/*::]*/: { n:"??" },
|
||||
/*::[*/0x0288/*::]*/: { n:"??" },
|
||||
/*::[*/0x0292/*::]*/: { n:"??" },
|
||||
/*::[*/0x0293/*::]*/: { n:"??" },
|
||||
/*::[*/0x0294/*::]*/: { n:"??" },
|
||||
/*::[*/0x0295/*::]*/: { n:"??" },
|
||||
/*::[*/0x0296/*::]*/: { n:"??" },
|
||||
/*::[*/0x0299/*::]*/: { n:"??" },
|
||||
/*::[*/0x029A/*::]*/: { n:"??" },
|
||||
/*::[*/0x0300/*::]*/: { n:"??" },
|
||||
/*::[*/0x0304/*::]*/: { n:"??" },
|
||||
/*::[*/0x0601/*::]*/: { n:"SHEETINFOQP", f:parse_SHEETINFOQP },
|
||||
/*::[*/0x0640/*::]*/: { n:"??" },
|
||||
/*::[*/0x0642/*::]*/: { n:"??" },
|
||||
/*::[*/0x0701/*::]*/: { n:"??" },
|
||||
/*::[*/0x0702/*::]*/: { n:"??" },
|
||||
/*::[*/0x0703/*::]*/: { n:"??" },
|
||||
/*::[*/0x0704/*::]*/: { n:"??" },
|
||||
/*::[*/0x0780/*::]*/: { n:"??" },
|
||||
/*::[*/0x0800/*::]*/: { n:"??" },
|
||||
/*::[*/0x0801/*::]*/: { n:"??" },
|
||||
/*::[*/0x0804/*::]*/: { n:"??" },
|
||||
/*::[*/0x0A80/*::]*/: { n:"??" },
|
||||
/*::[*/0x2AF6/*::]*/: { n:"??" },
|
||||
/*::[*/0x3231/*::]*/: { n:"??" },
|
||||
/*::[*/0x6E49/*::]*/: { n:"??" },
|
||||
/*::[*/0x6F44/*::]*/: { n:"??" },
|
||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||
0x0000: { n:"BOF" },
|
||||
0x0001: { n:"EOF" },
|
||||
0x0002: { n:"PASSWORD" },
|
||||
0x0003: { n:"CALCSET" },
|
||||
0x0004: { n:"WINDOWSET" },
|
||||
0x0005: { n:"SHEETCELLPTR" },
|
||||
0x0006: { n:"SHEETLAYOUT" },
|
||||
0x0007: { n:"COLUMNWIDTH" },
|
||||
0x0008: { n:"HIDDENCOLUMN" },
|
||||
0x0009: { n:"USERRANGE" },
|
||||
0x000A: { n:"SYSTEMRANGE" },
|
||||
0x000B: { n:"ZEROFORCE" },
|
||||
0x000C: { n:"SORTKEYDIR" },
|
||||
0x000D: { n:"FILESEAL" },
|
||||
0x000E: { n:"DATAFILLNUMS" },
|
||||
0x000F: { n:"PRINTMAIN" },
|
||||
0x0010: { n:"PRINTSTRING" },
|
||||
0x0011: { n:"GRAPHMAIN" },
|
||||
0x0012: { n:"GRAPHSTRING" },
|
||||
0x0013: { n:"??" },
|
||||
0x0014: { n:"ERRCELL" },
|
||||
0x0015: { n:"NACELL" },
|
||||
0x0016: { n:"LABEL16", f:parse_LABEL_16},
|
||||
0x0017: { n:"NUMBER17", f:parse_NUMBER_17 },
|
||||
0x0018: { n:"NUMBER18", f:parse_NUMBER_18 },
|
||||
0x0019: { n:"FORMULA19", f:parse_FORMULA_19},
|
||||
0x001A: { n:"FORMULA1A" },
|
||||
0x001B: { n:"XFORMAT", f:parse_XFORMAT },
|
||||
0x001C: { n:"DTLABELMISC" },
|
||||
0x001D: { n:"DTLABELCELL" },
|
||||
0x001E: { n:"GRAPHWINDOW" },
|
||||
0x001F: { n:"CPA" },
|
||||
0x0020: { n:"LPLAUTO" },
|
||||
0x0021: { n:"QUERY" },
|
||||
0x0022: { n:"HIDDENSHEET" },
|
||||
0x0023: { n:"??" },
|
||||
0x0025: { n:"NUMBER25", f:parse_NUMBER_25 },
|
||||
0x0026: { n:"??" },
|
||||
0x0027: { n:"NUMBER27", f:parse_NUMBER_27 },
|
||||
0x0028: { n:"FORMULA28", f:parse_FORMULA_28 },
|
||||
0x008E: { n:"??" },
|
||||
0x0093: { n:"??" },
|
||||
0x0096: { n:"??" },
|
||||
0x0097: { n:"??" },
|
||||
0x0098: { n:"??" },
|
||||
0x0099: { n:"??" },
|
||||
0x009A: { n:"??" },
|
||||
0x009B: { n:"??" },
|
||||
0x009C: { n:"??" },
|
||||
0x00A3: { n:"??" },
|
||||
0x00AE: { n:"??" },
|
||||
0x00AF: { n:"??" },
|
||||
0x00B0: { n:"??" },
|
||||
0x00B1: { n:"??" },
|
||||
0x00B8: { n:"??" },
|
||||
0x00B9: { n:"??" },
|
||||
0x00BA: { n:"??" },
|
||||
0x00BB: { n:"??" },
|
||||
0x00BC: { n:"??" },
|
||||
0x00C3: { n:"??" },
|
||||
0x00C9: { n:"??" },
|
||||
0x00CC: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
|
||||
0x00CD: { n:"??" },
|
||||
0x00CE: { n:"??" },
|
||||
0x00CF: { n:"??" },
|
||||
0x00D0: { n:"??" },
|
||||
0x0100: { n:"??" },
|
||||
0x0103: { n:"??" },
|
||||
0x0104: { n:"??" },
|
||||
0x0105: { n:"??" },
|
||||
0x0106: { n:"??" },
|
||||
0x0107: { n:"??" },
|
||||
0x0109: { n:"??" },
|
||||
0x010A: { n:"??" },
|
||||
0x010B: { n:"??" },
|
||||
0x010C: { n:"??" },
|
||||
0x010E: { n:"??" },
|
||||
0x010F: { n:"??" },
|
||||
0x0180: { n:"??" },
|
||||
0x0185: { n:"??" },
|
||||
0x0186: { n:"??" },
|
||||
0x0189: { n:"??" },
|
||||
0x018C: { n:"??" },
|
||||
0x0200: { n:"??" },
|
||||
0x0202: { n:"??" },
|
||||
0x0201: { n:"??" },
|
||||
0x0204: { n:"??" },
|
||||
0x0205: { n:"??" },
|
||||
0x0280: { n:"??" },
|
||||
0x0281: { n:"??" },
|
||||
0x0282: { n:"??" },
|
||||
0x0283: { n:"??" },
|
||||
0x0284: { n:"??" },
|
||||
0x0285: { n:"??" },
|
||||
0x0286: { n:"??" },
|
||||
0x0287: { n:"??" },
|
||||
0x0288: { n:"??" },
|
||||
0x0292: { n:"??" },
|
||||
0x0293: { n:"??" },
|
||||
0x0294: { n:"??" },
|
||||
0x0295: { n:"??" },
|
||||
0x0296: { n:"??" },
|
||||
0x0299: { n:"??" },
|
||||
0x029A: { n:"??" },
|
||||
0x0300: { n:"??" },
|
||||
0x0304: { n:"??" },
|
||||
0x0601: { n:"SHEETINFOQP", f:parse_SHEETINFOQP },
|
||||
0x0640: { n:"??" },
|
||||
0x0642: { n:"??" },
|
||||
0x0701: { n:"??" },
|
||||
0x0702: { n:"??" },
|
||||
0x0703: { n:"??" },
|
||||
0x0704: { n:"??" },
|
||||
0x0780: { n:"??" },
|
||||
0x0800: { n:"??" },
|
||||
0x0801: { n:"??" },
|
||||
0x0804: { n:"??" },
|
||||
0x0A80: { n:"??" },
|
||||
0x2AF6: { n:"??" },
|
||||
0x3231: { n:"??" },
|
||||
0x6E49: { n:"??" },
|
||||
0x6F44: { n:"??" },
|
||||
0xFFFF: { n:"" }
|
||||
};
|
||||
|
||||
/* TODO: fill out and verify this table across QP versions */
|
||||
var QPWNFTable = {
|
||||
/*::[*/0x05/*::*/: "dd-mmm-yy",
|
||||
/*::[*/0x06/*::*/: "dd-mmm",
|
||||
/*::[*/0x07/*::*/: "mmm-yy",
|
||||
/*::[*/0x08/*::*/: "mm/dd/yy", // Long Date Intl
|
||||
/*::[*/0x0A/*::*/: "hh:mm:ss AM/PM",
|
||||
/*::[*/0x0B/*::*/: "hh:mm AM/PM",
|
||||
/*::[*/0x0E/*::*/: "dd-mmm-yyyy",
|
||||
/*::[*/0x0F/*::*/: "mmm-yyyy",
|
||||
0x05: "dd-mmm-yy",
|
||||
0x06: "dd-mmm",
|
||||
0x07: "mmm-yy",
|
||||
0x08: "mm/dd/yy", // Long Date Intl
|
||||
0x0A: "hh:mm:ss AM/PM",
|
||||
0x0B: "hh:mm AM/PM",
|
||||
0x0E: "dd-mmm-yyyy",
|
||||
0x0F: "mmm-yyyy",
|
||||
|
||||
/* It is suspected that the the low nybble specifies decimal places */
|
||||
/*::[*/0x0022/*::*/: "0.00",
|
||||
/*::[*/0x0032/*::*/: "0.00;[Red]0.00",
|
||||
/*::[*/0x0042/*::*/: "0.00;\(0.00\)",
|
||||
/*::[*/0x0052/*::*/: "0.00;[Red]\(0.00\)",
|
||||
/*::[*/0x00A2/*::*/: '"$"#,##0.00;\\("$"#,##0.00\\)',
|
||||
/*::[*/0x0120/*::*/: '0%',
|
||||
/*::[*/0x0130/*::*/: '0E+00',
|
||||
/*::[*/0x0140/*::*/: '# ?/?'
|
||||
0x0022: "0.00",
|
||||
0x0032: "0.00;[Red]0.00",
|
||||
0x0042: "0.00;\(0.00\)",
|
||||
0x0052: "0.00;[Red]\(0.00\)",
|
||||
0x00A2: '"$"#,##0.00;\\("$"#,##0.00\\)',
|
||||
0x0120: '0%',
|
||||
0x0130: '0E+00',
|
||||
0x0140: '# ?/?'
|
||||
};
|
||||
|
||||
function parse_qpw_str(p) {
|
||||
|
@ -4,7 +4,7 @@ function parse_rpr(rpr) {
|
||||
var pass = false;
|
||||
if(m) for(;i!=m.length; ++i) {
|
||||
var y = parsexmltag(m[i]);
|
||||
switch(y[0].replace(/\w*:/g,"")) {
|
||||
switch(y[0].replace(/<\w*:/g,"<")) {
|
||||
/* 18.8.12 condense CT_BooleanProperty */
|
||||
/* ** not required . */
|
||||
case '<condense': break;
|
||||
@ -107,15 +107,14 @@ function parse_rpr(rpr) {
|
||||
}
|
||||
|
||||
var parse_rs = /*#__PURE__*/(function() {
|
||||
var tregex = matchtag("t"), rpregex = matchtag("rPr");
|
||||
/* 18.4.4 r CT_RElt */
|
||||
function parse_r(r) {
|
||||
/* 18.4.12 t ST_Xstring */
|
||||
var t = r.match(tregex)/*, cp = 65001*/;
|
||||
var t = str_match_xml_ns(r, "t")/*, cp = 65001*/;
|
||||
if(!t) return {t:"s", v:""};
|
||||
|
||||
var o/*:Cell*/ = ({t:'s', v:unescapexml(t[1])}/*:any*/);
|
||||
var rpr = r.match(rpregex);
|
||||
var rpr = str_match_xml_ns(r, "rPr");
|
||||
if(rpr) o.s = parse_rpr(rpr[1]);
|
||||
return o;
|
||||
}
|
||||
@ -168,8 +167,7 @@ var rs_to_html = /*#__PURE__*/(function parse_rs_factory() {
|
||||
})();
|
||||
|
||||
/* 18.4.8 si CT_Rst */
|
||||
var sitregex = /<(?:\w+:)?t[^>]*>([^<]*)<\/(?:\w+:)?t>/g, sirregex = /<(?:\w+:)?r\b[^>]*>/;
|
||||
var sirphregex = /<(?:\w+:)?rPh.*?>([\s\S]*?)<\/(?:\w+:)?rPh>/g;
|
||||
var sitregex = /<(?:\w+:)?t\b[^<>]*>([^<]*)<\/(?:\w+:)?t>/g, sirregex = /<(?:\w+:)?r\b[^<>]*>/;
|
||||
function parse_si(x, opts) {
|
||||
var html = opts ? opts.cellHTML : true;
|
||||
var z = {};
|
||||
@ -185,7 +183,7 @@ function parse_si(x, opts) {
|
||||
/* 18.4.4 r CT_RElt (Rich Text Run) */
|
||||
else if((/*y = */x.match(sirregex))) {
|
||||
z.r = utf8read(x);
|
||||
z.t = unescapexml(utf8read((x.replace(sirphregex, '').match(sitregex)||[]).join("").replace(tagregex,"")), true);
|
||||
z.t = unescapexml(utf8read((str_remove_xml_ns_g(x, "rPh").match(sitregex)||[]).join("").replace(tagregex,"")), true);
|
||||
if(html) z.h = rs_to_html(parse_rs(z.r));
|
||||
}
|
||||
/* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
|
||||
@ -194,21 +192,20 @@ function parse_si(x, opts) {
|
||||
}
|
||||
|
||||
/* 18.4 Shared String Table */
|
||||
var sstr0 = /<(?:\w+:)?sst([^>]*)>([\s\S]*)<\/(?:\w+:)?sst>/;
|
||||
var sstr1 = /<(?:\w+:)?(?:si|sstItem)>/g;
|
||||
var sstr2 = /<\/(?:\w+:)?(?:si|sstItem)>/;
|
||||
function parse_sst_xml(data/*:string*/, opts)/*:SST*/ {
|
||||
var s/*:SST*/ = ([]/*:any*/), ss = "";
|
||||
if(!data) return s;
|
||||
/* 18.4.9 sst CT_Sst */
|
||||
var sst = data.match(sstr0);
|
||||
var sst = str_match_xml_ns(data, "sst");
|
||||
if(sst) {
|
||||
ss = sst[2].replace(sstr1,"").split(sstr2);
|
||||
ss = sst[1].replace(sstr1,"").split(sstr2);
|
||||
for(var i = 0; i != ss.length; ++i) {
|
||||
var o = parse_si(ss[i].trim(), opts);
|
||||
if(o != null) s[s.length] = o;
|
||||
}
|
||||
sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount;
|
||||
sst = parsexmltag(sst[0].slice(0, sst[0].indexOf(">"))); s.Count = sst.count; s.Unique = sst.uniqueCount;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ function rtf_to_sheet_str(str, opts) {
|
||||
var dense = o.dense;
|
||||
if (dense)
|
||||
ws["!data"] = [];
|
||||
var rows = str.match(/\\trowd[\s\S]*?\\row\b/g);
|
||||
var rows = str_match_ng(str, "\\trowd", "\\row");
|
||||
if (!rows)
|
||||
throw new Error("RTF missing table");
|
||||
var range = { s: { c: 0, r: 0 }, e: { c: 0, r: rows.length - 1 } };
|
||||
@ -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;
|
||||
|
@ -3,7 +3,7 @@ function parse_borders(t, styles, themes, opts) {
|
||||
styles.Borders = [];
|
||||
var border = {};
|
||||
var pass = false;
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
(t.match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<borders': case '<borders>': case '</borders>': break;
|
||||
@ -78,7 +78,7 @@ function parse_fills(t, styles, themes, opts) {
|
||||
styles.Fills = [];
|
||||
var fill = {};
|
||||
var pass = false;
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
(t.match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<fills': case '<fills>': case '</fills>': break;
|
||||
@ -144,7 +144,7 @@ function parse_fonts(t, styles, themes, opts) {
|
||||
styles.Fonts = [];
|
||||
var font = {};
|
||||
var pass = false;
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
(t.match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<fonts': case '<fonts>': case '</fonts>': break;
|
||||
@ -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;
|
||||
@ -264,7 +273,7 @@ function parse_numFmts(t, styles, opts) {
|
||||
styles.NumberFmt = [];
|
||||
var k/*Array<number>*/ = (keys(table_fmt)/*:any*/);
|
||||
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = table_fmt[k[i]];
|
||||
var m = t[0].match(tagregex);
|
||||
var m = t.match(tagregex);
|
||||
if(!m) return;
|
||||
for(i=0; i < m.length; ++i) {
|
||||
var y = parsexmltag(m[i]);
|
||||
@ -305,7 +314,7 @@ function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
var xf;
|
||||
var pass = false;
|
||||
(t[0].match(tagregex)||[]).forEach(function(x) {
|
||||
(t.match(tagregex)||[]).forEach(function(x) {
|
||||
var y = parsexmltag(x), i = 0;
|
||||
switch(strip_ns(y[0])) {
|
||||
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
|
||||
@ -370,36 +379,31 @@ function write_cellXfs(cellXfs)/*:string*/ {
|
||||
|
||||
/* 18.8 Styles CT_Stylesheet*/
|
||||
var parse_sty_xml= /*#__PURE__*/(function make_pstyx() {
|
||||
var numFmtRegex = /<(?:\w+:)?numFmts([^>]*)>[\S\s]*?<\/(?:\w+:)?numFmts>/;
|
||||
var cellXfRegex = /<(?:\w+:)?cellXfs([^>]*)>[\S\s]*?<\/(?:\w+:)?cellXfs>/;
|
||||
var fillsRegex = /<(?:\w+:)?fills([^>]*)>[\S\s]*?<\/(?:\w+:)?fills>/;
|
||||
var fontsRegex = /<(?:\w+:)?fonts([^>]*)>[\S\s]*?<\/(?:\w+:)?fonts>/;
|
||||
var bordersRegex = /<(?:\w+:)?borders([^>]*)>[\S\s]*?<\/(?:\w+:)?borders>/;
|
||||
|
||||
return function parse_sty_xml(data, themes, opts) {
|
||||
var styles = {};
|
||||
if(!data) return styles;
|
||||
data = data.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
||||
data = remove_doctype(str_remove_ng(data, "<!--", "-->"));
|
||||
/* 18.8.39 styleSheet CT_Stylesheet */
|
||||
var t;
|
||||
|
||||
/* 18.8.31 numFmts CT_NumFmts ? */
|
||||
if((t=data.match(numFmtRegex))) parse_numFmts(t, styles, opts);
|
||||
if((t=str_match_xml_ns(data, "numFmts"))) parse_numFmts(t[0], styles, opts);
|
||||
|
||||
/* 18.8.23 fonts CT_Fonts ? */
|
||||
if((t=data.match(fontsRegex))) parse_fonts(t, styles, themes, opts);
|
||||
if((t=str_match_xml_ns(data, "fonts"))) parse_fonts(t[0], styles, themes, opts);
|
||||
|
||||
/* 18.8.21 fills CT_Fills ? */
|
||||
if((t=data.match(fillsRegex))) parse_fills(t, styles, themes, opts);
|
||||
if((t=str_match_xml_ns(data, "fills"))) parse_fills(t[0], styles, themes, opts);
|
||||
|
||||
/* 18.8.5 borders CT_Borders ? */
|
||||
if((t=data.match(bordersRegex))) parse_borders(t, styles, themes, opts);
|
||||
if((t=str_match_xml_ns(data, "borders"))) parse_borders(t[0], styles, themes, opts);
|
||||
|
||||
/* 18.8.9 cellStyleXfs CT_CellStyleXfs ? */
|
||||
/* 18.8.8 cellStyles CT_CellStyles ? */
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs ? */
|
||||
if((t=data.match(cellXfRegex))) parse_cellXfs(t, styles, opts);
|
||||
if((t=str_match_xml_ns(data, "cellXfs"))) parse_cellXfs(t[0], styles, opts);
|
||||
|
||||
/* 18.8.15 dxfs CT_Dxfs ? */
|
||||
/* 18.8.42 tableStyles CT_TableStyles ? */
|
||||
|
@ -18,10 +18,12 @@ function parse_clrScheme(t, themes, opts) {
|
||||
/* 20.1.2.3.32 srgbClr CT_SRgbColor */
|
||||
case '<a:srgbClr':
|
||||
color.rgb = y.val; break;
|
||||
case '</a:srgbClr>': break;
|
||||
|
||||
/* 20.1.2.3.33 sysClr CT_SystemColor */
|
||||
case '<a:sysClr':
|
||||
color.rgb = y.lastClr; break;
|
||||
case '</a:sysClr>': break;
|
||||
|
||||
/* 20.1.4.1.1 accent1 (Accent 1) */
|
||||
/* 20.1.4.1.2 accent2 (Accent 2) */
|
||||
@ -35,8 +37,10 @@ function parse_clrScheme(t, themes, opts) {
|
||||
/* 20.1.4.1.19 hlink (Hyperlink) */
|
||||
/* 20.1.4.1.22 lt1 (Light 1) */
|
||||
/* 20.1.4.1.23 lt2 (Light 2) */
|
||||
case '<a:dk1>': case '</a:dk1>':
|
||||
case '<a:lt1>': case '</a:lt1>':
|
||||
case '</a:dk1>':
|
||||
case '</a:lt1>':
|
||||
case '<a:dk1>':
|
||||
case '<a:lt1>':
|
||||
case '<a:dk2>': case '</a:dk2>':
|
||||
case '<a:lt2>': case '</a:lt2>':
|
||||
case '<a:accent1>': case '</a:accent1>':
|
||||
@ -66,30 +70,24 @@ function parse_fontScheme(/*::t, themes, opts*/) { }
|
||||
/* 20.1.4.1.15 fmtScheme CT_StyleMatrix */
|
||||
function parse_fmtScheme(/*::t, themes, opts*/) { }
|
||||
|
||||
var clrsregex = /<a:clrScheme([^>]*)>[\s\S]*<\/a:clrScheme>/;
|
||||
var fntsregex = /<a:fontScheme([^>]*)>[\s\S]*<\/a:fontScheme>/;
|
||||
var fmtsregex = /<a:fmtScheme([^>]*)>[\s\S]*<\/a:fmtScheme>/;
|
||||
|
||||
/* 20.1.6.10 themeElements CT_BaseStyles */
|
||||
function parse_themeElements(data, themes, opts) {
|
||||
themes.themeElements = {};
|
||||
|
||||
var t;
|
||||
|
||||
[
|
||||
/* clrScheme CT_ColorScheme */
|
||||
['clrScheme', clrsregex, parse_clrScheme],
|
||||
/* fontScheme CT_FontScheme */
|
||||
['fontScheme', fntsregex, parse_fontScheme],
|
||||
/* fmtScheme CT_StyleMatrix */
|
||||
['fmtScheme', fmtsregex, parse_fmtScheme]
|
||||
].forEach(function(m) {
|
||||
if(!(t=data.match(m[1]))) throw new Error(m[0] + ' not found in themeElements');
|
||||
m[2](t, themes, opts);
|
||||
});
|
||||
}
|
||||
/* clrScheme CT_ColorScheme */
|
||||
if(!(t=str_match_xml(data, "a:clrScheme"))) throw new Error('clrScheme not found in themeElements');
|
||||
parse_clrScheme(t, themes, opts);
|
||||
|
||||
var themeltregex = /<a:themeElements([^>]*)>[\s\S]*<\/a:themeElements>/;
|
||||
/* fontScheme CT_FontScheme */
|
||||
if(!(t=str_match_xml(data, "a:fontScheme"))) throw new Error('fontScheme not found in themeElements');
|
||||
parse_fontScheme(t, themes, opts);
|
||||
|
||||
/* fmtScheme CT_StyleMatrix */
|
||||
if(!(t=str_match_xml(data, "a:fmtScheme"))) throw new Error('fmtScheme not found in themeElements');
|
||||
parse_fmtScheme(t, themes, opts);
|
||||
}
|
||||
|
||||
/* 14.2.7 Theme Part */
|
||||
function parse_theme_xml(data/*:string*/, opts) {
|
||||
@ -100,7 +98,7 @@ function parse_theme_xml(data/*:string*/, opts) {
|
||||
var themes = {};
|
||||
|
||||
/* themeElements CT_BaseStyles */
|
||||
if(!(t=data.match(themeltregex))) throw new Error('themeElements not found in theme');
|
||||
if(!(t=str_match_xml(data, "a:themeElements"))) throw new Error('themeElements not found in theme');
|
||||
parse_themeElements(t[0], themes, opts);
|
||||
themes.raw = data;
|
||||
return themes;
|
||||
|
@ -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' */
|
||||
|
@ -13,7 +13,7 @@ function parse_drawing(data, rels/*:any*/) {
|
||||
the actual type is based on the URI of the graphicData
|
||||
TODO: handle embedded charts and other types of graphics
|
||||
*/
|
||||
var id = (data.match(/<c:chart [^>]*r:id="([^"]*)"/)||["",""])[1];
|
||||
var id = (data.match(/<c:chart [^<>]*r:id="([^<>"]*)"/)||["",""])[1];
|
||||
|
||||
return rels['!id'][id].Target;
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
/* L.5.5.2 SpreadsheetML Comments + VML Schema */
|
||||
var shapevmlregex = /<(?:\w+:)?shape(?:[^\w][^>]*)?>([\s\S]*?)<\/(?:\w+:)?shape>/g;
|
||||
function parse_vml(data/*:string*/, sheet, comments) {
|
||||
var cidx = 0;
|
||||
(data.match(shapevmlregex)||[]).forEach(function(m) {
|
||||
(str_match_xml_ns_g(data, "shape")||[]).forEach(function(m) {
|
||||
var type = "";
|
||||
var hidden = true;
|
||||
var aidx = -1;
|
||||
|
@ -4,22 +4,22 @@ function parse_comments_xml(data/*:string*/, opts)/*:Array<RawComment>*/ {
|
||||
if(data.match(/<(?:\w+:)?comments *\/>/)) return [];
|
||||
var authors/*:Array<string>*/ = [];
|
||||
var commentList/*:Array<RawComment>*/ = [];
|
||||
var authtag = data.match(/<(?:\w+:)?authors>([\s\S]*)<\/(?:\w+:)?authors>/);
|
||||
var authtag = str_match_xml_ns(data, "authors");
|
||||
if(authtag && authtag[1]) authtag[1].split(/<\/\w*:?author>/).forEach(function(x) {
|
||||
if(x === "" || x.trim() === "") return;
|
||||
var a = x.match(/<(?:\w+:)?author[^>]*>(.*)/);
|
||||
var a = x.match(/<(?:\w+:)?author[^<>]*>(.*)/);
|
||||
if(a) authors.push(a[1]);
|
||||
});
|
||||
var cmnttag = data.match(/<(?:\w+:)?commentList>([\s\S]*)<\/(?:\w+:)?commentList>/);
|
||||
var cmnttag = str_match_xml_ns(data, "commentList");
|
||||
if(cmnttag && cmnttag[1]) cmnttag[1].split(/<\/\w*:?comment>/).forEach(function(x) {
|
||||
if(x === "" || x.trim() === "") return;
|
||||
var cm = x.match(/<(?:\w+:)?comment[^>]*>/);
|
||||
var cm = x.match(/<(?:\w+:)?comment[^<>]*>/);
|
||||
if(!cm) return;
|
||||
var y = parsexmltag(cm[0]);
|
||||
var comment/*:RawComment*/ = ({ author: y.authorId && authors[y.authorId] || "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
|
||||
var cell = decode_cell(y.ref);
|
||||
if(opts.sheetRows && opts.sheetRows <= cell.r) return;
|
||||
var textMatch = x.match(/<(?:\w+:)?text>([\s\S]*)<\/(?:\w+:)?text>/);
|
||||
var textMatch = str_match_xml_ns(x, "text");
|
||||
var rt = !!textMatch && !!textMatch[1] && parse_si(textMatch[1]) || {r:"",t:"",h:""};
|
||||
comment.r = rt.r;
|
||||
if(rt.r == "<t></t>") rt.t = rt.h = "";
|
||||
|
@ -13,7 +13,7 @@ function fill_vba_xls(cfb, vba) {
|
||||
vba.FullPaths.forEach(function(p, i) {
|
||||
if (i == 0)
|
||||
return;
|
||||
var newpath = p.replace(/[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
|
||||
var newpath = p.replace(/^[\/]*[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
|
||||
if (newpath.slice(-1) !== "/")
|
||||
CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
|
||||
});
|
||||
|
196
bits/62_fxls.js
196
bits/62_fxls.js
@ -495,112 +495,112 @@ function parse_PtgAttrNoop(blob/*::, length, opts*/) {
|
||||
|
||||
/* [MS-XLS] 2.5.198.25 ; [MS-XLSB] 2.5.97.16 */
|
||||
var PtgTypes = {
|
||||
/*::[*/0x01/*::]*/: { n:'PtgExp', f:parse_PtgExp },
|
||||
/*::[*/0x02/*::]*/: { n:'PtgTbl', f:parse_PtgTbl },
|
||||
/*::[*/0x03/*::]*/: { n:'PtgAdd', f:parseread1 },
|
||||
/*::[*/0x04/*::]*/: { n:'PtgSub', f:parseread1 },
|
||||
/*::[*/0x05/*::]*/: { n:'PtgMul', f:parseread1 },
|
||||
/*::[*/0x06/*::]*/: { n:'PtgDiv', f:parseread1 },
|
||||
/*::[*/0x07/*::]*/: { n:'PtgPower', f:parseread1 },
|
||||
/*::[*/0x08/*::]*/: { n:'PtgConcat', f:parseread1 },
|
||||
/*::[*/0x09/*::]*/: { n:'PtgLt', f:parseread1 },
|
||||
/*::[*/0x0A/*::]*/: { n:'PtgLe', f:parseread1 },
|
||||
/*::[*/0x0B/*::]*/: { n:'PtgEq', f:parseread1 },
|
||||
/*::[*/0x0C/*::]*/: { n:'PtgGe', f:parseread1 },
|
||||
/*::[*/0x0D/*::]*/: { n:'PtgGt', f:parseread1 },
|
||||
/*::[*/0x0E/*::]*/: { n:'PtgNe', f:parseread1 },
|
||||
/*::[*/0x0F/*::]*/: { n:'PtgIsect', f:parseread1 },
|
||||
/*::[*/0x10/*::]*/: { n:'PtgUnion', f:parseread1 },
|
||||
/*::[*/0x11/*::]*/: { n:'PtgRange', f:parseread1 },
|
||||
/*::[*/0x12/*::]*/: { n:'PtgUplus', f:parseread1 },
|
||||
/*::[*/0x13/*::]*/: { n:'PtgUminus', f:parseread1 },
|
||||
/*::[*/0x14/*::]*/: { n:'PtgPercent', f:parseread1 },
|
||||
/*::[*/0x15/*::]*/: { n:'PtgParen', f:parseread1 },
|
||||
/*::[*/0x16/*::]*/: { n:'PtgMissArg', f:parseread1 },
|
||||
/*::[*/0x17/*::]*/: { n:'PtgStr', f:parse_PtgStr },
|
||||
/*::[*/0x1A/*::]*/: { n:'PtgSheet', f:parse_PtgSheet },
|
||||
/*::[*/0x1B/*::]*/: { n:'PtgEndSheet', f:parse_PtgEndSheet },
|
||||
/*::[*/0x1C/*::]*/: { n:'PtgErr', f:parse_PtgErr },
|
||||
/*::[*/0x1D/*::]*/: { n:'PtgBool', f:parse_PtgBool },
|
||||
/*::[*/0x1E/*::]*/: { n:'PtgInt', f:parse_PtgInt },
|
||||
/*::[*/0x1F/*::]*/: { n:'PtgNum', f:parse_PtgNum },
|
||||
/*::[*/0x20/*::]*/: { n:'PtgArray', f:parse_PtgArray },
|
||||
/*::[*/0x21/*::]*/: { n:'PtgFunc', f:parse_PtgFunc },
|
||||
/*::[*/0x22/*::]*/: { n:'PtgFuncVar', f:parse_PtgFuncVar },
|
||||
/*::[*/0x23/*::]*/: { n:'PtgName', f:parse_PtgName },
|
||||
/*::[*/0x24/*::]*/: { n:'PtgRef', f:parse_PtgRef },
|
||||
/*::[*/0x25/*::]*/: { n:'PtgArea', f:parse_PtgArea },
|
||||
/*::[*/0x26/*::]*/: { n:'PtgMemArea', f:parse_PtgMemArea },
|
||||
/*::[*/0x27/*::]*/: { n:'PtgMemErr', f:parse_PtgMemErr },
|
||||
/*::[*/0x28/*::]*/: { n:'PtgMemNoMem', f:parse_PtgMemNoMem },
|
||||
/*::[*/0x29/*::]*/: { n:'PtgMemFunc', f:parse_PtgMemFunc },
|
||||
/*::[*/0x2A/*::]*/: { n:'PtgRefErr', f:parse_PtgRefErr },
|
||||
/*::[*/0x2B/*::]*/: { n:'PtgAreaErr', f:parse_PtgAreaErr },
|
||||
/*::[*/0x2C/*::]*/: { n:'PtgRefN', f:parse_PtgRefN },
|
||||
/*::[*/0x2D/*::]*/: { n:'PtgAreaN', f:parse_PtgAreaN },
|
||||
/*::[*/0x2E/*::]*/: { n:'PtgMemAreaN', f:parse_PtgMemAreaN },
|
||||
/*::[*/0x2F/*::]*/: { n:'PtgMemNoMemN', f:parse_PtgMemNoMemN },
|
||||
/*::[*/0x39/*::]*/: { n:'PtgNameX', f:parse_PtgNameX },
|
||||
/*::[*/0x3A/*::]*/: { n:'PtgRef3d', f:parse_PtgRef3d },
|
||||
/*::[*/0x3B/*::]*/: { n:'PtgArea3d', f:parse_PtgArea3d },
|
||||
/*::[*/0x3C/*::]*/: { n:'PtgRefErr3d', f:parse_PtgRefErr3d },
|
||||
/*::[*/0x3D/*::]*/: { n:'PtgAreaErr3d', f:parse_PtgAreaErr3d },
|
||||
/*::[*/0xFF/*::]*/: {}
|
||||
0x01: { n:'PtgExp', f:parse_PtgExp },
|
||||
0x02: { n:'PtgTbl', f:parse_PtgTbl },
|
||||
0x03: { n:'PtgAdd', f:parseread1 },
|
||||
0x04: { n:'PtgSub', f:parseread1 },
|
||||
0x05: { n:'PtgMul', f:parseread1 },
|
||||
0x06: { n:'PtgDiv', f:parseread1 },
|
||||
0x07: { n:'PtgPower', f:parseread1 },
|
||||
0x08: { n:'PtgConcat', f:parseread1 },
|
||||
0x09: { n:'PtgLt', f:parseread1 },
|
||||
0x0A: { n:'PtgLe', f:parseread1 },
|
||||
0x0B: { n:'PtgEq', f:parseread1 },
|
||||
0x0C: { n:'PtgGe', f:parseread1 },
|
||||
0x0D: { n:'PtgGt', f:parseread1 },
|
||||
0x0E: { n:'PtgNe', f:parseread1 },
|
||||
0x0F: { n:'PtgIsect', f:parseread1 },
|
||||
0x10: { n:'PtgUnion', f:parseread1 },
|
||||
0x11: { n:'PtgRange', f:parseread1 },
|
||||
0x12: { n:'PtgUplus', f:parseread1 },
|
||||
0x13: { n:'PtgUminus', f:parseread1 },
|
||||
0x14: { n:'PtgPercent', f:parseread1 },
|
||||
0x15: { n:'PtgParen', f:parseread1 },
|
||||
0x16: { n:'PtgMissArg', f:parseread1 },
|
||||
0x17: { n:'PtgStr', f:parse_PtgStr },
|
||||
0x1A: { n:'PtgSheet', f:parse_PtgSheet },
|
||||
0x1B: { n:'PtgEndSheet', f:parse_PtgEndSheet },
|
||||
0x1C: { n:'PtgErr', f:parse_PtgErr },
|
||||
0x1D: { n:'PtgBool', f:parse_PtgBool },
|
||||
0x1E: { n:'PtgInt', f:parse_PtgInt },
|
||||
0x1F: { n:'PtgNum', f:parse_PtgNum },
|
||||
0x20: { n:'PtgArray', f:parse_PtgArray },
|
||||
0x21: { n:'PtgFunc', f:parse_PtgFunc },
|
||||
0x22: { n:'PtgFuncVar', f:parse_PtgFuncVar },
|
||||
0x23: { n:'PtgName', f:parse_PtgName },
|
||||
0x24: { n:'PtgRef', f:parse_PtgRef },
|
||||
0x25: { n:'PtgArea', f:parse_PtgArea },
|
||||
0x26: { n:'PtgMemArea', f:parse_PtgMemArea },
|
||||
0x27: { n:'PtgMemErr', f:parse_PtgMemErr },
|
||||
0x28: { n:'PtgMemNoMem', f:parse_PtgMemNoMem },
|
||||
0x29: { n:'PtgMemFunc', f:parse_PtgMemFunc },
|
||||
0x2A: { n:'PtgRefErr', f:parse_PtgRefErr },
|
||||
0x2B: { n:'PtgAreaErr', f:parse_PtgAreaErr },
|
||||
0x2C: { n:'PtgRefN', f:parse_PtgRefN },
|
||||
0x2D: { n:'PtgAreaN', f:parse_PtgAreaN },
|
||||
0x2E: { n:'PtgMemAreaN', f:parse_PtgMemAreaN },
|
||||
0x2F: { n:'PtgMemNoMemN', f:parse_PtgMemNoMemN },
|
||||
0x39: { n:'PtgNameX', f:parse_PtgNameX },
|
||||
0x3A: { n:'PtgRef3d', f:parse_PtgRef3d },
|
||||
0x3B: { n:'PtgArea3d', f:parse_PtgArea3d },
|
||||
0x3C: { n:'PtgRefErr3d', f:parse_PtgRefErr3d },
|
||||
0x3D: { n:'PtgAreaErr3d', f:parse_PtgAreaErr3d },
|
||||
0xFF: {}
|
||||
};
|
||||
/* These are duplicated in the PtgTypes table */
|
||||
var PtgDupes = {
|
||||
/*::[*/0x40/*::]*/: 0x20, /*::[*/0x60/*::]*/: 0x20,
|
||||
/*::[*/0x41/*::]*/: 0x21, /*::[*/0x61/*::]*/: 0x21,
|
||||
/*::[*/0x42/*::]*/: 0x22, /*::[*/0x62/*::]*/: 0x22,
|
||||
/*::[*/0x43/*::]*/: 0x23, /*::[*/0x63/*::]*/: 0x23,
|
||||
/*::[*/0x44/*::]*/: 0x24, /*::[*/0x64/*::]*/: 0x24,
|
||||
/*::[*/0x45/*::]*/: 0x25, /*::[*/0x65/*::]*/: 0x25,
|
||||
/*::[*/0x46/*::]*/: 0x26, /*::[*/0x66/*::]*/: 0x26,
|
||||
/*::[*/0x47/*::]*/: 0x27, /*::[*/0x67/*::]*/: 0x27,
|
||||
/*::[*/0x48/*::]*/: 0x28, /*::[*/0x68/*::]*/: 0x28,
|
||||
/*::[*/0x49/*::]*/: 0x29, /*::[*/0x69/*::]*/: 0x29,
|
||||
/*::[*/0x4A/*::]*/: 0x2A, /*::[*/0x6A/*::]*/: 0x2A,
|
||||
/*::[*/0x4B/*::]*/: 0x2B, /*::[*/0x6B/*::]*/: 0x2B,
|
||||
/*::[*/0x4C/*::]*/: 0x2C, /*::[*/0x6C/*::]*/: 0x2C,
|
||||
/*::[*/0x4D/*::]*/: 0x2D, /*::[*/0x6D/*::]*/: 0x2D,
|
||||
/*::[*/0x4E/*::]*/: 0x2E, /*::[*/0x6E/*::]*/: 0x2E,
|
||||
/*::[*/0x4F/*::]*/: 0x2F, /*::[*/0x6F/*::]*/: 0x2F,
|
||||
/*::[*/0x58/*::]*/: 0x22, /*::[*/0x78/*::]*/: 0x22,
|
||||
/*::[*/0x59/*::]*/: 0x39, /*::[*/0x79/*::]*/: 0x39,
|
||||
/*::[*/0x5A/*::]*/: 0x3A, /*::[*/0x7A/*::]*/: 0x3A,
|
||||
/*::[*/0x5B/*::]*/: 0x3B, /*::[*/0x7B/*::]*/: 0x3B,
|
||||
/*::[*/0x5C/*::]*/: 0x3C, /*::[*/0x7C/*::]*/: 0x3C,
|
||||
/*::[*/0x5D/*::]*/: 0x3D, /*::[*/0x7D/*::]*/: 0x3D
|
||||
0x40: 0x20, 0x60: 0x20,
|
||||
0x41: 0x21, 0x61: 0x21,
|
||||
0x42: 0x22, 0x62: 0x22,
|
||||
0x43: 0x23, 0x63: 0x23,
|
||||
0x44: 0x24, 0x64: 0x24,
|
||||
0x45: 0x25, 0x65: 0x25,
|
||||
0x46: 0x26, 0x66: 0x26,
|
||||
0x47: 0x27, 0x67: 0x27,
|
||||
0x48: 0x28, 0x68: 0x28,
|
||||
0x49: 0x29, 0x69: 0x29,
|
||||
0x4A: 0x2A, 0x6A: 0x2A,
|
||||
0x4B: 0x2B, 0x6B: 0x2B,
|
||||
0x4C: 0x2C, 0x6C: 0x2C,
|
||||
0x4D: 0x2D, 0x6D: 0x2D,
|
||||
0x4E: 0x2E, 0x6E: 0x2E,
|
||||
0x4F: 0x2F, 0x6F: 0x2F,
|
||||
0x58: 0x22, 0x78: 0x22,
|
||||
0x59: 0x39, 0x79: 0x39,
|
||||
0x5A: 0x3A, 0x7A: 0x3A,
|
||||
0x5B: 0x3B, 0x7B: 0x3B,
|
||||
0x5C: 0x3C, 0x7C: 0x3C,
|
||||
0x5D: 0x3D, 0x7D: 0x3D
|
||||
};
|
||||
|
||||
var Ptg18 = {
|
||||
/*::[*/0x01/*::]*/: { n:'PtgElfLel', f:parse_PtgElfLel },
|
||||
/*::[*/0x02/*::]*/: { n:'PtgElfRw', f:parse_PtgElfRw },
|
||||
/*::[*/0x03/*::]*/: { n:'PtgElfCol', f:parse_PtgElfCol },
|
||||
/*::[*/0x06/*::]*/: { n:'PtgElfRwV', f:parse_PtgElfRwV },
|
||||
/*::[*/0x07/*::]*/: { n:'PtgElfColV', f:parse_PtgElfColV },
|
||||
/*::[*/0x0A/*::]*/: { n:'PtgElfRadical', f:parse_PtgElfRadical },
|
||||
/*::[*/0x0B/*::]*/: { n:'PtgElfRadicalS', f:parse_PtgElfRadicalS },
|
||||
/*::[*/0x0D/*::]*/: { n:'PtgElfColS', f:parse_PtgElfColS },
|
||||
/*::[*/0x0F/*::]*/: { n:'PtgElfColSV', f:parse_PtgElfColSV },
|
||||
/*::[*/0x10/*::]*/: { n:'PtgElfRadicalLel', f:parse_PtgElfRadicalLel },
|
||||
/*::[*/0x19/*::]*/: { n:'PtgList', f:parse_PtgList },
|
||||
/*::[*/0x1D/*::]*/: { n:'PtgSxName', f:parse_PtgSxName },
|
||||
/*::[*/0xFF/*::]*/: {}
|
||||
0x01: { n:'PtgElfLel', f:parse_PtgElfLel },
|
||||
0x02: { n:'PtgElfRw', f:parse_PtgElfRw },
|
||||
0x03: { n:'PtgElfCol', f:parse_PtgElfCol },
|
||||
0x06: { n:'PtgElfRwV', f:parse_PtgElfRwV },
|
||||
0x07: { n:'PtgElfColV', f:parse_PtgElfColV },
|
||||
0x0A: { n:'PtgElfRadical', f:parse_PtgElfRadical },
|
||||
0x0B: { n:'PtgElfRadicalS', f:parse_PtgElfRadicalS },
|
||||
0x0D: { n:'PtgElfColS', f:parse_PtgElfColS },
|
||||
0x0F: { n:'PtgElfColSV', f:parse_PtgElfColSV },
|
||||
0x10: { n:'PtgElfRadicalLel', f:parse_PtgElfRadicalLel },
|
||||
0x19: { n:'PtgList', f:parse_PtgList },
|
||||
0x1D: { n:'PtgSxName', f:parse_PtgSxName },
|
||||
0xFF: {}
|
||||
};
|
||||
var Ptg19 = {
|
||||
/*::[*/0x00/*::]*/: { n:'PtgAttrNoop', f:parse_PtgAttrNoop },
|
||||
/*::[*/0x01/*::]*/: { n:'PtgAttrSemi', f:parse_PtgAttrSemi },
|
||||
/*::[*/0x02/*::]*/: { n:'PtgAttrIf', f:parse_PtgAttrIf },
|
||||
/*::[*/0x04/*::]*/: { n:'PtgAttrChoose', f:parse_PtgAttrChoose },
|
||||
/*::[*/0x08/*::]*/: { n:'PtgAttrGoto', f:parse_PtgAttrGoto },
|
||||
/*::[*/0x10/*::]*/: { n:'PtgAttrSum', f:parse_PtgAttrSum },
|
||||
/*::[*/0x20/*::]*/: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel },
|
||||
/*::[*/0x21/*::]*/: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel },
|
||||
/*::[*/0x40/*::]*/: { n:'PtgAttrSpace', f:parse_PtgAttrSpace },
|
||||
/*::[*/0x41/*::]*/: { n:'PtgAttrSpaceSemi', f:parse_PtgAttrSpaceSemi },
|
||||
/*::[*/0x80/*::]*/: { n:'PtgAttrIfError', f:parse_PtgAttrIfError },
|
||||
/*::[*/0xFF/*::]*/: {}
|
||||
0x00: { n:'PtgAttrNoop', f:parse_PtgAttrNoop },
|
||||
0x01: { n:'PtgAttrSemi', f:parse_PtgAttrSemi },
|
||||
0x02: { n:'PtgAttrIf', f:parse_PtgAttrIf },
|
||||
0x04: { n:'PtgAttrChoose', f:parse_PtgAttrChoose },
|
||||
0x08: { n:'PtgAttrGoto', f:parse_PtgAttrGoto },
|
||||
0x10: { n:'PtgAttrSum', f:parse_PtgAttrSum },
|
||||
0x20: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel },
|
||||
0x21: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel },
|
||||
0x40: { n:'PtgAttrSpace', f:parse_PtgAttrSpace },
|
||||
0x41: { n:'PtgAttrSpaceSemi', f:parse_PtgAttrSpaceSemi },
|
||||
0x80: { n:'PtgAttrIfError', f:parse_PtgAttrIfError },
|
||||
0xFF: {}
|
||||
};
|
||||
|
||||
/* [MS-XLS] 2.5.198.103 ; [MS-XLSB] 2.5.97.87 */
|
||||
|
@ -2,16 +2,13 @@ function parse_ws_xml_dim(ws/*:Worksheet*/, s/*:string*/) {
|
||||
var d = safe_decode_range(s);
|
||||
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
|
||||
}
|
||||
var mergecregex = /<(?:\w:)?mergeCell ref=["'][A-Z0-9:]+['"]\s*[\/]?>/g;
|
||||
var sheetdataregex = /<(?:\w+:)?sheetData[^>]*>([\s\S]*)<\/(?:\w+:)?sheetData>/;
|
||||
var hlinkregex = /<(?:\w:)?hyperlink [^>]*>/mg;
|
||||
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 colregex = /<(?:\w+:)?col\b[^<>]*[\/]?>/g;
|
||||
var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g;
|
||||
var marginregex= /<(?:\w:)?pageMargins[^>]*\/>/g;
|
||||
var sheetprregex = /<(?:\w:)?sheetPr\b(?:[^>a-z][^>]*)?\/>/;
|
||||
var sheetprregex2= /<(?:\w:)?sheetPr[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetPr)>/;
|
||||
var svsregex = /<(?:\w:)?sheetViews[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetViews)>/;
|
||||
var marginregex= /<(?:\w+:)?pageMargins[^<>]*\/>/g;
|
||||
var sheetprregex = /<(?:\w+:)?sheetPr\b[^<>]*?\/>/;
|
||||
|
||||
/* 18.3 Worksheets */
|
||||
function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ {
|
||||
@ -24,7 +21,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
||||
var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/);
|
||||
|
||||
var data1 = "", data2 = "";
|
||||
var mtch/*:?any*/ = data.match(sheetdataregex);
|
||||
var mtch/*:?any*/ = str_match_xml_ns(data, "sheetData");
|
||||
if(mtch) {
|
||||
data1 = data.slice(0, mtch.index);
|
||||
data2 = data.slice(mtch.index + mtch[0].length);
|
||||
@ -33,7 +30,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
||||
/* 18.3.1.82 sheetPr CT_SheetPr */
|
||||
var sheetPr = data1.match(sheetprregex);
|
||||
if(sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);
|
||||
else if((sheetPr = data1.match(sheetprregex2))) parse_ws_xml_sheetpr2(sheetPr[0], sheetPr[1]||"", s, wb, idx, styles, themes);
|
||||
else if((sheetPr = str_match_xml_ns(data1, "sheetPr"))) parse_ws_xml_sheetpr2(sheetPr[0], sheetPr[1]||"", s, wb, idx, styles, themes);
|
||||
|
||||
/* 18.3.1.35 dimension CT_SheetDimension */
|
||||
var ridx = (data1.match(/<(?:\w*:)?dimension/)||{index:-1}).index;
|
||||
@ -43,7 +40,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
|
||||
}
|
||||
|
||||
/* 18.3.1.88 sheetViews CT_SheetViews */
|
||||
var svs = data1.match(svsregex);
|
||||
var svs = str_match_xml_ns(data1, "sheetViews");
|
||||
if(svs && svs[1]) parse_ws_xml_sheetviews(svs[1], wb);
|
||||
|
||||
/* 18.3.1.17 cols CT_Cols */
|
||||
@ -65,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);
|
||||
@ -220,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*/ {
|
||||
@ -242,7 +239,7 @@ function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
|
||||
|
||||
/* 18.3.1.88 sheetViews CT_SheetViews */
|
||||
/* 18.3.1.87 sheetView CT_SheetView */
|
||||
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/?>/g;
|
||||
var sviewregex = /<(?:\w:)?sheetView(?:[^<>a-z][^<>]*)?\/?>/g;
|
||||
function parse_ws_xml_sheetviews(data, wb/*:WBWBProps*/) {
|
||||
if(!wb.Views) wb.Views = [{}];
|
||||
(data.match(sviewregex)||[]).forEach(function(r/*:string*/, i/*:number*/) {
|
||||
@ -321,9 +318,8 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts, idx, wb, date1904)/*:st
|
||||
|
||||
var parse_ws_xml_data = /*#__PURE__*/(function() {
|
||||
var cellregex = /<(?:\w+:)?c[ \/>]/, rowregex = /<\/(?:\w+:)?row>/;
|
||||
var rregex = /r=["']([^"']*)["']/, isregex = /<(?:\w+:)?is>([\S\s]*?)<\/(?:\w+:)?is>/;
|
||||
var rregex = /r=["']([^"']*)["']/;
|
||||
var refregex = /ref=["']([^"']*)["']/;
|
||||
var match_v = matchtag("v"), match_f = matchtag("f");
|
||||
|
||||
return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, themes, styles, wb) {
|
||||
var ri = 0, x = "", cells/*:Array<string>*/ = [], cref/*:?Array<string>*/ = [], idx=0, i=0, cc=0, d="", p/*:any*/;
|
||||
@ -402,9 +398,9 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
||||
d = x.slice(i);
|
||||
p = ({t:""}/*:any*/);
|
||||
|
||||
if((cref=d.match(match_v))!= null && /*::cref != null && */cref[1] !== '') p.v=unescapexml(cref[1]);
|
||||
if((cref=str_match_xml_ns(d, "v"))!= null && /*::cref != null && */cref[1] !== '') p.v=unescapexml(cref[1]);
|
||||
if(opts.cellFormula) {
|
||||
if((cref=d.match(match_f))!= null /*:: && cref != null*/) {
|
||||
if((cref=str_match_xml_ns(d, "f"))!= null /*:: && cref != null*/) {
|
||||
if(cref[1] == "") {
|
||||
if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="shared"') > -1) {
|
||||
// TODO: parse formula
|
||||
@ -426,7 +422,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
||||
sharedf[parseInt(ftag.si, 10)] = [ftag, ___f, tag.r];
|
||||
}
|
||||
}
|
||||
} else if((cref=d.match(/<f[^>]*\/>/))) {
|
||||
} else if((cref=d.match(/<f[^<>]*\/>/))) {
|
||||
ftag = parsexmltag(cref[0]);
|
||||
if(sharedf[ftag.si]) p.f = shift_formula_xlsx(sharedf[ftag.si][1], sharedf[ftag.si][2]/*[0].ref*/, tag.r);
|
||||
}
|
||||
@ -472,7 +468,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
||||
if(opts.cellHTML) p.h = escapehtml(p.v);
|
||||
break;
|
||||
case 'inlineStr':
|
||||
cref = d.match(isregex);
|
||||
cref = str_match_xml_ns(d, "is");
|
||||
p.t = 's';
|
||||
if(cref != null && (sstr = parse_si(cref[1]))) {
|
||||
p.v = sstr.t;
|
||||
@ -525,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);
|
||||
}
|
||||
@ -637,7 +634,7 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
if(!l[1].Target) return;
|
||||
rel = ({"ref":l[0]}/*:any*/);
|
||||
if(l[1].Target.charAt(0) != "#") {
|
||||
rId = add_rels(rels, -1, escapexml(l[1].Target).replace(/#.*$/, ""), RELS.HLINK);
|
||||
rId = add_rels(rels, -1, escapexml(l[1].Target).replace(/#[\s\S]*$/, ""), RELS.HLINK);
|
||||
rel["r:id"] = "rId"+rId;
|
||||
}
|
||||
if((relc = l[1].Target.indexOf("#")) > -1) rel.location = escapexml(l[1].Target.slice(relc+1));
|
||||
|
@ -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);
|
||||
@ -924,7 +928,7 @@ function write_HLINKS(ba, ws/*:Worksheet*/, rels) {
|
||||
/* *BrtHLink */
|
||||
ws['!links'].forEach(function(l) {
|
||||
if(!l[1].Target) return;
|
||||
var rId = add_rels(rels, -1, l[1].Target.replace(/#.*$/, ""), RELS.HLINK);
|
||||
var rId = add_rels(rels, -1, l[1].Target.replace(/#[\s\S]*$/, ""), RELS.HLINK);
|
||||
write_record(ba, 0x01EE /* BrtHLink */, write_BrtHLink(l, rId));
|
||||
});
|
||||
delete ws['!links'];
|
||||
|
@ -4,16 +4,16 @@ function parse_Cache(data/*:string*/)/*:[Array<number|string>, string, ?string]*
|
||||
var f;
|
||||
|
||||
/* 21.2.2.150 pt CT_NumVal */
|
||||
(data.match(/<c:pt idx="(\d*)">(.*?)<\/c:pt>/mg)||[]).forEach(function(pt) {
|
||||
var q = pt.match(/<c:pt idx="(\d*?)"><c:v>(.*)<\/c:v><\/c:pt>/);
|
||||
(data.match(/<c:pt idx="(\d*)"[^<>\/]*><c:v>([^<])<\/c:v><\/c:pt>/mg)||[]).forEach(function(pt) {
|
||||
var q = pt.match(/<c:pt idx="(\d*)"[^<>\/]*><c:v>([^<]*)<\/c:v><\/c:pt>/);
|
||||
if(!q) return;
|
||||
col[+q[1]] = num ? +q[2] : q[2];
|
||||
});
|
||||
|
||||
/* 21.2.2.71 formatCode CT_Xstring */
|
||||
var nf = unescapexml((data.match(/<c:formatCode>([\s\S]*?)<\/c:formatCode>/) || ["","General"])[1]);
|
||||
var nf = unescapexml((str_match_xml(data, "c:formatCode") || ["","General"])[1]);
|
||||
|
||||
(data.match(/<c:f>(.*?)<\/c:f>/mg)||[]).forEach(function(F) { f = F.replace(/<.*?>/g,""); });
|
||||
(str_match_ng(data, "<c:f>", "</c:f>")||[]).forEach(function(F) { f = F.replace(/<[^<>]*>/g,""); });
|
||||
|
||||
return [col, nf, f];
|
||||
}
|
||||
@ -28,7 +28,7 @@ function parse_chart(data/*:?string*/, name/*:string*/, opts, rels, wb, csheet)
|
||||
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
|
||||
|
||||
/* 21.2.2.120 numCache CT_NumData */
|
||||
(data.match(/<c:numCache>[\s\S]*?<\/c:numCache>/gm)||[]).forEach(function(nc) {
|
||||
(str_match_ng(data, "<c:numCache>", "</c:numCache>")||[]).forEach(function(nc) {
|
||||
var cache = parse_Cache(nc);
|
||||
refguess.s.r = refguess.s.c = 0;
|
||||
refguess.e.c = C;
|
||||
|
@ -69,8 +69,14 @@ function parse_BrtName(data, length, opts) {
|
||||
data.l += 1; //var chKey = data.read_shift(1);
|
||||
var itab = data.read_shift(4);
|
||||
var name = parse_XLNameWideString(data);
|
||||
var formula = parse_XLSBNameParsedFormula(data, 0, opts);
|
||||
var comment = parse_XLNullableWideString(data);
|
||||
var formula;
|
||||
var comment = "";
|
||||
try {
|
||||
formula = parse_XLSBNameParsedFormula(data, 0, opts);
|
||||
try {
|
||||
comment = parse_XLNullableWideString(data);
|
||||
} catch(e){}
|
||||
} catch(e) { console.error("Could not parse defined name " + name); }
|
||||
if(flags & 0x20) name = "_xlnm." + name;
|
||||
//if(0 /* fProc */) {
|
||||
// unusedstring1: XLNullableWideString
|
||||
@ -141,7 +147,7 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
|
||||
|
||||
case 0x0027: /* 'BrtName' */
|
||||
if(val.Sheet != null) opts.SID = val.Sheet;
|
||||
val.Ref = stringify_formula(val.Ptg, null, null, supbooks, opts);
|
||||
val.Ref = val.Ptg ? stringify_formula(val.Ptg, null, null, supbooks, opts) : "#REF!";
|
||||
delete opts.SID;
|
||||
delete val.Ptg;
|
||||
Names.push(val);
|
||||
|
@ -1,5 +1,5 @@
|
||||
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
||||
var attregexg2=/\b((?:\w+:)?[\w]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||
var attregex2=/\b((?:\w+:)?[\w]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
||||
function xlml_parsexmltag(tag/*:string*/, skip_root/*:?boolean*/) {
|
||||
var words = tag.split(/\s+/);
|
||||
var z/*:any*/ = ([]/*:any*/); if(!skip_root) z[0] = words[0];
|
||||
@ -99,10 +99,11 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
|
||||
if(sid === undefined && row) sid = row.StyleID;
|
||||
if(sid === undefined && csty) sid = csty.StyleID;
|
||||
while(styles[sid] !== undefined) {
|
||||
if(styles[sid].nf) nf = styles[sid].nf;
|
||||
if(styles[sid].Interior) interiors.push(styles[sid].Interior);
|
||||
if(!styles[sid].Parent) break;
|
||||
sid = styles[sid].Parent;
|
||||
var ssid = styles[sid];
|
||||
if(ssid.nf) nf = ssid.nf;
|
||||
if(ssid.Interior) interiors.push(ssid.Interior);
|
||||
if(!ssid.Parent) break;
|
||||
sid = ssid.Parent;
|
||||
}
|
||||
switch(data.Type) {
|
||||
case 'Boolean':
|
||||
@ -111,7 +112,7 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
|
||||
break;
|
||||
case 'String':
|
||||
cell.t = 's'; cell.r = xlml_fixstr(unescapexml(xml));
|
||||
cell.v = (xml.indexOf("<") > -1 ? unescapexml(ss||xml).replace(/<.*?>/g, "") : cell.r); // todo: BR etc
|
||||
cell.v = (xml.indexOf("<") > -1 ? unescapexml(ss||xml).replace(/<[^<>]*>/g, "") : cell.r); // todo: BR etc
|
||||
break;
|
||||
case 'DateTime':
|
||||
if(xml.slice(-1) != "Z") xml += "Z";
|
||||
@ -221,7 +222,7 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
||||
var rowinfo/*:Array<RowInfo>*/ = [], rowobj = {}, cc = 0, rr = 0;
|
||||
var Workbook/*:WBWBProps*/ = ({ Sheets:[], WBProps:{date1904:false} }/*:any*/), wsprops = {};
|
||||
xlmlregex.lastIndex = 0;
|
||||
str = str.replace(/<!--([\s\S]*?)-->/mg,"");
|
||||
str = str_remove_ng(str, "<!--", "-->");
|
||||
var raw_Rn3 = "";
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3] = (raw_Rn3 = Rn[3]).toLowerCase())) {
|
||||
case 'data' /*case 'Data'*/:
|
||||
@ -1143,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;
|
||||
@ -1185,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;
|
||||
@ -1198,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));
|
||||
}
|
||||
@ -1222,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("");
|
||||
}
|
||||
@ -1241,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,
|
||||
|
@ -125,7 +125,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
||||
return XLSIcv[icv];
|
||||
};
|
||||
var process_cell_style = function pcs(cell, line/*:any*/, options) {
|
||||
var process_cell_style = function pcs(line/*:any*/, options) {
|
||||
var xfd = line.XF.data;
|
||||
if(!xfd || !xfd.patternType || !options || !options.cellStyles) return;
|
||||
line.s = ({}/*:any*/);
|
||||
@ -137,7 +137,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
var addcell = function addcell(cell/*:any*/, line/*:any*/, options/*:any*/) {
|
||||
if(!biff4w && file_depth > 1) return;
|
||||
if(options.sheetRows && cell.r >= options.sheetRows) return;
|
||||
if(options.cellStyles && line.XF && line.XF.data) process_cell_style(cell, line, options);
|
||||
if(options.cellStyles && line.XF && line.XF.data) process_cell_style(line, options);
|
||||
delete line.ixfe; delete line.XF;
|
||||
lastcell = cell;
|
||||
last_cell = encode_cell(cell);
|
||||
@ -330,17 +330,17 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
} break;
|
||||
case 0x0009: case 0x0209: case 0x0409: case 0x0809 /* BOF */: {
|
||||
if(opts.biff === 8) opts.biff = {
|
||||
/*::[*/0x0009/*::]*/:2,
|
||||
/*::[*/0x0209/*::]*/:3,
|
||||
/*::[*/0x0409/*::]*/:4
|
||||
0x0009: 2,
|
||||
0x0209: 3,
|
||||
0x0409: 4
|
||||
}[RecordType] || {
|
||||
/*::[*/0x0200/*::]*/:2,
|
||||
/*::[*/0x0300/*::]*/:3,
|
||||
/*::[*/0x0400/*::]*/:4,
|
||||
/*::[*/0x0500/*::]*/:5,
|
||||
/*::[*/0x0600/*::]*/:8,
|
||||
/*::[*/0x0002/*::]*/:2,
|
||||
/*::[*/0x0007/*::]*/:2
|
||||
0x0200: 2,
|
||||
0x0300: 3,
|
||||
0x0400: 4,
|
||||
0x0500: 5,
|
||||
0x0600: 8,
|
||||
0x0002: 2,
|
||||
0x0007: 2
|
||||
}[val.BIFFVer] || 8;
|
||||
opts.biffguess = val.BIFFVer == 0;
|
||||
if(val.BIFFVer == 0 && val.dt == 0x1000) { opts.biff = 5; seen_codepage = true; set_cp(opts.codepage = 28591); }
|
||||
@ -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);
|
||||
|
2599
bits/77_parsetab.js
2599
bits/77_parsetab.js
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,7 @@ function write_biff_continue(ba/*:BufArray*/, type/*:number*/, payload, length/*
|
||||
}
|
||||
}
|
||||
|
||||
function write_BIFF2BERR(r/*:number*/, c/*:number*/, val, t/*:string*/) {
|
||||
function write_BIFF2BERR(r/*:number*/, c/*:number*/, val, t/*:?string*/) {
|
||||
var out = new_buf(9);
|
||||
write_BIFF2Cell(out, r, c);
|
||||
write_Bes(val, t || 'b', out);
|
||||
@ -101,11 +101,11 @@ function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:n
|
||||
|
||||
function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
var dense = ws["!data"] != null;
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), rr = "", cols/*:Array<string>*/ = [];
|
||||
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"]);
|
||||
/* ... */
|
||||
@ -545,19 +599,18 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
|
||||
var date1904 = (((wb||{}).Workbook||{}).WBProps||{}).date1904;
|
||||
if(b8) ws['!links'] = [];
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
|
||||
var comments = [];
|
||||
var row = [];
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
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 || {};
|
||||
|
@ -3,12 +3,12 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
|
||||
var opts = _opts || {};
|
||||
var dense = (opts.dense != null) ? opts.dense : DENSE;
|
||||
var ws/*:Worksheet*/ = ({}/*:any*/); if(dense) ws["!data"] = [];
|
||||
str = str.replace(/<!--.*?-->/g, "");
|
||||
str = str_remove_ng(str, "<!--", "-->");
|
||||
var mtch/*:any*/ = str.match(/<table/i);
|
||||
if(!mtch) throw new Error("Invalid HTML: could not find <table>");
|
||||
var mtch2/*:any*/ = str.match(/<\/table/i);
|
||||
var i/*:number*/ = mtch.index, j/*:number*/ = mtch2 && mtch2.index || str.length;
|
||||
var rows = split_regex(str.slice(i, j), /(:?<tr[^>]*>)/i, "<tr>");
|
||||
var rows = split_regex(str.slice(i, j), /(:?<tr[^<>]*>)/i, "<tr>");
|
||||
var R = -1, C = 0, RS = 0, CS = 0;
|
||||
var range/*:Range*/ = {s:{r:10000000, c:10000000},e:{r:0,c:0}};
|
||||
var merges/*:Array<Range>*/ = [];
|
||||
@ -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*/);
|
||||
@ -84,8 +90,9 @@ function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HT
|
||||
else if(cell) {
|
||||
sp["data-t"] = cell && cell.t || 'z';
|
||||
// note: data-v is unaffected by the timezone interpretation
|
||||
if(cell.v != null) sp["data-v"] = cell.v instanceof Date ? cell.v.toISOString() : cell.v;
|
||||
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;
|
||||
@ -99,7 +106,7 @@ var HTML_BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export
|
||||
var HTML_END = '</body></html>';
|
||||
|
||||
function html_to_workbook(str/*:string*/, opts)/*:Workbook*/ {
|
||||
var mtch = str.match(/<table[\s\S]*?>[\s\S]*?<\/table>/gi);
|
||||
var mtch = str_match_xml_ig(str, "table");
|
||||
if(!mtch || mtch.length == 0) throw new Error("Invalid HTML: could not find <table>");
|
||||
if(mtch.length == 1) {
|
||||
var w = sheet_to_workbook(html_to_sheet(mtch[0], opts), opts);
|
||||
@ -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;
|
||||
|
@ -5,9 +5,9 @@ function parse_text_p(text/*:string*//*::, tag*/)/*:Array<any>*/ {
|
||||
.replace(/[\t\r\n]/g, " ").trim().replace(/ +/g, " ")
|
||||
.replace(/<text:s\/>/g," ")
|
||||
.replace(/<text:s text:c="(\d+)"\/>/g, function($$,$1) { return Array(parseInt($1,10)+1).join(" "); })
|
||||
.replace(/<text:tab[^>]*\/>/g,"\t")
|
||||
.replace(/<text:tab[^<>]*\/>/g,"\t")
|
||||
.replace(/<text:line-break\/>/g,"\n");
|
||||
var v = unescapexml(fixed.replace(/<[^>]*>/g,""));
|
||||
var v = unescapexml(fixed.replace(/<[^<>]*>/g,""));
|
||||
|
||||
return [v];
|
||||
}
|
||||
@ -17,10 +17,10 @@ function parse_ods_styles(d/*:string*/, _opts, _nfm) {
|
||||
var number_format_map = _nfm || {};
|
||||
var str = xlml_normalize(d);
|
||||
xlmlregex.lastIndex = 0;
|
||||
str = str.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
||||
str = remove_doctype(str_remove_ng(str, "<!--", "-->"));
|
||||
var Rn, NFtag, NF = "", tNF = "", y, etpos = 0, tidx = -1, infmt = false, payload = "";
|
||||
while((Rn = xlmlregex.exec(str))) {
|
||||
switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
switch((Rn[3]=Rn[3].replace(/_[\s\S]*$/,""))) {
|
||||
/* Number Format Definitions */
|
||||
case 'number-style': // <number:number-style> 16.29.2
|
||||
case 'currency-style': // <number:currency-style> 16.29.8
|
||||
@ -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*/);
|
||||
@ -264,8 +264,8 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
|
||||
var isstub = false, intable = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
str = str.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
str = remove_doctype(str_remove_ng(str, "<!--", "-->"));
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_[\s\S]*$/,""))) {
|
||||
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ function write_number_format_ods(nf/*:string*/, nfidx/*:string*/)/*:string*/ {
|
||||
if((t=nf.match(/# (\?+)\/(\d+)/))) { payload += writextag("number:fraction", null, {"number:min-integer-digits":0, "number:min-numerator-digits": t[1].length, "number:denominator-value": +t[2]}); break j; }
|
||||
|
||||
/* percentages */
|
||||
if((t=nf.match(/(\d+)(|\.\d+)%/))) { type = "percentage"; payload += writextag("number:number", null, {"number:decimal-places": t[2] && t.length - 1 || 0, "number:min-decimal-places": t[2] && t.length - 1 || 0, "number:min-integer-digits": t[1].length }) + "<number:text>%</number:text>"; break j; }
|
||||
if((t=nf.match(/\b(\d+)(|\.\d+)%/))) { type = "percentage"; payload += writextag("number:number", null, {"number:decimal-places": t[2] && t.length - 1 || 0, "number:min-decimal-places": t[2] && t.length - 1 || 0, "number:min-integer-digits": t[1].length }) + "<number:text>%</number:text>"; break j; }
|
||||
|
||||
/* datetime */
|
||||
var has_time = false;
|
||||
@ -196,17 +196,17 @@ function write_names_ods(Names, SheetNames, idx) {
|
||||
return " " + writextag("table:named-range", null, {
|
||||
"table:name": name.Name,
|
||||
"table:cell-range-address": odsref,
|
||||
"table:base-cell-address": odsref.replace(/[\.]?[^\.]*$/, ".$A$1")
|
||||
"table:base-cell-address": odsref.replace(/[\.][^\.]*$/, ".$A$1")
|
||||
});
|
||||
}).join("\n") + "\n </table:named-expressions>\n";
|
||||
}
|
||||
var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function() {
|
||||
/* 6.1.2 White Space Characters */
|
||||
var write_text_p = function(text/*:string*/)/*:string*/ {
|
||||
var write_text_p = function(text/*:string*/, span)/*:string*/ {
|
||||
return escapexml(text)
|
||||
.replace(/ +/g, function($$){return '<text:s text:c="'+$$.length+'"/>';})
|
||||
.replace(/\t/g, "<text:tab/>")
|
||||
.replace(/\n/g, "</text:p><text:p>")
|
||||
.replace(/\n/g, span ? "<text:line-break/>": "</text:p><text:p>")
|
||||
.replace(/^ /, "<text:s/>").replace(/ $/, "<text:s/>");
|
||||
};
|
||||
|
||||
@ -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');
|
||||
@ -436,7 +454,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
|
||||
|
||||
if(opts.bookType == "fods") {
|
||||
o.push('<office:document' + attr + fods + '>\n');
|
||||
o.push(write_meta_ods().replace(/<office:document-meta.*?>/, "").replace(/<\/office:document-meta>/, "") + "\n");
|
||||
o.push(write_meta_ods().replace(/<office:document-meta[^<>]*?>/, "").replace(/<\/office:document-meta>/, "") + "\n");
|
||||
// TODO: settings (equiv of settings.xml for ODS)
|
||||
} else o.push('<office:document-content' + attr + '>\n');
|
||||
// o.push(' <office:scripts/>\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);
|
||||
@ -1512,7 +1544,7 @@ function numbers_add_meta(mlist, newid, newloc) {
|
||||
mlist[3].push({ type: 2, data: write_shallow([
|
||||
[],
|
||||
[{ type: 0, data: write_varint49(newid) }],
|
||||
[{ type: 2, data: stru8(newloc.replace(/-.*$/, "")) }],
|
||||
[{ type: 2, data: stru8(newloc.replace(/-[\s\S]*$/, "")) }],
|
||||
[{ type: 2, data: stru8(newloc) }],
|
||||
[{ type: 2, data: new Uint8Array([2, 0, 0]) }],
|
||||
[{ type: 2, data: new Uint8Array([2, 0, 0]) }],
|
||||
|
@ -204,7 +204,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(wbrels && wbrels[i]) {
|
||||
path = 'xl/' + (wbrels[i][1]).replace(/[\/]?xl\//, "");
|
||||
if(!safegetzipfile(zip, path)) path = wbrels[i][1];
|
||||
if(!safegetzipfile(zip, path)) path = wbrelsfile.replace(/_rels\/.*$/,"") + wbrels[i][1];
|
||||
if(!safegetzipfile(zip, path)) path = wbrelsfile.replace(/_rels\/[\S\s]*$/,"") + wbrels[i][1];
|
||||
stype = wbrels[i][2];
|
||||
} else {
|
||||
path = 'xl/worksheets/sheet'+(i+1-nmode)+"." + wbext;
|
||||
@ -257,7 +257,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(dir.vba.length > 0) out.vbaraw = getzipdata(zip,strip_front_slash(dir.vba[0]),true);
|
||||
else if(dir.defaults && dir.defaults.bin === CT_VBA) out.vbaraw = getzipdata(zip, 'xl/vbaProject.bin',true);
|
||||
}
|
||||
// TODO: pass back content types metdata for xlsm/xlsx resolution
|
||||
// TODO: pass back content types metadata for xlsm/xlsx resolution
|
||||
out.bookType = xlsb ? "xlsb" : "xlsx";
|
||||
return out;
|
||||
}
|
||||
|
@ -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;
|
||||
@ -117,7 +117,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, '""') + '"';
|
||||
@ -125,6 +125,7 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr
|
||||
/* NOTE: Excel CSV does not support array formulae */
|
||||
row.push(txt);
|
||||
}
|
||||
if(o.strip) while(row[row.length - 1] === "") --row.length;
|
||||
if(o.blankrows === false && isempty) return null;
|
||||
return row.join(FS);
|
||||
}
|
||||
@ -136,7 +137,6 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
|
||||
var r = safe_decode_range(sheet["!ref"]);
|
||||
var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0);
|
||||
var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0);
|
||||
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
|
||||
var row = "", cols/*:Array<string>*/ = [];
|
||||
var colinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
|
||||
var rowinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!rows"] || [];
|
||||
@ -144,9 +144,8 @@ 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(o.strip) row = row.replace(endregex,"");
|
||||
if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
|
||||
}
|
||||
return out.join("");
|
||||
@ -160,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;
|
||||
@ -181,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";
|
||||
@ -309,10 +309,10 @@ function book_append_sheet(wb/*:Workbook*/, ws/*:Worksheet*/, name/*:?string*/,
|
||||
var i = 1;
|
||||
if(!name) for(; i <= 0xFFFF; ++i, name = undefined) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break;
|
||||
if(!name || wb.SheetNames.length >= 0xFFFF) throw new Error("Too many worksheets");
|
||||
if(roll && wb.SheetNames.indexOf(name) >= 0) {
|
||||
var m = name.match(/(^.*?)(\d+)$/);
|
||||
i = m && +m[2] || 0;
|
||||
var root = m && m[1] || name;
|
||||
if(roll && wb.SheetNames.indexOf(name) >= 0 && name.length < 32) {
|
||||
var m = name.match(/\d+$/); // at this point, name length is capped at 32
|
||||
i = m && +m[0] || 0;
|
||||
var root = m && name.slice(0, m.index) || name;
|
||||
for(++i; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = root + i) == -1) break;
|
||||
}
|
||||
check_ws_name(name);
|
||||
|
164
bits/97_node.js
164
bits/97_node.js
@ -8,7 +8,6 @@ function write_csv_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
|
||||
var r = safe_decode_range(sheet["!ref"]);
|
||||
var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0);
|
||||
var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0);
|
||||
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
|
||||
var row/*:?string*/ = "", cols/*:Array<string>*/ = [];
|
||||
var colinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
|
||||
var rowinfo/*:Array<RowInfo>*/ = o.skipHidden && sheet["!rows"] || [];
|
||||
@ -20,9 +19,8 @@ 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(o.strip) row = row.replace(endregex,"");
|
||||
if(row || (o.blankrows !== false)) return stream.push((w++ ? RS : "") + row);
|
||||
}
|
||||
}
|
||||
@ -105,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)) {
|
||||
@ -118,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
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
2
dist/xlsx.core.min.map
generated
vendored
File diff suppressed because one or more lines are too long
4583
dist/xlsx.extendscript.js
generated
vendored
4583
dist/xlsx.extendscript.js
generated
vendored
File diff suppressed because it is too large
Load Diff
34
dist/xlsx.full.min.js
generated
vendored
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
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
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
2
dist/xlsx.mini.min.map
generated
vendored
File diff suppressed because one or more lines are too long
@ -68,7 +68,12 @@ function Base64_encode_arr(input) {
|
||||
function Base64_decode(input) {
|
||||
var o = "";
|
||||
var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
|
||||
input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/, "").replace(/[^\w\+\/\=]/g, "");
|
||||
if (input.slice(0, 5) == "data:") {
|
||||
var i = input.slice(0, 1024).indexOf(";base64,");
|
||||
if (i > -1)
|
||||
input = input.slice(i + 8);
|
||||
}
|
||||
input = input.replace(/[^\w\+\/\=]/g, "");
|
||||
for (var i = 0; i < input.length; ) {
|
||||
e1 = Base64_map.indexOf(input.charAt(i++));
|
||||
e2 = Base64_map.indexOf(input.charAt(i++));
|
||||
|
@ -59,8 +59,11 @@ function Base64_encode_arr(input: Uint8Array|number[]): string {
|
||||
function Base64_decode(input: string): string {
|
||||
var o = "";
|
||||
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
|
||||
input = input.replace(/^data:([^\/]+\/[^\/]+)?;base64\,/,'')
|
||||
.replace(/[^\w\+\/\=]/g, "")
|
||||
if(input.slice(0,5) == "data:") {
|
||||
var i = input.slice(0, 1024).indexOf(";base64,");
|
||||
if(i > -1) input = input.slice(i+8);
|
||||
}
|
||||
input = input.replace(/[^\w\+\/\=]/g, "");
|
||||
for(var i = 0; i < input.length;) {
|
||||
e1 = Base64_map.indexOf(input.charAt(i++));
|
||||
e2 = Base64_map.indexOf(input.charAt(i++));
|
||||
|
@ -17,7 +17,7 @@ function rtf_to_sheet_str(str, opts) {
|
||||
var dense = o.dense;
|
||||
if (dense)
|
||||
ws["!data"] = [];
|
||||
var rows = str.match(/\\trowd[\s\S]*?\\row\b/g);
|
||||
var rows = str_match_ng(str, "\\trowd", "\\row");
|
||||
if (!rows)
|
||||
throw new Error("RTF missing table");
|
||||
var range = { s: { c: 0, r: 0 }, e: { c: 0, r: rows.length - 1 } };
|
||||
@ -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) {
|
||||
@ -31,7 +32,7 @@ function rtf_to_sheet_str(str: string, opts: ParsingOptions): WorkSheet {
|
||||
var dense = o.dense;
|
||||
if(dense) ws["!data"] = [];
|
||||
|
||||
var rows = str.match(/\\trowd[\s\S]*?\\row\b/g);
|
||||
var rows = str_match_ng(str, "\\trowd", "\\row");
|
||||
if(!rows) throw new Error("RTF missing table");
|
||||
var range: Range = {s: {c:0, r:0}, e: {c:0, r:rows.length - 1}};
|
||||
var row: CellObject[] = [];
|
||||
@ -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;
|
||||
|
||||
|
@ -13,7 +13,7 @@ function fill_vba_xls(cfb, vba) {
|
||||
vba.FullPaths.forEach(function(p, i) {
|
||||
if (i == 0)
|
||||
return;
|
||||
var newpath = p.replace(/[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
|
||||
var newpath = p.replace(/^[\/]*[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
|
||||
if (newpath.slice(-1) !== "/")
|
||||
CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
|
||||
});
|
||||
|
@ -16,7 +16,7 @@ function make_vba_xls(cfb: CFBModule.CFB$Container) {
|
||||
function fill_vba_xls(cfb: CFBModule.CFB$Container, vba: CFBModule.CFB$Container): void {
|
||||
vba.FullPaths.forEach(function(p, i) {
|
||||
if(i == 0) return;
|
||||
var newpath = p.replace(/[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
|
||||
var newpath = p.replace(/^[\/]*[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
|
||||
if(newpath.slice(-1) !== "/") CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
|
||||
});
|
||||
}
|
||||
|
@ -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);
|
||||
@ -1512,7 +1544,7 @@ function numbers_add_meta(mlist, newid, newloc) {
|
||||
mlist[3].push({ type: 2, data: write_shallow([
|
||||
[],
|
||||
[{ type: 0, data: write_varint49(newid) }],
|
||||
[{ type: 2, data: stru8(newloc.replace(/-.*$/, "")) }],
|
||||
[{ type: 2, data: stru8(newloc.replace(/-[\s\S]*$/, "")) }],
|
||||
[{ type: 2, data: stru8(newloc) }],
|
||||
[{ type: 2, data: new Uint8Array([2, 0, 0]) }],
|
||||
[{ type: 2, data: new Uint8Array([2, 0, 0]) }],
|
||||
|
@ -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) */
|
||||
@ -1281,7 +1326,7 @@ function numbers_iwa_find(cfb: CFB$Container, deps: Dependents, id: number) {
|
||||
function numbers_add_meta(mlist: ProtoMessage, newid: number, newloc: string) {
|
||||
mlist[3].push({type: 2, data: write_shallow([ [],
|
||||
[{type: 0, data: write_varint49(newid)}],
|
||||
[{type: 2, data: stru8(newloc.replace(/-.*$/, "")) }],
|
||||
[{type: 2, data: stru8(newloc.replace(/-[\s\S]*$/, "")) }],
|
||||
[{type: 2, data: stru8(newloc)}],
|
||||
[{type: 2, data: new Uint8Array([2, 0, 0])}],
|
||||
[{type: 2, data: new Uint8Array([2, 0, 0])}],
|
||||
@ -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.1",
|
||||
"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"
|
||||
|
@ -17,7 +17,7 @@ types: dta.ts
|
||||
node: dist/dta.js
|
||||
|
||||
dist/dta.js: dta.ts
|
||||
npx esbuild@0.14.14 dta.ts --bundle --outdir=dist --platform=node
|
||||
npx esbuild@0.14.14 $< --bundle --outfile=$@ --platform=node
|
||||
|
||||
.PHONY: test-node
|
||||
test-node: dist/dta.js test.js
|
||||
@ -28,5 +28,8 @@ test-node: dist/dta.js test.js
|
||||
browser: dist/dta.min.js
|
||||
|
||||
dist/dta.min.js: dta.ts
|
||||
npx esbuild@0.14.14 dta.ts --bundle --outfile=dist/dta.min.js --minify --sourcemap --global-name=DTA
|
||||
npx esbuild@0.14.14 $< --bundle --outfile=$@ --minify --sourcemap --global-name=DTA
|
||||
|
||||
dist/dta.mjs: dta.ts
|
||||
npx esbuild@0.14.14 $< --bundle --outfile=$@ --minify --sourcemap --format=esm
|
||||
|
||||
|
@ -13,13 +13,13 @@ The codec will truncate data to 1048576 observations and 16384 variables.
|
||||
Using NodeJS package manager:
|
||||
|
||||
```bash
|
||||
npm install --save https://cdn.sheetjs.com/dta-0.0.1/dta-0.0.1.tgz
|
||||
npm install --save https://cdn.sheetjs.com/dta-0.0.2/dta-0.0.2.tgz
|
||||
```
|
||||
|
||||
The standalone script is also hosted on the SheetJS CDN:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.sheetjs.com/dta-0.0.1/package/dist/dta.min.js"></script>
|
||||
<script src="https://cdn.sheetjs.com/dta-0.0.2/package/dist/dta.min.js"></script>
|
||||
```
|
||||
|
||||
## Usage
|
||||
@ -52,7 +52,7 @@ const wb = DTA.parse(fs.readFileSync("auto.dta"));
|
||||
DTA.set_utils(XLSX.utils);
|
||||
(async() => {
|
||||
/* fetch file */
|
||||
const data = await (await fetch("test.dta")).arrayBuffer();
|
||||
const data = await (await fetch("test.dta")).arrayBuffer();
|
||||
/* parse */
|
||||
const wb = DTA.parse(new Uint8Array(data));
|
||||
/* wb is a SheetJS workbook object */
|
||||
@ -60,4 +60,10 @@ DTA.set_utils(XLSX.utils);
|
||||
out.innerHTML = html;
|
||||
})();
|
||||
</script>
|
||||
```
|
||||
```
|
||||
|
||||
`dist/dta.mjs` is a ECMAScript Module build designed to be used with bundlers:
|
||||
|
||||
```js
|
||||
import * as DTA from 'dta';
|
||||
```
|
||||
|
4
packages/dta/dist/dta.js
vendored
4
packages/dta/dist/dta.js
vendored
@ -28,7 +28,7 @@ __export(dta_exports, {
|
||||
set_utils: () => set_utils,
|
||||
version: () => version
|
||||
});
|
||||
var version = "0.0.1";
|
||||
var version = "0.0.2";
|
||||
var _utils;
|
||||
function set_utils(utils) {
|
||||
_utils = utils;
|
||||
@ -524,6 +524,7 @@ function parse_tagged(raw) {
|
||||
throw err;
|
||||
const wb = _utils.book_new();
|
||||
_utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
wb.bookType = "dta";
|
||||
return wb;
|
||||
}
|
||||
function parse_legacy(raw) {
|
||||
@ -668,6 +669,7 @@ function parse_legacy(raw) {
|
||||
}
|
||||
const wb = _utils.book_new();
|
||||
_utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
wb.bookType = "dta";
|
||||
return wb;
|
||||
}
|
||||
function parse(data) {
|
||||
|
2
packages/dta/dist/dta.min.js
vendored
2
packages/dta/dist/dta.min.js
vendored
File diff suppressed because one or more lines are too long
4
packages/dta/dist/dta.min.js.map
vendored
4
packages/dta/dist/dta.min.js.map
vendored
File diff suppressed because one or more lines are too long
2
packages/dta/dist/dta.mjs
generated
vendored
Normal file
2
packages/dta/dist/dta.mjs
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
7
packages/dta/dist/dta.mjs.map
vendored
Normal file
7
packages/dta/dist/dta.mjs.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
||||
import { CellObject, DenseWorkSheet, WorkBook, type utils } from 'xlsx';
|
||||
export { parse, set_utils, version };
|
||||
|
||||
const version = "0.0.1";
|
||||
const version = "0.0.2";
|
||||
|
||||
let _utils: typeof utils;
|
||||
/** Set internal instance of `utils`
|
||||
@ -92,7 +92,6 @@ function read_f32(p: Payload, LE: boolean): number | null {
|
||||
p.ptr += 4;
|
||||
const d = p.dv.getFloat32(p.ptr - 4, LE);
|
||||
return d > 1.701e+38 ? null : d;
|
||||
|
||||
}
|
||||
function read_u32(p: Payload, LE: boolean) {
|
||||
p.ptr += 4;
|
||||
@ -150,7 +149,7 @@ function parse_tagged(raw: Uint8Array): WorkBook {
|
||||
ptr: 0,
|
||||
raw,
|
||||
dv: u8_to_dataview(raw)
|
||||
}
|
||||
};
|
||||
|
||||
let vers: number = 118;
|
||||
let LE: boolean = true;
|
||||
@ -469,6 +468,7 @@ function parse_tagged(raw: Uint8Array): WorkBook {
|
||||
if(!valid_inc(d, "</stata_dta>")) throw err;
|
||||
const wb = _utils.book_new();
|
||||
_utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
wb.bookType = "dta" as any;
|
||||
return wb;
|
||||
}
|
||||
|
||||
@ -480,7 +480,7 @@ function parse_legacy(raw: Uint8Array): WorkBook {
|
||||
ptr: 1,
|
||||
raw,
|
||||
dv: u8_to_dataview(raw)
|
||||
}
|
||||
};
|
||||
|
||||
let LE: boolean = true;
|
||||
let nvar: number = 0, nobs: number = 0;
|
||||
@ -612,6 +612,7 @@ function parse_legacy(raw: Uint8Array): WorkBook {
|
||||
|
||||
const wb: WorkBook = _utils.book_new();
|
||||
_utils.book_append_sheet(wb, ws, "Sheet1");
|
||||
wb.bookType = "dta" as any;
|
||||
return wb;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
{
|
||||
"name": "dta",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"author": "sheetjs",
|
||||
"description": "Stata .dta codecs for SheetJS Common Spreadsheet Format",
|
||||
"bin": {
|
||||
"dta2csv": "./bin/dta2csv.njs"
|
||||
},
|
||||
"main": "dist/dta.js",
|
||||
"module": "dist/dta.mjs",
|
||||
"types": "types",
|
||||
"files": [
|
||||
"bin/",
|
||||
@ -33,6 +34,6 @@
|
||||
"node": ">=12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz"
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.1/xlsx-0.20.1.tgz"
|
||||
}
|
||||
}
|
||||
|
2
packages/dta/types/index.d.ts
vendored
2
packages/dta/types/index.d.ts
vendored
@ -1,6 +1,6 @@
|
||||
import { WorkBook } from 'xlsx';
|
||||
export { parse, set_utils, version };
|
||||
declare const version = "0.0.1";
|
||||
declare const version = "0.0.2";
|
||||
/** Set internal instance of `utils`
|
||||
*
|
||||
* Usage:
|
||||
|
@ -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!");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
200
test.js
200
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); }
|
||||
@ -367,13 +367,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]); });
|
||||
}
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -1023,10 +1034,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);
|
||||
@ -1061,6 +1076,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() {
|
||||
@ -1741,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});
|
||||
@ -1752,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);
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1869,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$/); }
|
||||
@ -2156,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);
|
||||
@ -2476,10 +2535,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]);
|
||||
});
|
||||
@ -2513,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");
|
||||
@ -2646,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() {
|
||||
@ -2703,6 +2790,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([
|
||||
|
186
test.mjs
generated
186
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([
|
||||
|
165
test.mts
165
test.mts
@ -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([
|
||||
|
2
test.sh
2
test.sh
@ -40,5 +40,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
|
||||
|
||||
|
||||
|
310
testbun.mjs → test.test.mjs
generated
310
testbun.mjs → test.test.mjs
generated
@ -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});
|
||||
});
|
165
test.ts
165
test.ts
@ -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([
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user