version bump 0.18.7
This commit is contained in:
parent
694cdcb75a
commit
eee39946e3
|
@ -27,9 +27,11 @@ tmp
|
|||
*.[uU][oO][sS]
|
||||
*.[wW][kKqQbB][S1234567890]
|
||||
*.[qQ][pP][wW]
|
||||
*.[fF][mM][3tT]
|
||||
*.[bB][iI][fF][fF][23458]
|
||||
*.[rR][tT][fF]
|
||||
*.[eE][tT][hH]
|
||||
*.[nN][uU][mM][bB][eE][rR][sS]
|
||||
*.123
|
||||
*.htm
|
||||
*.html
|
||||
|
|
|
@ -4,6 +4,10 @@ This log is intended to keep track of backwards-incompatible changes, including
|
|||
but not limited to API changes and file location changes. Minor behavioral
|
||||
changes may not be included if they are not expected to break existing code.
|
||||
|
||||
## v0.18.7
|
||||
|
||||
* Normalized handling of `\r` and `\n` newline characters
|
||||
|
||||
## v0.18.6
|
||||
|
||||
* Removed all npm dependencies
|
||||
|
|
48
README.md
48
README.md
|
@ -125,11 +125,11 @@ port calculations to web apps; automate common spreadsheet tasks, and much more!
|
|||
|
||||
Each standalone release script is available at <https://cdn.sheetjs.com/>.
|
||||
|
||||
The current version is `0.18.6` and can be referenced as follows:
|
||||
The current version is `0.18.7` and can be referenced as follows:
|
||||
|
||||
```html
|
||||
<!-- use version 0.18.6 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.full.min.js"></script>
|
||||
<!-- use version 0.18.7 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.full.min.js"></script>
|
||||
```
|
||||
|
||||
The `latest` tag references the latest version and updates with each release:
|
||||
|
@ -157,8 +157,8 @@ A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
|||
These scripts are also available on the CDN:
|
||||
|
||||
```html
|
||||
<!-- use xlsx.mini.min.js from version 0.18.6 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.mini.min.js"></script>
|
||||
<!-- use xlsx.mini.min.js from version 0.18.7 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.mini.min.js"></script>
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -208,11 +208,11 @@ a page with a `script` tag using `type="module"`:
|
|||
|
||||
```html
|
||||
<script type="module">
|
||||
import { read, writeFileXLSX } from "https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs";
|
||||
import { read, writeFileXLSX } from "https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs";
|
||||
|
||||
/* load the codepage support library for extended support with older formats */
|
||||
import { set_cptable } from "https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs";
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/cpexcel.full.mjs';
|
||||
import { set_cptable } from "https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs";
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs';
|
||||
set_cptable(cptable);
|
||||
</script>
|
||||
```
|
||||
|
@ -222,9 +222,9 @@ _Frameworks (Angular, VueJS, React) and Bundlers (webpack, etc)_
|
|||
The NodeJS package is readily installed from the tarballs:
|
||||
|
||||
```bash
|
||||
$ npm install --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
Once installed, the library can be imported under the name `xlsx`:
|
||||
|
@ -243,11 +243,11 @@ set_cptable(cptable);
|
|||
`xlsx.mjs` can be imported in Deno:
|
||||
|
||||
```ts
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-0.18.6/package/types/index.d.ts"
|
||||
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs';
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-0.18.7/package/types/index.d.ts"
|
||||
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs';
|
||||
|
||||
/* load the codepage support library for extended support with older formats */
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/cpexcel.full.mjs';
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs';
|
||||
XLSX.set_cptable(cptable);
|
||||
```
|
||||
|
||||
|
@ -256,7 +256,7 @@ XLSX.set_cptable(cptable);
|
|||
Tarballs are available on <https://cdn.sheetjs.com>.
|
||||
|
||||
Each individual version can be referenced using a similar URL pattern.
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz> is the URL for `0.18.6`
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz> is the URL for `0.18.7`
|
||||
|
||||
<https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz> is a link to the latest
|
||||
version and will refresh on each release.
|
||||
|
@ -266,15 +266,15 @@ _Installation_
|
|||
Tarballs can be directly installed using a package manager:
|
||||
|
||||
```bash
|
||||
$ npm install https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
For general stability, "vendoring" modules is the recommended approach:
|
||||
|
||||
1) Download the tarball (`xlsx-0.18.6.tgz`) for the desired version. The current
|
||||
version is available at <https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz>
|
||||
1) Download the tarball (`xlsx-0.18.7.tgz`) for the desired version. The current
|
||||
version is available at <https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz>
|
||||
|
||||
2) Create a `vendor` subdirectory at the root of your project and move the
|
||||
tarball to that folder. Add it to your project repository.
|
||||
|
@ -282,9 +282,9 @@ For general stability, "vendoring" modules is the recommended approach:
|
|||
3) Install the tarball using a package manager:
|
||||
|
||||
```bash
|
||||
$ npm install --save file:vendor/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install --save file:vendor/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add file:vendor/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install --save file:vendor/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install --save file:vendor/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add file:vendor/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
The package will be installed and accessible as `xlsx`.
|
||||
|
@ -320,7 +320,7 @@ XLSX.set_cptable(cpexcel);
|
|||
#### Photoshop and InDesign
|
||||
|
||||
`dist/xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign.
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.extendscript.js> is the
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.extendscript.js> is the
|
||||
current version. After downloading the script, it can be directly referenced
|
||||
with a `#include` directive:
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
XLSX.version = '0.18.6';
|
||||
XLSX.version = '0.18.7';
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -160,7 +160,7 @@ var DO_NOT_EXPORT_CODEPAGE = true;
|
|||
/*global exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
function make_xlsx_lib(XLSX){
|
||||
XLSX.version = '0.18.6';
|
||||
XLSX.version = '0.18.7';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true, window */
|
||||
var $cptable;
|
||||
|
@ -3674,15 +3674,19 @@ var rencoding = evert(encodings);
|
|||
var unescapexml = (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;
|
||||
return function unescapexml(text) {
|
||||
function raw_unescapexml(text) {
|
||||
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));});
|
||||
var j = s.indexOf("]]>");
|
||||
return unescapexml(s.slice(0, i)) + s.slice(i+9,j) + unescapexml(s.slice(j+3));
|
||||
return raw_unescapexml(s.slice(0, i)) + s.slice(i+9,j) + raw_unescapexml(s.slice(j+3));
|
||||
}
|
||||
return function unescapexml(text, xlsx) {
|
||||
var out = raw_unescapexml(text);
|
||||
return xlsx ? out.replace(/\r\n/g, "\n") : out;
|
||||
};
|
||||
})();
|
||||
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f\uFFFE-\uFFFF]/g;
|
||||
function escapexml(text){
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
|
||||
|
@ -3708,12 +3712,14 @@ var xlml_fixstr = (function() {
|
|||
})();
|
||||
function xlml_unfixstr(str) { return str.replace(/(\r\n|[\r\n])/g,"\ "); }
|
||||
|
||||
/* note: xsd:boolean valid values: true / 1 / false / 0 */
|
||||
function parsexmlbool(value) {
|
||||
switch(value) {
|
||||
case 1: case true: case '1': case 'true': case 'TRUE': return true;
|
||||
/* case '0': case 'false': case 'FALSE':*/
|
||||
default: return false;
|
||||
case 1: case true: case '1': case 'true': return true;
|
||||
case 0: case false: case '0': case 'false': return false;
|
||||
//default: throw new Error("Invalid xsd:boolean " + value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function utf8reada(orig) {
|
||||
|
@ -6060,6 +6066,7 @@ function parse_PropertySet(blob, PIDSI) {
|
|||
if(fail) throw new Error("Read Error: Expected address " + Props[i][1] + ' at ' + blob.l + ' :' + i);
|
||||
}
|
||||
if(PIDSI) {
|
||||
if(Props[i][0] == 0 && Props.length > i+1 && Props[i][1] == Props[i+1][1]) continue; // R9
|
||||
var piddsi = PIDSI[Props[i][0]];
|
||||
PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true});
|
||||
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
|
||||
|
@ -8515,10 +8522,9 @@ var PRN = (function() {
|
|||
else sep = guess_sep(str.slice(0,1024));
|
||||
var R = 0, C = 0, v = 0;
|
||||
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0, startcc=str.charCodeAt(0);
|
||||
str = str.replace(/\r\n/mg, "\n");
|
||||
var _re = o.dateNF != null ? dateNF_regex(o.dateNF) : null;
|
||||
function finish_cell() {
|
||||
var s = str.slice(start, end);
|
||||
var s = str.slice(start, end); if(s.slice(-1) == "\r") s = s.slice(0, -1);
|
||||
var cell = ({});
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length === 0) cell.t = 'z';
|
||||
|
@ -8553,7 +8559,11 @@ var PRN = (function() {
|
|||
}
|
||||
outer: for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
|
||||
case 0x22: if(startcc === 0x22) instr = !instr; break;
|
||||
case sepcc: case 0x0a: case 0x0d: if(!instr && finish_cell()) break outer; break;
|
||||
case 0x0d:
|
||||
if(instr) break;
|
||||
if(str.charCodeAt(end+1) == 0x0a) ++end;
|
||||
/* falls through */
|
||||
case sepcc: case 0x0a: if(!instr && finish_cell()) break outer; break;
|
||||
default: break;
|
||||
}
|
||||
if(end - start > 0) finish_cell();
|
||||
|
@ -8669,6 +8679,7 @@ var WK_ = (function() {
|
|||
var refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
|
||||
var sheetRows = o.sheetRows || 0;
|
||||
|
||||
if(d[4] == 0x51 && d[5] == 0x50 && d[6] == 0x57) return qpw_to_workbook_buf(d, opts);
|
||||
if(d[2] == 0x00) {
|
||||
if(d[3] == 0x08 || d[3] == 0x09) {
|
||||
if(d.length >= 16 && d[14] == 0x05 && d[15] === 0x6c) throw new Error("Unsupported Works 3 for Mac file");
|
||||
|
@ -8682,12 +8693,17 @@ var WK_ = (function() {
|
|||
o.vers = val;
|
||||
if(val >= 0x1000) o.qpro = true;
|
||||
break;
|
||||
case 0xFF: /* BOF (works 3+) */
|
||||
o.vers = val;
|
||||
o.works = true;
|
||||
break;
|
||||
case 0x06: refguess = val; break; /* RANGE */
|
||||
case 0xCC: if(val) next_n = val; break; /* SHEETNAMECS */
|
||||
case 0xDE: next_n = val; break; /* SHEETNAMELP */
|
||||
case 0x0F: /* LABEL */
|
||||
case 0x33: /* STRING */
|
||||
if(!o.qpro) val[1].v = val[1].v.slice(1);
|
||||
if((!o.qpro && !o.works || RT == 0x33) && val[1].v.charCodeAt(0) < 0x30) val[1].v = val[1].v.slice(1);
|
||||
if(o.works || o.works2) val[1].v = val[1].v.replace(/\r\n/g, "\n");
|
||||
/* falls through */
|
||||
case 0x0D: /* INTEGER */
|
||||
case 0x0E: /* NUMBER */
|
||||
|
@ -8721,6 +8737,7 @@ var WK_ = (function() {
|
|||
s[val[0].r][val[0].c] = val[1];
|
||||
} else s[encode_cell(val[0])] = val[1];
|
||||
break;
|
||||
case 0x5405: o.works2 = true; break;
|
||||
default:
|
||||
}}, o);
|
||||
} else if(d[2] == 0x1A || d[2] == 0x0E) {
|
||||
|
@ -8729,7 +8746,9 @@ var WK_ = (function() {
|
|||
lotushopper(d, function(val, R, RT) { switch(RT) {
|
||||
case 0xCC: n = val; break; /* SHEETNAMECS */
|
||||
case 0x16: /* LABEL16 */
|
||||
val[1].v = val[1].v.slice(1);
|
||||
if(val[1].v.charCodeAt(0) < 0x30) val[1].v = val[1].v.slice(1);
|
||||
// TODO: R9 appears to encode control codes this way -- verify against other versions
|
||||
val[1].v = val[1].v.replace(/\x0F./g, function($$) { return String.fromCharCode($$.charCodeAt(1) - 0x20); }).replace(/\r\n/g, "\n");
|
||||
/* falls through */
|
||||
case 0x17: /* NUMBER17 */
|
||||
case 0x18: /* NUMBER18 */
|
||||
|
@ -8924,6 +8943,9 @@ var WK_ = (function() {
|
|||
o[3] = blob.read_shift(1);
|
||||
o[0].r = blob.read_shift(2);
|
||||
blob.l+=2;
|
||||
} else if(opts.works) { // TODO: verify with more complex works3-4 examples
|
||||
o[0].c = blob.read_shift(2); o[0].r = blob.read_shift(2);
|
||||
o[2] = blob.read_shift(2);
|
||||
} else {
|
||||
o[2] = blob.read_shift(1);
|
||||
o[0].c = blob.read_shift(2); o[0].r = blob.read_shift(2);
|
||||
|
@ -8959,6 +8981,18 @@ var WK_ = (function() {
|
|||
o.write_shift(1, 0);
|
||||
return o;
|
||||
}
|
||||
function parse_STRING(blob, length, opts) {
|
||||
var tgt = blob.l + length;
|
||||
var o = parse_cell(blob, length, opts);
|
||||
o[1].t = 's';
|
||||
if(opts.vers == 0x5120) {
|
||||
var len = blob.read_shift(1);
|
||||
o[1].v = blob.read_shift(len, 'utf8');
|
||||
return o;
|
||||
}
|
||||
o[1].v = blob.read_shift(tgt - blob.l, 'cstr');
|
||||
return o;
|
||||
}
|
||||
|
||||
function parse_INTEGER(blob, length, opts) {
|
||||
var o = parse_cell(blob, length, opts);
|
||||
|
@ -9017,6 +9051,7 @@ var WK_ = (function() {
|
|||
0x33: ["FALSE", 0],
|
||||
0x34: ["TRUE", 0],
|
||||
0x46: ["LEN", 1],
|
||||
0x4A: ["CHAR", 1],
|
||||
0x50: ["SUM", 69],
|
||||
0x51: ["AVERAGEA", 69],
|
||||
0x52: ["COUNTA", 69],
|
||||
|
@ -9207,8 +9242,8 @@ var WK_ = (function() {
|
|||
}
|
||||
|
||||
function parse_FORMULA_28(blob, length) {
|
||||
var o = parse_NUMBER_27(blob, 14);
|
||||
blob.l += length - 10; /* TODO: formula */
|
||||
var o = parse_NUMBER_27(blob, 12);
|
||||
blob.l += length - 12; /* TODO: formula */
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -9298,7 +9333,7 @@ var WK_ = (function() {
|
|||
0x0030: { n:"UNFORMATTED" },
|
||||
0x0031: { n:"CURSORW12" },
|
||||
0x0032: { n:"WINDOW" },
|
||||
0x0033: { n:"STRING", f:parse_LABEL },
|
||||
0x0033: { n:"STRING", f:parse_STRING },
|
||||
0x0037: { n:"PASSWORD" },
|
||||
0x0038: { n:"LOCKED" },
|
||||
0x003C: { n:"QUERY" },
|
||||
|
@ -9322,6 +9357,7 @@ var WK_ = (function() {
|
|||
0x0069: { n:"MRANGES??" },
|
||||
0x00CC: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
|
||||
0x00DE: { n:"SHEETNAMELP", f:parse_SHEETNAMELP },
|
||||
0x00FF: { n:"BOF", f:parseuint16 },
|
||||
0xFFFF: { n:"" }
|
||||
};
|
||||
|
||||
|
@ -9450,6 +9486,144 @@ var WK_ = (function() {
|
|||
0x6F44: { n:"??" },
|
||||
0xFFFF: { n:"" }
|
||||
};
|
||||
|
||||
/* QPW uses a different set of record types */
|
||||
function qpw_to_workbook_buf(d, opts) {
|
||||
prep_blob(d, 0);
|
||||
var o = opts || {};
|
||||
if(DENSE != null && o.dense == null) o.dense = DENSE;
|
||||
var s = ((o.dense ? [] : {}));
|
||||
var SST = [], sname = "", formulae = [];
|
||||
var range = {s:{r:-1,c:-1}, e:{r:-1,c:-1}};
|
||||
var cnt = 0, type = 0, C = 0, R = 0;
|
||||
var wb = { SheetNames: [], Sheets: {} };
|
||||
outer: while(d.l < d.length) {
|
||||
var RT = d.read_shift(2), length = d.read_shift(2);
|
||||
var p = d.slice(d.l, d.l + length);
|
||||
prep_blob(p, 0);
|
||||
switch(RT) {
|
||||
case 0x01: /* BOF */
|
||||
if(p.read_shift(4) != 0x39575051) throw "Bad QPW9 BOF!";
|
||||
break;
|
||||
case 0x02: /* EOF */ break outer;
|
||||
|
||||
/* TODO: The behavior here should be consistent with Numbers: QP Notebook ~ .TN.SheetArchive, QP Sheet ~ .TST.TSTable */
|
||||
case 0x0401: /* BON */ break;
|
||||
case 0x0402: /* EON */ /* TODO: backfill missing sheets based on BON cnt */ break;
|
||||
|
||||
case 0x0407: { /* SST */
|
||||
p.l += 12;
|
||||
while(p.l < p.length) {
|
||||
cnt = p.read_shift(2);
|
||||
type = p.read_shift(1);
|
||||
SST.push(p.read_shift(cnt, 'cstr'));
|
||||
}
|
||||
} break;
|
||||
case 0x0408: { /* FORMULAE */
|
||||
//p.l += 12;
|
||||
//while(p.l < p.length) {
|
||||
// cnt = p.read_shift(2);
|
||||
// formulae.push(p.slice(p.l, p.l + cnt + 1)); p.l += cnt + 1;
|
||||
//}
|
||||
} break;
|
||||
|
||||
case 0x0601: { /* BOS */
|
||||
var sidx = p.read_shift(2);
|
||||
s = ((o.dense ? [] : {}));
|
||||
range.s.c = p.read_shift(2);
|
||||
range.e.c = p.read_shift(2);
|
||||
range.s.r = p.read_shift(4);
|
||||
range.e.r = p.read_shift(4);
|
||||
p.l += 4;
|
||||
if(p.l + 2 < p.length) {
|
||||
cnt = p.read_shift(2);
|
||||
type = p.read_shift(1);
|
||||
sname = cnt == 0 ? "" : p.read_shift(cnt, 'cstr');
|
||||
}
|
||||
if(!sname) sname = XLSX.utils.encode_col(sidx);
|
||||
/* TODO: backfill empty sheets */
|
||||
} break;
|
||||
case 0x0602: { /* EOS */
|
||||
/* NOTE: QP valid range A1:IV1000000 */
|
||||
if(range.s.c > 0xFF || range.s.r > 999999) break;
|
||||
if(range.e.c < range.s.c) range.e.c = range.s.c;
|
||||
if(range.e.r < range.s.r) range.e.r = range.s.r;
|
||||
s["!ref"] = encode_range(range);
|
||||
book_append_sheet(wb, s, sname); // TODO: a barrel roll
|
||||
} break;
|
||||
|
||||
case 0x0A01: { /* COL (like XLS Row, modulo the layout transposition) */
|
||||
C = p.read_shift(2);
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
R = p.read_shift(4);
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
R = p.read_shift(4);
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
} break;
|
||||
|
||||
case 0x0C01: { /* MulCells (like XLS MulRK, but takes advantage of common column data patterns) */
|
||||
R = p.read_shift(4), cnt = p.read_shift(4);
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.e.r < R + cnt - 1) range.e.r = R + cnt - 1;
|
||||
while(p.l < p.length) {
|
||||
var cell = { t: "z" };
|
||||
var flags = p.read_shift(1);
|
||||
if(flags & 0x80) p.l += 2;
|
||||
var mul = (flags & 0x40) ? p.read_shift(2) - 1: 0;
|
||||
switch(flags & 0x1F) {
|
||||
case 1: break;
|
||||
case 2: cell = { t: "n", v: p.read_shift(2) }; break;
|
||||
case 3: cell = { t: "n", v: p.read_shift(2, 'i') }; break;
|
||||
case 5: cell = { t: "n", v: p.read_shift(8, 'f') }; break;
|
||||
case 7: cell = { t: "s", v: SST[type = p.read_shift(4) - 1] }; break;
|
||||
case 8: cell = { t: "n", v: p.read_shift(8, 'f') }; p.l += 2; /* cell.f = formulae[p.read_shift(4)]; */ p.l += 4; break;
|
||||
default: throw "Unrecognized QPW cell type " + (flags & 0x1F);
|
||||
}
|
||||
var delta = 0;
|
||||
if(flags & 0x20) switch(flags & 0x1F) {
|
||||
case 2: delta = p.read_shift(2); break;
|
||||
case 3: delta = p.read_shift(2, 'i'); break;
|
||||
case 7: delta = p.read_shift(2); break;
|
||||
default: throw "Unsupported delta for QPW cell type " + (flags & 0x1F);
|
||||
}
|
||||
if(!(!o.sheetStubs && cell.t == "z")) {
|
||||
if(Array.isArray(s)) {
|
||||
if(!s[R]) s[R] = [];
|
||||
s[R][C] = cell;
|
||||
} else s[encode_cell({r:R, c:C})] = cell;
|
||||
}
|
||||
++R; --cnt;
|
||||
while(mul-- > 0 && cnt >= 0) {
|
||||
if(flags & 0x20) switch(flags & 0x1F) {
|
||||
case 2: cell = { t: "n", v: (cell.v + delta) & 0xFFFF }; break;
|
||||
case 3: cell = { t: "n", v: (cell.v + delta) & 0xFFFF }; if(cell.v > 0x7FFF) cell.v -= 0x10000; break;
|
||||
case 7: cell = { t: "s", v: SST[type = (type + delta) >>> 0] }; break;
|
||||
default: throw "Cannot apply delta for QPW cell type " + (flags & 0x1F);
|
||||
} else switch(flags & 0x1F) {
|
||||
case 1: cell = { t: "z" }; break;
|
||||
case 2: cell = { t: "n", v: p.read_shift(2) }; break;
|
||||
case 7: cell = { t: "s", v: SST[type = p.read_shift(4) - 1] }; break;
|
||||
default: throw "Cannot apply repeat for QPW cell type " + (flags & 0x1F);
|
||||
}
|
||||
if(!(!o.sheetStubs && cell.t == "z")) {
|
||||
if(Array.isArray(s)) {
|
||||
if(!s[R]) s[R] = [];
|
||||
s[R][C] = cell;
|
||||
} else s[encode_cell({r:R, c:C})] = cell;
|
||||
}
|
||||
++R; --cnt;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
d.l += length;
|
||||
}
|
||||
return wb;
|
||||
}
|
||||
|
||||
return {
|
||||
sheet_to_wk1: sheet_to_wk1,
|
||||
book_to_wk3: book_to_wk3,
|
||||
|
@ -9636,14 +9810,14 @@ function parse_si(x, opts) {
|
|||
/* 18.4.12 t ST_Xstring (Plaintext String) */
|
||||
// TODO: is whitespace actually valid here?
|
||||
if(x.match(/^\s*<(?:\w+:)?t[^>]*>/)) {
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""));
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""), true);
|
||||
z.r = utf8read(x);
|
||||
if(html) z.h = escapehtml(z.t);
|
||||
}
|
||||
/* 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,"")));
|
||||
z.t = unescapexml(utf8read((x.replace(sirphregex, '').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) */
|
||||
|
@ -10075,27 +10249,33 @@ var RTF = (function() {
|
|||
var o = opts || {};
|
||||
var ws = o.dense ? ([]) : ({});
|
||||
|
||||
var rows = str.match(/\\trowd.*?\\row\b/g);
|
||||
var rows = str.match(/\\trowd[\s\S]*?\\row\b/g);
|
||||
if(!rows.length) throw new Error("RTF missing table");
|
||||
var range = ({s: {c:0, r:0}, e: {c:0, r:rows.length - 1}});
|
||||
rows.forEach(function(rowtf, R) {
|
||||
if(Array.isArray(ws)) ws[R] = [];
|
||||
var rtfre = /\\\w+\b/g;
|
||||
var rtfre = /\\[\w\-]+\b/g;
|
||||
var last_index = 0;
|
||||
var res;
|
||||
var C = -1;
|
||||
var payload = [];
|
||||
while((res = rtfre.exec(rowtf))) {
|
||||
var data = rowtf.slice(last_index, rtfre.lastIndex - res[0].length);
|
||||
if(data.charCodeAt(0) == 0x20) data = data.slice(1);
|
||||
if(data.length) payload.push(data);
|
||||
switch(res[0]) {
|
||||
case "\\cell":
|
||||
var data = rowtf.slice(last_index, rtfre.lastIndex - res[0].length);
|
||||
if(data[0] == " ") data = data.slice(1);
|
||||
++C;
|
||||
if(data.length) {
|
||||
if(payload.length) {
|
||||
// TODO: value parsing, including codepage adjustments
|
||||
var cell = {v: data, t:"s"};
|
||||
var cell = {v: payload.join(""), t:"s"};
|
||||
if(Array.isArray(ws)) ws[R][C] = cell;
|
||||
else ws[encode_cell({r:R, c:C})] = cell;
|
||||
}
|
||||
payload = [];
|
||||
break;
|
||||
case "\\par": // NOTE: Excel serializes both "\r" and "\n" as "\\par"
|
||||
payload.push("\n");
|
||||
break;
|
||||
}
|
||||
last_index = rtfre.lastIndex;
|
||||
|
@ -10121,7 +10301,7 @@ var RTF = (function() {
|
|||
var coord = encode_cell({r:R,c:C});
|
||||
cell = dense ? (ws[R]||[])[C]: ws[coord];
|
||||
if(!cell || cell.v == null && (!cell.f || cell.F)) continue;
|
||||
o.push(" " + (cell.w || (format_cell(cell), cell.w)));
|
||||
o.push(" " + (cell.w || (format_cell(cell), cell.w)).replace(/[\r\n]/g, "\\par "));
|
||||
o.push("\\cell");
|
||||
}
|
||||
o.push("\\pard\\intbl\\row");
|
||||
|
@ -14923,7 +15103,7 @@ function parse_ws_xml_sheetviews(data, wb) {
|
|||
// $FlowIgnore
|
||||
if(+tag.zoomScale) wb.Views[i].zoom = +tag.zoomScale;
|
||||
// $FlowIgnore
|
||||
if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
if(tag.rightToLeft && parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
});
|
||||
}
|
||||
function write_ws_xml_sheetviews(ws, opts, idx, wb) {
|
||||
|
@ -15015,7 +15195,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||
if(opts.sheetRows && opts.sheetRows < tagr) continue;
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.hidden && parsexmlbool(tag.hidden)) { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
@ -15032,7 +15212,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||
if(opts && opts.cellStyles) {
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.hidden && parsexmlbool(tag.hidden)) { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
@ -15065,7 +15245,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||
if(opts.cellFormula) {
|
||||
if((cref=d.match(match_f))!= null && cref[1] !== '') {
|
||||
/* TODO: match against XLSXFutureFunctions */
|
||||
p.f=unescapexml(utf8read(cref[1])).replace(/\r\n/g, "\n");
|
||||
p.f=unescapexml(utf8read(cref[1]), true);
|
||||
if(!opts.xlfn) p.f = _xlfn(p.f);
|
||||
if(cref[0].indexOf('t="array"') > -1) {
|
||||
p.F = (d.match(refregex)||[])[1];
|
||||
|
@ -15119,7 +15299,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||
break;
|
||||
case 'str':
|
||||
p.t = "s";
|
||||
p.v = (p.v!=null) ? utf8read(p.v) : '';
|
||||
p.v = (p.v!=null) ? unescapexml(utf8read(p.v), true) : '';
|
||||
if(opts.cellHTML) p.h = escapehtml(p.v);
|
||||
break;
|
||||
case 'inlineStr':
|
||||
|
@ -16134,6 +16314,8 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||
|
||||
/* TODO: something useful -- this is a stub */
|
||||
function write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen) {
|
||||
var o = ({r:R, c:C});
|
||||
if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
|
||||
if(cell.v === undefined) return false;
|
||||
var vv = "";
|
||||
switch(cell.t) {
|
||||
|
@ -16147,11 +16329,9 @@ function write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen) {
|
|||
case 'n': case 'e': vv = ''+cell.v; break;
|
||||
default: vv = cell.v; break;
|
||||
}
|
||||
var o = ({r:R, c:C});
|
||||
/* TODO: cell style */
|
||||
o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
if(cell.l) ws['!links'].push([encode_cell(o), cell.l]);
|
||||
if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
|
||||
switch(cell.t) {
|
||||
case 's': case 'str':
|
||||
if(opts.bookSST) {
|
||||
|
@ -23556,8 +23736,8 @@ function write_zip_xlsb(wb, opts) {
|
|||
opts.Strings = []; opts.Strings.Count = 0; opts.Strings.Unique = 0;
|
||||
if(browser_has_Map) opts.revStrings = new Map();
|
||||
else { opts.revStrings = {}; opts.revStrings.foo = []; delete opts.revStrings.foo; }
|
||||
var wbext = opts.bookType == "xlsb" ? "bin" : "xml";
|
||||
var vbafmt = VBAFMTS.indexOf(opts.bookType) > -1;
|
||||
var wbext = "bin";
|
||||
var vbafmt = true;
|
||||
var ct = new_ct();
|
||||
fix_write_opts(opts = opts || {});
|
||||
var zip = zip_new();
|
||||
|
@ -23755,10 +23935,10 @@ f = "docProps/app.xml";
|
|||
carr[1].forEach(function(c) { if(c.T == true) needtc = true; });
|
||||
});
|
||||
if(needtc) {
|
||||
cf = "xl/threadedComments/threadedComment" + rId + "." + wbext;
|
||||
cf = "xl/threadedComments/threadedComment" + rId + ".xml";
|
||||
zip_add_file(zip, cf, write_tcmnt_xml(comments, people, opts));
|
||||
ct.threadedcomments.push(cf);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + "." + wbext, RELS.TCMNT);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + ".xml", RELS.TCMNT);
|
||||
}
|
||||
|
||||
cf = "xl/comments" + rId + "." + wbext;
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -6,11 +6,11 @@
|
|||
|
||||
Each standalone release script is available at <https://cdn.sheetjs.com/>.
|
||||
|
||||
The current version is `0.18.6` and can be referenced as follows:
|
||||
The current version is `0.18.7` and can be referenced as follows:
|
||||
|
||||
```html
|
||||
<!-- use version 0.18.6 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.full.min.js"></script>
|
||||
<!-- use version 0.18.7 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.full.min.js"></script>
|
||||
```
|
||||
|
||||
The `latest` tag references the latest version and updates with each release:
|
||||
|
@ -38,8 +38,8 @@ A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
|||
These scripts are also available on the CDN:
|
||||
|
||||
```html
|
||||
<!-- use xlsx.mini.min.js from version 0.18.6 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.mini.min.js"></script>
|
||||
<!-- use xlsx.mini.min.js from version 0.18.7 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.mini.min.js"></script>
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -89,11 +89,11 @@ a page with a `script` tag using `type="module"`:
|
|||
|
||||
```html
|
||||
<script type="module">
|
||||
import { read, writeFileXLSX } from "https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs";
|
||||
import { read, writeFileXLSX } from "https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs";
|
||||
|
||||
/* load the codepage support library for extended support with older formats */
|
||||
import { set_cptable } from "https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs";
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/cpexcel.full.mjs';
|
||||
import { set_cptable } from "https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs";
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs';
|
||||
set_cptable(cptable);
|
||||
</script>
|
||||
```
|
||||
|
@ -103,9 +103,9 @@ _Frameworks (Angular, VueJS, React) and Bundlers (webpack, etc)_
|
|||
The NodeJS package is readily installed from the tarballs:
|
||||
|
||||
```bash
|
||||
$ npm install --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
Once installed, the library can be imported under the name `xlsx`:
|
||||
|
@ -124,11 +124,11 @@ set_cptable(cptable);
|
|||
`xlsx.mjs` can be imported in Deno:
|
||||
|
||||
```ts
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-0.18.6/package/types/index.d.ts"
|
||||
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs';
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-0.18.7/package/types/index.d.ts"
|
||||
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs';
|
||||
|
||||
/* load the codepage support library for extended support with older formats */
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/cpexcel.full.mjs';
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs';
|
||||
XLSX.set_cptable(cptable);
|
||||
```
|
||||
|
||||
|
@ -137,7 +137,7 @@ XLSX.set_cptable(cptable);
|
|||
Tarballs are available on <https://cdn.sheetjs.com>.
|
||||
|
||||
Each individual version can be referenced using a similar URL pattern.
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz> is the URL for `0.18.6`
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz> is the URL for `0.18.7`
|
||||
|
||||
<https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz> is a link to the latest
|
||||
version and will refresh on each release.
|
||||
|
@ -147,15 +147,15 @@ _Installation_
|
|||
Tarballs can be directly installed using a package manager:
|
||||
|
||||
```bash
|
||||
$ npm install https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
For general stability, "vendoring" modules is the recommended approach:
|
||||
|
||||
1) Download the tarball (`xlsx-0.18.6.tgz`) for the desired version. The current
|
||||
version is available at <https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz>
|
||||
1) Download the tarball (`xlsx-0.18.7.tgz`) for the desired version. The current
|
||||
version is available at <https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz>
|
||||
|
||||
2) Create a `vendor` subdirectory at the root of your project and move the
|
||||
tarball to that folder. Add it to your project repository.
|
||||
|
@ -163,9 +163,9 @@ For general stability, "vendoring" modules is the recommended approach:
|
|||
3) Install the tarball using a package manager:
|
||||
|
||||
```bash
|
||||
$ npm install --save file:vendor/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install --save file:vendor/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add file:vendor/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install --save file:vendor/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install --save file:vendor/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add file:vendor/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
The package will be installed and accessible as `xlsx`.
|
||||
|
@ -201,7 +201,7 @@ XLSX.set_cptable(cpexcel);
|
|||
#### Photoshop and InDesign
|
||||
|
||||
`dist/xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign.
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.extendscript.js> is the
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.extendscript.js> is the
|
||||
current version. After downloading the script, it can be directly referenced
|
||||
with a `#include` directive:
|
||||
|
||||
|
|
|
@ -122,11 +122,11 @@ port calculations to web apps; automate common spreadsheet tasks, and much more!
|
|||
|
||||
Each standalone release script is available at <https://cdn.sheetjs.com/>.
|
||||
|
||||
The current version is `0.18.6` and can be referenced as follows:
|
||||
The current version is `0.18.7` and can be referenced as follows:
|
||||
|
||||
```html
|
||||
<!-- use version 0.18.6 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.full.min.js"></script>
|
||||
<!-- use version 0.18.7 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.full.min.js"></script>
|
||||
```
|
||||
|
||||
The `latest` tag references the latest version and updates with each release:
|
||||
|
@ -152,8 +152,8 @@ A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
|||
These scripts are also available on the CDN:
|
||||
|
||||
```html
|
||||
<!-- use xlsx.mini.min.js from version 0.18.6 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.mini.min.js"></script>
|
||||
<!-- use xlsx.mini.min.js from version 0.18.7 -->
|
||||
<script lang="javascript" src="https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.mini.min.js"></script>
|
||||
```
|
||||
|
||||
|
||||
|
@ -199,11 +199,11 @@ a page with a `script` tag using `type="module"`:
|
|||
|
||||
```html
|
||||
<script type="module">
|
||||
import { read, writeFileXLSX } from "https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs";
|
||||
import { read, writeFileXLSX } from "https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs";
|
||||
|
||||
/* load the codepage support library for extended support with older formats */
|
||||
import { set_cptable } from "https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs";
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/cpexcel.full.mjs';
|
||||
import { set_cptable } from "https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs";
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs';
|
||||
set_cptable(cptable);
|
||||
</script>
|
||||
```
|
||||
|
@ -213,9 +213,9 @@ _Frameworks (Angular, VueJS, React) and Bundlers (webpack, etc)_
|
|||
The NodeJS package is readily installed from the tarballs:
|
||||
|
||||
```bash
|
||||
$ npm install --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add --save https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add --save https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
Once installed, the library can be imported under the name `xlsx`:
|
||||
|
@ -234,11 +234,11 @@ set_cptable(cptable);
|
|||
`xlsx.mjs` can be imported in Deno:
|
||||
|
||||
```ts
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-0.18.6/package/types/index.d.ts"
|
||||
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/xlsx.mjs';
|
||||
// @deno-types="https://cdn.sheetjs.com/xlsx-0.18.7/package/types/index.d.ts"
|
||||
import * as XLSX from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/xlsx.mjs';
|
||||
|
||||
/* load the codepage support library for extended support with older formats */
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/cpexcel.full.mjs';
|
||||
import * as cptable from 'https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/cpexcel.full.mjs';
|
||||
XLSX.set_cptable(cptable);
|
||||
```
|
||||
|
||||
|
@ -247,7 +247,7 @@ XLSX.set_cptable(cptable);
|
|||
Tarballs are available on <https://cdn.sheetjs.com>.
|
||||
|
||||
Each individual version can be referenced using a similar URL pattern.
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz> is the URL for `0.18.6`
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz> is the URL for `0.18.7`
|
||||
|
||||
<https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz> is a link to the latest
|
||||
version and will refresh on each release.
|
||||
|
@ -257,15 +257,15 @@ _Installation_
|
|||
Tarballs can be directly installed using a package manager:
|
||||
|
||||
```bash
|
||||
$ npm install https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
For general stability, "vendoring" modules is the recommended approach:
|
||||
|
||||
1) Download the tarball (`xlsx-0.18.6.tgz`) for the desired version. The current
|
||||
version is available at <https://cdn.sheetjs.com/xlsx-0.18.6/xlsx-0.18.6.tgz>
|
||||
1) Download the tarball (`xlsx-0.18.7.tgz`) for the desired version. The current
|
||||
version is available at <https://cdn.sheetjs.com/xlsx-0.18.7/xlsx-0.18.7.tgz>
|
||||
|
||||
2) Create a `vendor` subdirectory at the root of your project and move the
|
||||
tarball to that folder. Add it to your project repository.
|
||||
|
@ -273,9 +273,9 @@ For general stability, "vendoring" modules is the recommended approach:
|
|||
3) Install the tarball using a package manager:
|
||||
|
||||
```bash
|
||||
$ npm install --save file:vendor/xlsx-0.18.6.tgz # npm
|
||||
$ pnpm install --save file:vendor/xlsx-0.18.6.tgz # pnpm
|
||||
$ yarn add file:vendor/xlsx-0.18.6.tgz # yarn
|
||||
$ npm install --save file:vendor/xlsx-0.18.7.tgz # npm
|
||||
$ pnpm install --save file:vendor/xlsx-0.18.7.tgz # pnpm
|
||||
$ yarn add file:vendor/xlsx-0.18.7.tgz # yarn
|
||||
```
|
||||
|
||||
The package will be installed and accessible as `xlsx`.
|
||||
|
@ -311,7 +311,7 @@ XLSX.set_cptable(cpexcel);
|
|||
#### Photoshop and InDesign
|
||||
|
||||
`dist/xlsx.extendscript.js` is an ExtendScript build for Photoshop and InDesign.
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.6/package/dist/xlsx.extendscript.js> is the
|
||||
<https://cdn.sheetjs.com/xlsx-0.18.7/package/dist/xlsx.extendscript.js> is the
|
||||
current version. After downloading the script, it can be directly referenced
|
||||
with a `#include` directive:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.18.6",
|
||||
"version": "0.18.7",
|
||||
"author": "sheetjs",
|
||||
"description": "SheetJS Spreadsheet data parser and writer",
|
||||
"keywords": [
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/*global exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
function make_xlsx_lib(XLSX){
|
||||
XLSX.version = '0.18.6';
|
||||
XLSX.version = '0.18.7';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true, window */
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/*global exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
function make_xlsx_lib(XLSX){
|
||||
XLSX.version = '0.18.6';
|
||||
XLSX.version = '0.18.7';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true, window */
|
||||
var $cptable;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/*global exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
function make_xlsx_lib(XLSX){
|
||||
XLSX.version = '0.18.6';
|
||||
XLSX.version = '0.18.7';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
|
||||
var VALID_ANSI = [ 874, 932, 936, 949, 950, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 10000 ];
|
||||
|
@ -3571,15 +3571,19 @@ var rencoding = /*#__PURE__*/evert(encodings);
|
|||
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;
|
||||
return function unescapexml(text/*:string*/)/*:string*/ {
|
||||
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));});
|
||||
var j = s.indexOf("]]>");
|
||||
return unescapexml(s.slice(0, i)) + s.slice(i+9,j) + unescapexml(s.slice(j+3));
|
||||
return raw_unescapexml(s.slice(0, i)) + s.slice(i+9,j) + raw_unescapexml(s.slice(j+3));
|
||||
}
|
||||
return function unescapexml(text/*:string*/, xlsx/*:boolean*/) {
|
||||
var out = raw_unescapexml(text);
|
||||
return xlsx ? out.replace(/\r\n/g, "\n") : out;
|
||||
};
|
||||
})();
|
||||
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f\uFFFE-\uFFFF]/g;
|
||||
function escapexml(text/*:string*/)/*:string*/{
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
|
||||
|
@ -3605,12 +3609,14 @@ var xlml_fixstr/*:StringConv*/ = /*#__PURE__*/(function() {
|
|||
})();
|
||||
function xlml_unfixstr(str/*:string*/)/*:string*/ { return str.replace(/(\r\n|[\r\n])/g,"\ "); }
|
||||
|
||||
/* note: xsd:boolean valid values: true / 1 / false / 0 */
|
||||
function parsexmlbool(value/*:any*/)/*:boolean*/ {
|
||||
switch(value) {
|
||||
case 1: case true: case '1': case 'true': case 'TRUE': return true;
|
||||
/* case '0': case 'false': case 'FALSE':*/
|
||||
default: return false;
|
||||
case 1: case true: case '1': case 'true': return true;
|
||||
case 0: case false: case '0': case 'false': return false;
|
||||
//default: throw new Error("Invalid xsd:boolean " + value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function utf8reada(orig/*:string*/)/*:string*/ {
|
||||
|
@ -6288,10 +6294,9 @@ var PRN = /*#__PURE__*/(function() {
|
|||
else sep = guess_sep(str.slice(0,1024));
|
||||
var R = 0, C = 0, v = 0;
|
||||
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0, startcc=str.charCodeAt(0);
|
||||
str = str.replace(/\r\n/mg, "\n");
|
||||
var _re/*:?RegExp*/ = o.dateNF != null ? dateNF_regex(o.dateNF) : null;
|
||||
function finish_cell() {
|
||||
var s = str.slice(start, end);
|
||||
var s = str.slice(start, end); if(s.slice(-1) == "\r") s = s.slice(0, -1);
|
||||
var cell = ({}/*:any*/);
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length === 0) cell.t = 'z';
|
||||
|
@ -6326,7 +6331,11 @@ var PRN = /*#__PURE__*/(function() {
|
|||
}
|
||||
outer: for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
|
||||
case 0x22: if(startcc === 0x22) instr = !instr; break;
|
||||
case sepcc: case 0x0a: case 0x0d: if(!instr && finish_cell()) break outer; break;
|
||||
case 0x0d:
|
||||
if(instr) break;
|
||||
if(str.charCodeAt(end+1) == 0x0a) ++end;
|
||||
/* falls through */
|
||||
case sepcc: case 0x0a: if(!instr && finish_cell()) break outer; break;
|
||||
default: break;
|
||||
}
|
||||
if(end - start > 0) finish_cell();
|
||||
|
@ -6586,14 +6595,14 @@ function parse_si(x, opts) {
|
|||
/* 18.4.12 t ST_Xstring (Plaintext String) */
|
||||
// TODO: is whitespace actually valid here?
|
||||
if(x.match(/^\s*<(?:\w+:)?t[^>]*>/)) {
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""));
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""), true);
|
||||
z.r = utf8read(x);
|
||||
if(html) z.h = escapehtml(z.t);
|
||||
}
|
||||
/* 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,"")));
|
||||
z.t = unescapexml(utf8read((x.replace(sirphregex, '').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) */
|
||||
|
@ -8392,7 +8401,7 @@ function parse_ws_xml_sheetviews(data, wb/*:WBWBProps*/) {
|
|||
// $FlowIgnore
|
||||
if(+tag.zoomScale) wb.Views[i].zoom = +tag.zoomScale;
|
||||
// $FlowIgnore
|
||||
if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
if(tag.rightToLeft && parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
});
|
||||
}
|
||||
function write_ws_xml_sheetviews(ws, opts, idx, wb)/*:string*/ {
|
||||
|
@ -8484,7 +8493,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||
if(opts.sheetRows && opts.sheetRows < tagr) continue;
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.hidden && parsexmlbool(tag.hidden)) { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
@ -8501,7 +8510,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||
if(opts && opts.cellStyles) {
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.hidden && parsexmlbool(tag.hidden)) { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
@ -8534,7 +8543,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||
if(opts.cellFormula) {
|
||||
if((cref=d.match(match_f))!= null && /*::cref != null && */cref[1] !== '') {
|
||||
/* TODO: match against XLSXFutureFunctions */
|
||||
p.f=unescapexml(utf8read(cref[1])).replace(/\r\n/g, "\n");
|
||||
p.f=unescapexml(utf8read(cref[1]), true);
|
||||
if(!opts.xlfn) p.f = _xlfn(p.f);
|
||||
if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="array"') > -1) {
|
||||
p.F = (d.match(refregex)||[])[1];
|
||||
|
@ -8588,7 +8597,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||
break;
|
||||
case 'str':
|
||||
p.t = "s";
|
||||
p.v = (p.v!=null) ? utf8read(p.v) : '';
|
||||
p.v = (p.v!=null) ? unescapexml(utf8read(p.v), true) : '';
|
||||
if(opts.cellHTML) p.h = escapehtml(p.v);
|
||||
break;
|
||||
case 'inlineStr':
|
||||
|
@ -10765,8 +10774,8 @@ function write_zip_xlsb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||
opts.Strings = /*::((*/[]/*:: :any):SST)*/; opts.Strings.Count = 0; opts.Strings.Unique = 0;
|
||||
if(browser_has_Map) opts.revStrings = new Map();
|
||||
else { opts.revStrings = {}; opts.revStrings.foo = []; delete opts.revStrings.foo; }
|
||||
var wbext = opts.bookType == "xlsb" ? "bin" : "xml";
|
||||
var vbafmt = VBAFMTS.indexOf(opts.bookType) > -1;
|
||||
var wbext = "bin";
|
||||
var vbafmt = true;
|
||||
var ct = new_ct();
|
||||
fix_write_opts(opts = opts || {});
|
||||
var zip = zip_new();
|
||||
|
@ -10966,10 +10975,10 @@ function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||
carr[1].forEach(function(c) { if(c.T == true) needtc = true; });
|
||||
});
|
||||
if(needtc) {
|
||||
cf = "xl/threadedComments/threadedComment" + rId + "." + wbext;
|
||||
cf = "xl/threadedComments/threadedComment" + rId + ".xml";
|
||||
zip_add_file(zip, cf, write_tcmnt_xml(comments, people, opts));
|
||||
ct.threadedcomments.push(cf);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + "." + wbext, RELS.TCMNT);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + ".xml", RELS.TCMNT);
|
||||
}
|
||||
|
||||
cf = "xl/comments" + rId + "." + wbext;
|
||||
|
|
51
xlsx.mini.js
51
xlsx.mini.js
|
@ -4,7 +4,7 @@
|
|||
/*global exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
function make_xlsx_lib(XLSX){
|
||||
XLSX.version = '0.18.6';
|
||||
XLSX.version = '0.18.7';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
|
||||
var VALID_ANSI = [ 874, 932, 936, 949, 950, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 10000 ];
|
||||
|
@ -3498,15 +3498,19 @@ var rencoding = evert(encodings);
|
|||
var unescapexml = (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;
|
||||
return function unescapexml(text) {
|
||||
function raw_unescapexml(text) {
|
||||
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));});
|
||||
var j = s.indexOf("]]>");
|
||||
return unescapexml(s.slice(0, i)) + s.slice(i+9,j) + unescapexml(s.slice(j+3));
|
||||
return raw_unescapexml(s.slice(0, i)) + s.slice(i+9,j) + raw_unescapexml(s.slice(j+3));
|
||||
}
|
||||
return function unescapexml(text, xlsx) {
|
||||
var out = raw_unescapexml(text);
|
||||
return xlsx ? out.replace(/\r\n/g, "\n") : out;
|
||||
};
|
||||
})();
|
||||
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f\uFFFE-\uFFFF]/g;
|
||||
function escapexml(text){
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
|
||||
|
@ -3532,12 +3536,14 @@ var xlml_fixstr = (function() {
|
|||
})();
|
||||
function xlml_unfixstr(str) { return str.replace(/(\r\n|[\r\n])/g,"\ "); }
|
||||
|
||||
/* note: xsd:boolean valid values: true / 1 / false / 0 */
|
||||
function parsexmlbool(value) {
|
||||
switch(value) {
|
||||
case 1: case true: case '1': case 'true': case 'TRUE': return true;
|
||||
/* case '0': case 'false': case 'FALSE':*/
|
||||
default: return false;
|
||||
case 1: case true: case '1': case 'true': return true;
|
||||
case 0: case false: case '0': case 'false': return false;
|
||||
//default: throw new Error("Invalid xsd:boolean " + value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function utf8reada(orig) {
|
||||
|
@ -6203,10 +6209,9 @@ var PRN = (function() {
|
|||
else sep = guess_sep(str.slice(0,1024));
|
||||
var R = 0, C = 0, v = 0;
|
||||
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0, startcc=str.charCodeAt(0);
|
||||
str = str.replace(/\r\n/mg, "\n");
|
||||
var _re = o.dateNF != null ? dateNF_regex(o.dateNF) : null;
|
||||
function finish_cell() {
|
||||
var s = str.slice(start, end);
|
||||
var s = str.slice(start, end); if(s.slice(-1) == "\r") s = s.slice(0, -1);
|
||||
var cell = ({});
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length === 0) cell.t = 'z';
|
||||
|
@ -6241,7 +6246,11 @@ var PRN = (function() {
|
|||
}
|
||||
outer: for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
|
||||
case 0x22: if(startcc === 0x22) instr = !instr; break;
|
||||
case sepcc: case 0x0a: case 0x0d: if(!instr && finish_cell()) break outer; break;
|
||||
case 0x0d:
|
||||
if(instr) break;
|
||||
if(str.charCodeAt(end+1) == 0x0a) ++end;
|
||||
/* falls through */
|
||||
case sepcc: case 0x0a: if(!instr && finish_cell()) break outer; break;
|
||||
default: break;
|
||||
}
|
||||
if(end - start > 0) finish_cell();
|
||||
|
@ -6501,14 +6510,14 @@ function parse_si(x, opts) {
|
|||
/* 18.4.12 t ST_Xstring (Plaintext String) */
|
||||
// TODO: is whitespace actually valid here?
|
||||
if(x.match(/^\s*<(?:\w+:)?t[^>]*>/)) {
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""));
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""), true);
|
||||
z.r = utf8read(x);
|
||||
if(html) z.h = escapehtml(z.t);
|
||||
}
|
||||
/* 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,"")));
|
||||
z.t = unescapexml(utf8read((x.replace(sirphregex, '').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) */
|
||||
|
@ -8307,7 +8316,7 @@ function parse_ws_xml_sheetviews(data, wb) {
|
|||
// $FlowIgnore
|
||||
if(+tag.zoomScale) wb.Views[i].zoom = +tag.zoomScale;
|
||||
// $FlowIgnore
|
||||
if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
if(tag.rightToLeft && parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
});
|
||||
}
|
||||
function write_ws_xml_sheetviews(ws, opts, idx, wb) {
|
||||
|
@ -8399,7 +8408,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||
if(opts.sheetRows && opts.sheetRows < tagr) continue;
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.hidden && parsexmlbool(tag.hidden)) { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
@ -8416,7 +8425,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||
if(opts && opts.cellStyles) {
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.hidden && parsexmlbool(tag.hidden)) { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
@ -8449,7 +8458,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||
if(opts.cellFormula) {
|
||||
if((cref=d.match(match_f))!= null && cref[1] !== '') {
|
||||
/* TODO: match against XLSXFutureFunctions */
|
||||
p.f=unescapexml(utf8read(cref[1])).replace(/\r\n/g, "\n");
|
||||
p.f=unescapexml(utf8read(cref[1]), true);
|
||||
if(!opts.xlfn) p.f = _xlfn(p.f);
|
||||
if(cref[0].indexOf('t="array"') > -1) {
|
||||
p.F = (d.match(refregex)||[])[1];
|
||||
|
@ -8503,7 +8512,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||
break;
|
||||
case 'str':
|
||||
p.t = "s";
|
||||
p.v = (p.v!=null) ? utf8read(p.v) : '';
|
||||
p.v = (p.v!=null) ? unescapexml(utf8read(p.v), true) : '';
|
||||
if(opts.cellHTML) p.h = escapehtml(p.v);
|
||||
break;
|
||||
case 'inlineStr':
|
||||
|
@ -10676,8 +10685,8 @@ function write_zip_xlsb(wb, opts) {
|
|||
opts.Strings = []; opts.Strings.Count = 0; opts.Strings.Unique = 0;
|
||||
if(browser_has_Map) opts.revStrings = new Map();
|
||||
else { opts.revStrings = {}; opts.revStrings.foo = []; delete opts.revStrings.foo; }
|
||||
var wbext = opts.bookType == "xlsb" ? "bin" : "xml";
|
||||
var vbafmt = VBAFMTS.indexOf(opts.bookType) > -1;
|
||||
var wbext = "bin";
|
||||
var vbafmt = true;
|
||||
var ct = new_ct();
|
||||
fix_write_opts(opts = opts || {});
|
||||
var zip = zip_new();
|
||||
|
@ -10875,10 +10884,10 @@ f = "docProps/app.xml";
|
|||
carr[1].forEach(function(c) { if(c.T == true) needtc = true; });
|
||||
});
|
||||
if(needtc) {
|
||||
cf = "xl/threadedComments/threadedComment" + rId + "." + wbext;
|
||||
cf = "xl/threadedComments/threadedComment" + rId + ".xml";
|
||||
zip_add_file(zip, cf, write_tcmnt_xml(comments, people, opts));
|
||||
ct.threadedcomments.push(cf);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + "." + wbext, RELS.TCMNT);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + ".xml", RELS.TCMNT);
|
||||
}
|
||||
|
||||
cf = "xl/comments" + rId + "." + wbext;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/*exported XLSX */
|
||||
/*global process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
|
||||
var XLSX = {};
|
||||
XLSX.version = '0.18.6';
|
||||
XLSX.version = '0.18.7';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
|
||||
var VALID_ANSI = [ 874, 932, 936, 949, 950, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 10000 ];
|
||||
|
@ -3580,15 +3580,19 @@ var rencoding = /*#__PURE__*/evert(encodings);
|
|||
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;
|
||||
return function unescapexml(text/*:string*/)/*:string*/ {
|
||||
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));});
|
||||
var j = s.indexOf("]]>");
|
||||
return unescapexml(s.slice(0, i)) + s.slice(i+9,j) + unescapexml(s.slice(j+3));
|
||||
return raw_unescapexml(s.slice(0, i)) + s.slice(i+9,j) + raw_unescapexml(s.slice(j+3));
|
||||
}
|
||||
return function unescapexml(text/*:string*/, xlsx/*:boolean*/) {
|
||||
var out = raw_unescapexml(text);
|
||||
return xlsx ? out.replace(/\r\n/g, "\n") : out;
|
||||
};
|
||||
})();
|
||||
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f\uFFFE-\uFFFF]/g;
|
||||
function escapexml(text/*:string*/)/*:string*/{
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
|
||||
|
@ -3614,12 +3618,14 @@ var xlml_fixstr/*:StringConv*/ = /*#__PURE__*/(function() {
|
|||
})();
|
||||
function xlml_unfixstr(str/*:string*/)/*:string*/ { return str.replace(/(\r\n|[\r\n])/g,"\ "); }
|
||||
|
||||
/* note: xsd:boolean valid values: true / 1 / false / 0 */
|
||||
function parsexmlbool(value/*:any*/)/*:boolean*/ {
|
||||
switch(value) {
|
||||
case 1: case true: case '1': case 'true': case 'TRUE': return true;
|
||||
/* case '0': case 'false': case 'FALSE':*/
|
||||
default: return false;
|
||||
case 1: case true: case '1': case 'true': return true;
|
||||
case 0: case false: case '0': case 'false': return false;
|
||||
//default: throw new Error("Invalid xsd:boolean " + value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function utf8reada(orig/*:string*/)/*:string*/ {
|
||||
|
@ -5980,6 +5986,7 @@ function parse_PropertySet(blob, PIDSI) {
|
|||
if(fail) throw new Error("Read Error: Expected address " + Props[i][1] + ' at ' + blob.l + ' :' + i);
|
||||
}
|
||||
if(PIDSI) {
|
||||
if(Props[i][0] == 0 && Props.length > i+1 && Props[i][1] == Props[i+1][1]) continue; // R9
|
||||
var piddsi = PIDSI[Props[i][0]];
|
||||
PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true});
|
||||
if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
|
||||
|
@ -8437,10 +8444,9 @@ var PRN = /*#__PURE__*/(function() {
|
|||
else sep = guess_sep(str.slice(0,1024));
|
||||
var R = 0, C = 0, v = 0;
|
||||
var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0, startcc=str.charCodeAt(0);
|
||||
str = str.replace(/\r\n/mg, "\n");
|
||||
var _re/*:?RegExp*/ = o.dateNF != null ? dateNF_regex(o.dateNF) : null;
|
||||
function finish_cell() {
|
||||
var s = str.slice(start, end);
|
||||
var s = str.slice(start, end); if(s.slice(-1) == "\r") s = s.slice(0, -1);
|
||||
var cell = ({}/*:any*/);
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length === 0) cell.t = 'z';
|
||||
|
@ -8475,7 +8481,11 @@ var PRN = /*#__PURE__*/(function() {
|
|||
}
|
||||
outer: for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
|
||||
case 0x22: if(startcc === 0x22) instr = !instr; break;
|
||||
case sepcc: case 0x0a: case 0x0d: if(!instr && finish_cell()) break outer; break;
|
||||
case 0x0d:
|
||||
if(instr) break;
|
||||
if(str.charCodeAt(end+1) == 0x0a) ++end;
|
||||
/* falls through */
|
||||
case sepcc: case 0x0a: if(!instr && finish_cell()) break outer; break;
|
||||
default: break;
|
||||
}
|
||||
if(end - start > 0) finish_cell();
|
||||
|
@ -8591,6 +8601,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
var refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
|
||||
var sheetRows = o.sheetRows || 0;
|
||||
|
||||
if(d[4] == 0x51 && d[5] == 0x50 && d[6] == 0x57) return qpw_to_workbook_buf(d, opts);
|
||||
if(d[2] == 0x00) {
|
||||
if(d[3] == 0x08 || d[3] == 0x09) {
|
||||
if(d.length >= 16 && d[14] == 0x05 && d[15] === 0x6c) throw new Error("Unsupported Works 3 for Mac file");
|
||||
|
@ -8604,12 +8615,17 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
o.vers = val;
|
||||
if(val >= 0x1000) o.qpro = true;
|
||||
break;
|
||||
case 0xFF: /* BOF (works 3+) */
|
||||
o.vers = val;
|
||||
o.works = true;
|
||||
break;
|
||||
case 0x06: refguess = val; break; /* RANGE */
|
||||
case 0xCC: if(val) next_n = val; break; /* SHEETNAMECS */
|
||||
case 0xDE: next_n = val; break; /* SHEETNAMELP */
|
||||
case 0x0F: /* LABEL */
|
||||
case 0x33: /* STRING */
|
||||
if(!o.qpro) val[1].v = val[1].v.slice(1);
|
||||
if((!o.qpro && !o.works || RT == 0x33) && val[1].v.charCodeAt(0) < 0x30) val[1].v = val[1].v.slice(1);
|
||||
if(o.works || o.works2) val[1].v = val[1].v.replace(/\r\n/g, "\n");
|
||||
/* falls through */
|
||||
case 0x0D: /* INTEGER */
|
||||
case 0x0E: /* NUMBER */
|
||||
|
@ -8643,6 +8659,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
s[val[0].r][val[0].c] = val[1];
|
||||
} else s[encode_cell(val[0])] = val[1];
|
||||
break;
|
||||
case 0x5405: o.works2 = true; break;
|
||||
default:
|
||||
}}, o);
|
||||
} else if(d[2] == 0x1A || d[2] == 0x0E) {
|
||||
|
@ -8651,7 +8668,9 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
lotushopper(d, function(val, R, RT) { switch(RT) {
|
||||
case 0xCC: n = val; break; /* SHEETNAMECS */
|
||||
case 0x16: /* LABEL16 */
|
||||
val[1].v = val[1].v.slice(1);
|
||||
if(val[1].v.charCodeAt(0) < 0x30) val[1].v = val[1].v.slice(1);
|
||||
// TODO: R9 appears to encode control codes this way -- verify against other versions
|
||||
val[1].v = val[1].v.replace(/\x0F./g, function($$) { return String.fromCharCode($$.charCodeAt(1) - 0x20); }).replace(/\r\n/g, "\n");
|
||||
/* falls through */
|
||||
case 0x17: /* NUMBER17 */
|
||||
case 0x18: /* NUMBER18 */
|
||||
|
@ -8846,6 +8865,9 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
o[3] = blob.read_shift(1);
|
||||
o[0].r = blob.read_shift(2);
|
||||
blob.l+=2;
|
||||
} else if(opts.works) { // TODO: verify with more complex works3-4 examples
|
||||
o[0].c = blob.read_shift(2); o[0].r = blob.read_shift(2);
|
||||
o[2] = blob.read_shift(2);
|
||||
} else {
|
||||
o[2] = blob.read_shift(1);
|
||||
o[0].c = blob.read_shift(2); o[0].r = blob.read_shift(2);
|
||||
|
@ -8881,6 +8903,18 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
o.write_shift(1, 0);
|
||||
return o;
|
||||
}
|
||||
function parse_STRING(blob, length, opts) {
|
||||
var tgt = blob.l + length;
|
||||
var o = parse_cell(blob, length, opts);
|
||||
o[1].t = 's';
|
||||
if(opts.vers == 0x5120) {
|
||||
var len = blob.read_shift(1);
|
||||
o[1].v = blob.read_shift(len, 'utf8');
|
||||
return o;
|
||||
}
|
||||
o[1].v = blob.read_shift(tgt - blob.l, 'cstr');
|
||||
return o;
|
||||
}
|
||||
|
||||
function parse_INTEGER(blob, length, opts) {
|
||||
var o = parse_cell(blob, length, opts);
|
||||
|
@ -8939,6 +8973,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
0x33: ["FALSE", 0],
|
||||
0x34: ["TRUE", 0],
|
||||
0x46: ["LEN", 1],
|
||||
0x4A: ["CHAR", 1],
|
||||
0x50: ["SUM", 69],
|
||||
0x51: ["AVERAGEA", 69],
|
||||
0x52: ["COUNTA", 69],
|
||||
|
@ -9129,8 +9164,8 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
}
|
||||
|
||||
function parse_FORMULA_28(blob, length) {
|
||||
var o = parse_NUMBER_27(blob, 14);
|
||||
blob.l += length - 10; /* TODO: formula */
|
||||
var o = parse_NUMBER_27(blob, 12);
|
||||
blob.l += length - 12; /* TODO: formula */
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -9220,7 +9255,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
/*::[*/0x0030/*::]*/: { n:"UNFORMATTED" },
|
||||
/*::[*/0x0031/*::]*/: { n:"CURSORW12" },
|
||||
/*::[*/0x0032/*::]*/: { n:"WINDOW" },
|
||||
/*::[*/0x0033/*::]*/: { n:"STRING", f:parse_LABEL },
|
||||
/*::[*/0x0033/*::]*/: { n:"STRING", f:parse_STRING },
|
||||
/*::[*/0x0037/*::]*/: { n:"PASSWORD" },
|
||||
/*::[*/0x0038/*::]*/: { n:"LOCKED" },
|
||||
/*::[*/0x003C/*::]*/: { n:"QUERY" },
|
||||
|
@ -9244,6 +9279,7 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
/*::[*/0x0069/*::]*/: { n:"MRANGES??" },
|
||||
/*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
|
||||
/*::[*/0x00DE/*::]*/: { n:"SHEETNAMELP", f:parse_SHEETNAMELP },
|
||||
/*::[*/0x00FF/*::]*/: { n:"BOF", f:parseuint16 },
|
||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||
};
|
||||
|
||||
|
@ -9372,6 +9408,144 @@ var WK_ = /*#__PURE__*/(function() {
|
|||
/*::[*/0x6F44/*::]*/: { n:"??" },
|
||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||
};
|
||||
|
||||
/* QPW uses a different set of record types */
|
||||
function qpw_to_workbook_buf(d, opts)/*:Workbook*/ {
|
||||
prep_blob(d, 0);
|
||||
var o = opts || {};
|
||||
if(DENSE != null && o.dense == null) o.dense = DENSE;
|
||||
var s/*:Worksheet*/ = ((o.dense ? [] : {})/*:any*/);
|
||||
var SST = [], sname = "", formulae = [];
|
||||
var range = {s:{r:-1,c:-1}, e:{r:-1,c:-1}};
|
||||
var cnt = 0, type = 0, C = 0, R = 0;
|
||||
var wb = { SheetNames: [], Sheets: {} };
|
||||
outer: while(d.l < d.length) {
|
||||
var RT = d.read_shift(2), length = d.read_shift(2);
|
||||
var p = d.slice(d.l, d.l + length);
|
||||
prep_blob(p, 0);
|
||||
switch(RT) {
|
||||
case 0x01: /* BOF */
|
||||
if(p.read_shift(4) != 0x39575051) throw "Bad QPW9 BOF!";
|
||||
break;
|
||||
case 0x02: /* EOF */ break outer;
|
||||
|
||||
/* TODO: The behavior here should be consistent with Numbers: QP Notebook ~ .TN.SheetArchive, QP Sheet ~ .TST.TSTable */
|
||||
case 0x0401: /* BON */ break;
|
||||
case 0x0402: /* EON */ /* TODO: backfill missing sheets based on BON cnt */ break;
|
||||
|
||||
case 0x0407: { /* SST */
|
||||
p.l += 12;
|
||||
while(p.l < p.length) {
|
||||
cnt = p.read_shift(2);
|
||||
type = p.read_shift(1);
|
||||
SST.push(p.read_shift(cnt, 'cstr'));
|
||||
}
|
||||
} break;
|
||||
case 0x0408: { /* FORMULAE */
|
||||
//p.l += 12;
|
||||
//while(p.l < p.length) {
|
||||
// cnt = p.read_shift(2);
|
||||
// formulae.push(p.slice(p.l, p.l + cnt + 1)); p.l += cnt + 1;
|
||||
//}
|
||||
} break;
|
||||
|
||||
case 0x0601: { /* BOS */
|
||||
var sidx = p.read_shift(2);
|
||||
s = ((o.dense ? [] : {})/*:any*/);
|
||||
range.s.c = p.read_shift(2);
|
||||
range.e.c = p.read_shift(2);
|
||||
range.s.r = p.read_shift(4);
|
||||
range.e.r = p.read_shift(4);
|
||||
p.l += 4;
|
||||
if(p.l + 2 < p.length) {
|
||||
cnt = p.read_shift(2);
|
||||
type = p.read_shift(1);
|
||||
sname = cnt == 0 ? "" : p.read_shift(cnt, 'cstr');
|
||||
}
|
||||
if(!sname) sname = XLSX.utils.encode_col(sidx);
|
||||
/* TODO: backfill empty sheets */
|
||||
} break;
|
||||
case 0x0602: { /* EOS */
|
||||
/* NOTE: QP valid range A1:IV1000000 */
|
||||
if(range.s.c > 0xFF || range.s.r > 999999) break;
|
||||
if(range.e.c < range.s.c) range.e.c = range.s.c;
|
||||
if(range.e.r < range.s.r) range.e.r = range.s.r;
|
||||
s["!ref"] = encode_range(range);
|
||||
book_append_sheet(wb, s, sname); // TODO: a barrel roll
|
||||
} break;
|
||||
|
||||
case 0x0A01: { /* COL (like XLS Row, modulo the layout transposition) */
|
||||
C = p.read_shift(2);
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
R = p.read_shift(4);
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
R = p.read_shift(4);
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
} break;
|
||||
|
||||
case 0x0C01: { /* MulCells (like XLS MulRK, but takes advantage of common column data patterns) */
|
||||
R = p.read_shift(4), cnt = p.read_shift(4);
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.e.r < R + cnt - 1) range.e.r = R + cnt - 1;
|
||||
while(p.l < p.length) {
|
||||
var cell = { t: "z" };
|
||||
var flags = p.read_shift(1);
|
||||
if(flags & 0x80) p.l += 2;
|
||||
var mul = (flags & 0x40) ? p.read_shift(2) - 1: 0;
|
||||
switch(flags & 0x1F) {
|
||||
case 1: break;
|
||||
case 2: cell = { t: "n", v: p.read_shift(2) }; break;
|
||||
case 3: cell = { t: "n", v: p.read_shift(2, 'i') }; break;
|
||||
case 5: cell = { t: "n", v: p.read_shift(8, 'f') }; break;
|
||||
case 7: cell = { t: "s", v: SST[type = p.read_shift(4) - 1] }; break;
|
||||
case 8: cell = { t: "n", v: p.read_shift(8, 'f') }; p.l += 2; /* cell.f = formulae[p.read_shift(4)]; */ p.l += 4; break;
|
||||
default: throw "Unrecognized QPW cell type " + (flags & 0x1F);
|
||||
}
|
||||
var delta = 0;
|
||||
if(flags & 0x20) switch(flags & 0x1F) {
|
||||
case 2: delta = p.read_shift(2); break;
|
||||
case 3: delta = p.read_shift(2, 'i'); break;
|
||||
case 7: delta = p.read_shift(2); break;
|
||||
default: throw "Unsupported delta for QPW cell type " + (flags & 0x1F);
|
||||
}
|
||||
if(!(!o.sheetStubs && cell.t == "z")) {
|
||||
if(Array.isArray(s)) {
|
||||
if(!s[R]) s[R] = [];
|
||||
s[R][C] = cell;
|
||||
} else s[encode_cell({r:R, c:C})] = cell;
|
||||
}
|
||||
++R; --cnt;
|
||||
while(mul-- > 0 && cnt >= 0) {
|
||||
if(flags & 0x20) switch(flags & 0x1F) {
|
||||
case 2: cell = { t: "n", v: (cell.v + delta) & 0xFFFF }; break;
|
||||
case 3: cell = { t: "n", v: (cell.v + delta) & 0xFFFF }; if(cell.v > 0x7FFF) cell.v -= 0x10000; break;
|
||||
case 7: cell = { t: "s", v: SST[type = (type + delta) >>> 0] }; break;
|
||||
default: throw "Cannot apply delta for QPW cell type " + (flags & 0x1F);
|
||||
} else switch(flags & 0x1F) {
|
||||
case 1: cell = { t: "z" }; break;
|
||||
case 2: cell = { t: "n", v: p.read_shift(2) }; break;
|
||||
case 7: cell = { t: "s", v: SST[type = p.read_shift(4) - 1] }; break;
|
||||
default: throw "Cannot apply repeat for QPW cell type " + (flags & 0x1F);
|
||||
}
|
||||
if(!(!o.sheetStubs && cell.t == "z")) {
|
||||
if(Array.isArray(s)) {
|
||||
if(!s[R]) s[R] = [];
|
||||
s[R][C] = cell;
|
||||
} else s[encode_cell({r:R, c:C})] = cell;
|
||||
}
|
||||
++R; --cnt;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
d.l += length;
|
||||
}
|
||||
return wb;
|
||||
}
|
||||
|
||||
return {
|
||||
sheet_to_wk1: sheet_to_wk1,
|
||||
book_to_wk3: book_to_wk3,
|
||||
|
@ -9558,14 +9732,14 @@ function parse_si(x, opts) {
|
|||
/* 18.4.12 t ST_Xstring (Plaintext String) */
|
||||
// TODO: is whitespace actually valid here?
|
||||
if(x.match(/^\s*<(?:\w+:)?t[^>]*>/)) {
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""));
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""), true);
|
||||
z.r = utf8read(x);
|
||||
if(html) z.h = escapehtml(z.t);
|
||||
}
|
||||
/* 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,"")));
|
||||
z.t = unescapexml(utf8read((x.replace(sirphregex, '').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) */
|
||||
|
@ -9998,27 +10172,33 @@ var RTF = /*#__PURE__*/(function() {
|
|||
var o = opts || {};
|
||||
var ws/*:Worksheet*/ = o.dense ? ([]/*:any*/) : ({}/*:any*/);
|
||||
|
||||
var rows = str.match(/\\trowd.*?\\row\b/g);
|
||||
var rows = str.match(/\\trowd[\s\S]*?\\row\b/g);
|
||||
if(!rows.length) throw new Error("RTF missing table");
|
||||
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:rows.length - 1}}/*:any*/);
|
||||
rows.forEach(function(rowtf, R) {
|
||||
if(Array.isArray(ws)) ws[R] = [];
|
||||
var rtfre = /\\\w+\b/g;
|
||||
var rtfre = /\\[\w\-]+\b/g;
|
||||
var last_index = 0;
|
||||
var res;
|
||||
var C = -1;
|
||||
var payload = [];
|
||||
while((res = rtfre.exec(rowtf))) {
|
||||
var data = rowtf.slice(last_index, rtfre.lastIndex - res[0].length);
|
||||
if(data.charCodeAt(0) == 0x20) data = data.slice(1);
|
||||
if(data.length) payload.push(data);
|
||||
switch(res[0]) {
|
||||
case "\\cell":
|
||||
var data = rowtf.slice(last_index, rtfre.lastIndex - res[0].length);
|
||||
if(data[0] == " ") data = data.slice(1);
|
||||
++C;
|
||||
if(data.length) {
|
||||
if(payload.length) {
|
||||
// TODO: value parsing, including codepage adjustments
|
||||
var cell = {v: data, t:"s"};
|
||||
var cell = {v: payload.join(""), t:"s"};
|
||||
if(Array.isArray(ws)) ws[R][C] = cell;
|
||||
else ws[encode_cell({r:R, c:C})] = cell;
|
||||
}
|
||||
payload = [];
|
||||
break;
|
||||
case "\\par": // NOTE: Excel serializes both "\r" and "\n" as "\\par"
|
||||
payload.push("\n");
|
||||
break;
|
||||
}
|
||||
last_index = rtfre.lastIndex;
|
||||
|
@ -10044,7 +10224,7 @@ var RTF = /*#__PURE__*/(function() {
|
|||
var coord = encode_cell({r:R,c:C});
|
||||
cell = dense ? (ws[R]||[])[C]: ws[coord];
|
||||
if(!cell || cell.v == null && (!cell.f || cell.F)) continue;
|
||||
o.push(" " + (cell.w || (format_cell(cell), cell.w)));
|
||||
o.push(" " + (cell.w || (format_cell(cell), cell.w)).replace(/[\r\n]/g, "\\par "));
|
||||
o.push("\\cell");
|
||||
}
|
||||
o.push("\\pard\\intbl\\row");
|
||||
|
@ -14849,7 +15029,7 @@ function parse_ws_xml_sheetviews(data, wb/*:WBWBProps*/) {
|
|||
// $FlowIgnore
|
||||
if(+tag.zoomScale) wb.Views[i].zoom = +tag.zoomScale;
|
||||
// $FlowIgnore
|
||||
if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
if(tag.rightToLeft && parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
|
||||
});
|
||||
}
|
||||
function write_ws_xml_sheetviews(ws, opts, idx, wb)/*:string*/ {
|
||||
|
@ -14941,7 +15121,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||
if(opts.sheetRows && opts.sheetRows < tagr) continue;
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.hidden && parsexmlbool(tag.hidden)) { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
@ -14958,7 +15138,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||
if(opts && opts.cellStyles) {
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.hidden && parsexmlbool(tag.hidden)) { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
@ -14991,7 +15171,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||
if(opts.cellFormula) {
|
||||
if((cref=d.match(match_f))!= null && /*::cref != null && */cref[1] !== '') {
|
||||
/* TODO: match against XLSXFutureFunctions */
|
||||
p.f=unescapexml(utf8read(cref[1])).replace(/\r\n/g, "\n");
|
||||
p.f=unescapexml(utf8read(cref[1]), true);
|
||||
if(!opts.xlfn) p.f = _xlfn(p.f);
|
||||
if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="array"') > -1) {
|
||||
p.F = (d.match(refregex)||[])[1];
|
||||
|
@ -15045,7 +15225,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||
break;
|
||||
case 'str':
|
||||
p.t = "s";
|
||||
p.v = (p.v!=null) ? utf8read(p.v) : '';
|
||||
p.v = (p.v!=null) ? unescapexml(utf8read(p.v), true) : '';
|
||||
if(opts.cellHTML) p.h = escapehtml(p.v);
|
||||
break;
|
||||
case 'inlineStr':
|
||||
|
@ -16061,6 +16241,8 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||
|
||||
/* TODO: something useful -- this is a stub */
|
||||
function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, ws/*:Worksheet*/, last_seen/*:boolean*/)/*:boolean*/ {
|
||||
var o/*:any*/ = ({r:R, c:C}/*:any*/);
|
||||
if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
|
||||
if(cell.v === undefined) return false;
|
||||
var vv = "";
|
||||
switch(cell.t) {
|
||||
|
@ -16074,11 +16256,9 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
|
|||
case 'n': case 'e': vv = ''+cell.v; break;
|
||||
default: vv = cell.v; break;
|
||||
}
|
||||
var o/*:any*/ = ({r:R, c:C}/*:any*/);
|
||||
/* TODO: cell style */
|
||||
o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
if(cell.l) ws['!links'].push([encode_cell(o), cell.l]);
|
||||
if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
|
||||
switch(cell.t) {
|
||||
case 's': case 'str':
|
||||
if(opts.bookSST) {
|
||||
|
@ -23500,8 +23680,8 @@ function write_zip_xlsb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||
opts.Strings = /*::((*/[]/*:: :any):SST)*/; opts.Strings.Count = 0; opts.Strings.Unique = 0;
|
||||
if(browser_has_Map) opts.revStrings = new Map();
|
||||
else { opts.revStrings = {}; opts.revStrings.foo = []; delete opts.revStrings.foo; }
|
||||
var wbext = opts.bookType == "xlsb" ? "bin" : "xml";
|
||||
var vbafmt = VBAFMTS.indexOf(opts.bookType) > -1;
|
||||
var wbext = "bin";
|
||||
var vbafmt = true;
|
||||
var ct = new_ct();
|
||||
fix_write_opts(opts = opts || {});
|
||||
var zip = zip_new();
|
||||
|
@ -23701,10 +23881,10 @@ function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||
carr[1].forEach(function(c) { if(c.T == true) needtc = true; });
|
||||
});
|
||||
if(needtc) {
|
||||
cf = "xl/threadedComments/threadedComment" + rId + "." + wbext;
|
||||
cf = "xl/threadedComments/threadedComment" + rId + ".xml";
|
||||
zip_add_file(zip, cf, write_tcmnt_xml(comments, people, opts));
|
||||
ct.threadedcomments.push(cf);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + "." + wbext, RELS.TCMNT);
|
||||
add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + ".xml", RELS.TCMNT);
|
||||
}
|
||||
|
||||
cf = "xl/comments" + rId + "." + wbext;
|
||||
|
|
Loading…
Reference in New Issue