forked from sheetjs/sheetjs
version bump 0.11.5: "string" type
- proper JS string input / output type - bower main now uses full version (fixes #820 h/t @newmesiss) - DOM parse directly acts on innerHTML (see #779 h/t @danxfisher) - unicode core props and ext props (fixes #822 h/t @fureweb-com) - shim update for IE10/11 - test refresh and flow checks
This commit is contained in:
parent
1a8f97269e
commit
af3df44633
@ -4,6 +4,11 @@ This log is intended to keep track of backwards-incompatible changes, including
|
||||
but not limited to API changes and file location changes. Minor behavioral
|
||||
changes may not be included if they are not expected to break existing code.
|
||||
|
||||
## 0.11.5 (2017-09-30)
|
||||
|
||||
* Bower main script shifted to full version
|
||||
* 'binary' / 'string' encoding
|
||||
|
||||
## 0.11.3 (2017-08-19)
|
||||
|
||||
* XLS cell ixfe/XF removed
|
||||
|
7
Makefile
7
Makefile
@ -156,6 +156,9 @@ demo-systemjs: ## Run systemjs demo build
|
||||
|
||||
## Code Checking
|
||||
|
||||
.PHONY: fullint
|
||||
fullint: lint old-lint tslint flow mdlint ## Run all checks
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks
|
||||
@eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json
|
||||
@ -165,9 +168,9 @@ lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks
|
||||
old-lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
|
||||
@jshint --show-non-errors $(TARGET) $(AUXTARGETS)
|
||||
@jshint --show-non-errors $(CMDS)
|
||||
@jshint --show-non-errors package.json bower.json
|
||||
@jshint --show-non-errors package.json bower.json test.js
|
||||
@jshint --show-non-errors --extract=always $(HTMLLINT)
|
||||
@jscs $(TARGET) $(AUXTARGETS)
|
||||
@jscs $(TARGET) $(AUXTARGETS) test.js
|
||||
if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi
|
||||
|
||||
.PHONY: tslint
|
||||
|
42
README.md
42
README.md
@ -294,6 +294,9 @@ data and feeding it into the library. Here are a few common scenarios:
|
||||
<details>
|
||||
<summary><b>nodejs read a file</b> (click to show)</summary>
|
||||
|
||||
`readFile` is only available in server environments. Browsers have no API for
|
||||
reading arbitrary files given a path, so another strategy must be used.
|
||||
|
||||
```js
|
||||
if(typeof require !== 'undefined') XLSX = require('xlsx');
|
||||
var workbook = XLSX.readFile('test.xlsx');
|
||||
@ -305,11 +308,21 @@ var workbook = XLSX.readFile('test.xlsx');
|
||||
<details>
|
||||
<summary><b>Browser read TABLE element from page</b> (click to show)</summary>
|
||||
|
||||
The `table_to_book` and `table_to_sheet` utility functions take a DOM TABLE
|
||||
element and iterate through the child nodes.
|
||||
|
||||
```js
|
||||
var worksheet = XLSX.utils.table_to_book(document.getElementById('tableau'));
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
```
|
||||
|
||||
Alternatively, the HTML code can be extracted and parsed:
|
||||
|
||||
```js
|
||||
var htmlstr = document.getElementById('tableau').outerHTML;
|
||||
var worksheet = XLSX.read(htmlstr, {type:'string'});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@ -566,16 +579,35 @@ Assuming `workbook` is a workbook object:
|
||||
<details>
|
||||
<summary><b>nodejs write a file</b> (click to show)</summary>
|
||||
|
||||
`writeFile` is only available in server environments. Browsers have no API for
|
||||
writing arbitrary files given a path, so another strategy must be used.
|
||||
|
||||
```js
|
||||
if(typeof require !== 'undefined') XLSX = require('xlsx');
|
||||
/* output format determined by filename */
|
||||
XLSX.writeFile(workbook, 'out.xlsx');
|
||||
/* at this point, out.xlsx is a file that you can distribute */
|
||||
XLSX.writeFile(workbook, 'out.xlsb');
|
||||
/* at this point, out.xlsb is a file that you can distribute */
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Browser download file</b> (click to show)</summary>
|
||||
<summary><b>Browser add to web page</b> (click to show)</summary>
|
||||
|
||||
The `sheet_to_html` utility function generates HTML code that can be added to
|
||||
any DOM element.
|
||||
|
||||
```js
|
||||
var worksheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
var container = document.getElementById('tableau');
|
||||
container.innerHTML = XLSX.utils.sheet_to_html(worksheet);
|
||||
```
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Browser save file</b> (click to show)</summary>
|
||||
|
||||
Note: browser generates binary blob and forces a "download" to client. This
|
||||
example uses [FileSaver](https://github.com/eligrey/FileSaver.js/):
|
||||
@ -596,6 +628,7 @@ function s2ab(s) {
|
||||
/* the saveAs call downloads a file on the local machine */
|
||||
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "test.xlsx");
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@ -1442,6 +1475,7 @@ tells the library how to parse the data argument:
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (characters interpreted as UTF8) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"array"` | array: array of 8-bit unsigned int (byte `n` is `data[n]`) |
|
||||
| `"file"` | string: path of file that will be read (nodejs only) |
|
||||
@ -1574,10 +1608,10 @@ The `type` argument for `write` mirrors the `type` argument for `read`:
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (characters interpreted as UTF8) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"file"` | string: path of file that will be created (nodejs only) |
|
||||
|
||||
|
||||
## Utility Functions
|
||||
|
||||
The `sheet_to_*` functions accept a worksheet and an optional options object.
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.11.4';
|
||||
XLSX.version = '0.11.5';
|
||||
|
@ -39,7 +39,7 @@ function getzipfile(zip, file/*:string*/) {
|
||||
return o;
|
||||
}
|
||||
|
||||
function getzipdata(zip, file/*:string*/, safe/*:?boolean*/) {
|
||||
function getzipdata(zip, file/*:string*/, safe/*:?boolean*/)/*:any*/ {
|
||||
if(!safe) return getdata(getzipfile(zip, file));
|
||||
if(!file) return null;
|
||||
try { return getzipdata(zip, file); } catch(e) { return null; }
|
||||
|
@ -101,6 +101,31 @@ var utf8read/*:StringConv*/ = function utf8reada(orig) {
|
||||
return out;
|
||||
};
|
||||
|
||||
var utf8write/*:StringConv*/ = function(orig) {
|
||||
var out = [], i = 0, c = 0, d = 0;
|
||||
while(i < orig.length) {
|
||||
c = orig.charCodeAt(i++);
|
||||
switch(true) {
|
||||
case c < 128: out.push(String.fromCharCode(c)); break;
|
||||
case c < 2048:
|
||||
out.push(String.fromCharCode(192 + (c >> 6)));
|
||||
out.push(String.fromCharCode(128 + (c & 63)));
|
||||
break;
|
||||
case c >= 55296 && c < 57344:
|
||||
c -= 55296; d = orig.charCodeAt(i++) - 56320 + (c<<10);
|
||||
out.push(String.fromCharCode(240 + ((d >>18) & 7)));
|
||||
out.push(String.fromCharCode(144 + ((d >>12) & 63)));
|
||||
out.push(String.fromCharCode(128 + ((d >> 6) & 63)));
|
||||
out.push(String.fromCharCode(128 + (d & 63)));
|
||||
break;
|
||||
default:
|
||||
out.push(String.fromCharCode(224 + (c >> 12)));
|
||||
out.push(String.fromCharCode(128 + ((c >> 6) & 63)));
|
||||
out.push(String.fromCharCode(128 + (c & 63)));
|
||||
}
|
||||
}
|
||||
return out.join("");
|
||||
};
|
||||
|
||||
if(has_buf) {
|
||||
var utf8readb = function utf8readb(data) {
|
||||
@ -124,6 +149,8 @@ if(has_buf) {
|
||||
// $FlowIgnore
|
||||
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
|
||||
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
|
||||
|
||||
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
|
||||
}
|
||||
|
||||
// matches <foo>...</foo> extracts content
|
||||
@ -136,6 +163,10 @@ var matchtag = (function() {
|
||||
};
|
||||
})();
|
||||
|
||||
function htmldecode(str/*:string*/)/*:string*/ {
|
||||
return str.trim().replace(/\s+/g, " ").replace(/<\s*[bB][rR]\s*\/?/g,"\n").replace(/<[^>]*>/g,"").replace(/ /g, " ");
|
||||
}
|
||||
|
||||
var vtregex = (function(){ var vt_cache = {};
|
||||
return function vt_regex(bt) {
|
||||
if(vt_cache[bt] !== undefined) return vt_cache[bt];
|
||||
|
@ -1,4 +1,4 @@
|
||||
function read_double_le(b, idx/*:number*/)/*:number*/ {
|
||||
function read_double_le(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ {
|
||||
var s = 1 - 2 * (b[idx + 7] >>> 7);
|
||||
var e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f);
|
||||
var m = (b[idx+6]&0x0f);
|
||||
@ -9,7 +9,7 @@ function read_double_le(b, idx/*:number*/)/*:number*/ {
|
||||
return s * Math.pow(2, e - 52) * m;
|
||||
}
|
||||
|
||||
function write_double_le(b, v/*:number*/, idx/*:number*/) {
|
||||
function write_double_le(b/*:RawBytes|CFBlob*/, v/*:number*/, idx/*:number*/) {
|
||||
var bs = ((v < 0 || 1/v == -Infinity) ? 1 : 0) << 7, e = 0, m = 0;
|
||||
var av = bs ? -v : v;
|
||||
if(!isFinite(av)) { e = 0x7ff; m = isNaN(v) ? 0x6969 : 0; }
|
||||
@ -25,61 +25,61 @@ function write_double_le(b, v/*:number*/, idx/*:number*/) {
|
||||
b[idx + 7] = (e >> 4) | bs;
|
||||
}
|
||||
|
||||
var __toBuffer, ___toBuffer;
|
||||
__toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var __utf16le, ___utf16le;
|
||||
__utf16le = ___utf16le = function utf16le_(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var ___toBuffer = __toBuffer;
|
||||
var __utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var ___utf16le = __utf16le;
|
||||
var __hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };
|
||||
var ___hexlify = __hexlify;
|
||||
var __utf8, ___utf8;
|
||||
__utf8 = ___utf8 = function(b,s,e) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
|
||||
var __lpstr, ___lpstr;
|
||||
__lpstr = ___lpstr = function lpstr_(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __lpwstr, ___lpwstr;
|
||||
__lpwstr = ___lpwstr = function lpwstr_(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
|
||||
var ___utf8 = __utf8;
|
||||
var __lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpstr = __lpstr;
|
||||
var __lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpwstr = __lpwstr;
|
||||
var __lpp4, ___lpp4;
|
||||
__lpp4 = ___lpp4 = function lpp4_(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : "";};
|
||||
var __8lpp4, ___8lpp4;
|
||||
__8lpp4 = ___8lpp4 = function lpp4_8(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
|
||||
__lpp4 = ___lpp4 = function lpp4_(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : "";};
|
||||
var __8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
|
||||
var ___8lpp4 = __8lpp4;
|
||||
var __double, ___double;
|
||||
__double = ___double = function(b, idx) { return read_double_le(b, idx);};
|
||||
|
||||
__double = ___double = function(b/*:RawBytes|CFBlob*/, idx/*:number*/) { return read_double_le(b, idx);};
|
||||
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
|
||||
if(has_buf/*:: && typeof Buffer != 'undefined'*/) {
|
||||
__utf16le = function utf16le_b(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b,i) { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
__utf8 = function utf8_b(b, s,e) { return b.toString('utf8',s,e); };
|
||||
|
||||
if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { return Buffer.isBuffer(b)/*:: && b instanceof Buffer*/ ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
__utf8 = function utf8_b(b/*:RawBytes|CFBlob*/, s/*:number*/, e/*:number*/) { return (Buffer.isBuffer(b)/*:: && (b instanceof Buffer)*/) ? b.toString('utf8',s,e) : __utf8(b,s,e); };
|
||||
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
|
||||
bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); };
|
||||
__double = function double_(b,i) { if(Buffer.isBuffer(b)/*::&& b instanceof Buffer*/) return b.readDoubleLE(i); return ___double(b,i); };
|
||||
__double = function double_(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(Buffer.isBuffer(b)/*::&& b instanceof Buffer*/) return b.readDoubleLE(i); return ___double(b,i); };
|
||||
is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
|
||||
}
|
||||
|
||||
/* from js-xls */
|
||||
if(typeof cptable !== 'undefined') {
|
||||
__utf16le = function(b,s,e) { return cptable.utils.decode(1200, b.slice(s,e)); };
|
||||
__utf8 = function(b,s,e) { return cptable.utils.decode(65001, b.slice(s,e)); };
|
||||
__lpstr = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpwstr = function(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
|
||||
__lpp4 = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
|
||||
__8lpp4 = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)); };
|
||||
__utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(65001, b.slice(s,e)); };
|
||||
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
|
||||
__lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
|
||||
__8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
|
||||
}
|
||||
|
||||
var __readUInt8 = function(b, idx/*:number*/)/*:number*/ { return b[idx]; };
|
||||
var __readUInt16LE = function(b, idx/*:number*/)/*:number*/ { return b[idx+1]*(1<<8)+b[idx]; };
|
||||
var __readInt16LE = function(b, idx/*:number*/)/*:number*/ { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
|
||||
var __readUInt32LE = function(b, idx/*:number*/)/*:number*/ { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
|
||||
var __readInt32LE = function(b, idx/*:number*/)/*:number*/ { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
|
||||
var __readUInt8 = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx]; };
|
||||
var __readUInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx+1]*(1<<8)+b[idx]; };
|
||||
var __readInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
|
||||
var __readUInt32LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
|
||||
var __readInt32LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
|
||||
|
||||
var ___unhexlify = function(s) { return s.match(/../g).map(function(x) { return parseInt(x,16);}); };
|
||||
var __unhexlify = typeof Buffer !== "undefined" ? function(s) { return Buffer.isBuffer(s) ? new Buffer(s, 'hex') : ___unhexlify(s); } : ___unhexlify;
|
||||
var ___unhexlify = function(s/*:string*/)/*:Array<number>*/ { return (s.match(/../g)||[]).map(function(x) { return parseInt(x,16);}); };
|
||||
var __unhexlify = typeof Buffer !== "undefined" ? function(s/*:string*/)/*:Array<number>|Buffer*/ { return Buffer.isBuffer(s) ? new Buffer(s, 'hex') : ___unhexlify(s); } : ___unhexlify;
|
||||
|
||||
function ReadShift(size/*:number*/, t/*:?string*/) {
|
||||
var o="", oI, oR, oo=[], w, vv, i, loc;
|
||||
function ReadShift(size/*:number*/, t/*:?string*/)/*:number|string*/ {
|
||||
var o="", oI/*:: :number = 0*/, oR, oo=[], w, vv, i, loc;
|
||||
switch(t) {
|
||||
case 'dbcs':
|
||||
loc = this.l;
|
||||
@ -151,11 +151,11 @@ function ReadShift(size/*:number*/, t/*:?string*/) {
|
||||
this.l+=size; return o;
|
||||
}
|
||||
|
||||
var __writeUInt16LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
|
||||
var __writeUInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };
|
||||
var __writeInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
|
||||
var __writeUInt32LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };
|
||||
var __writeInt32LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
|
||||
var __writeUInt16LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
|
||||
|
||||
function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/) {
|
||||
function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/)/*:any*/ {
|
||||
var size = 0, i = 0;
|
||||
if(f === 'dbcs') {
|
||||
/*:: if(typeof val !== 'string') throw new Error("unreachable"); */
|
||||
@ -171,6 +171,7 @@ function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/) {
|
||||
this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;
|
||||
} return this;
|
||||
} else if(f === 'utf16le') {
|
||||
/*:: if(typeof val !== "string") throw new Error("unreachable"); */
|
||||
var end/*:number*/ = this.l + t;
|
||||
for(i = 0; i < Math.min(val.length, t); ++i) {
|
||||
var cc = val.charCodeAt(i);
|
||||
@ -192,20 +193,20 @@ function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/) {
|
||||
this.l += size; return this;
|
||||
}
|
||||
|
||||
function CheckField(hexstr, fld) {
|
||||
function CheckField(hexstr/*:string*/, fld/*:string*/)/*:void*/ {
|
||||
var m = __hexlify(this,this.l,hexstr.length>>1);
|
||||
if(m !== hexstr) throw fld + 'Expected ' + hexstr + ' saw ' + m;
|
||||
if(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);
|
||||
this.l += hexstr.length>>1;
|
||||
}
|
||||
|
||||
function prep_blob(blob, pos/*:number*/) {
|
||||
function prep_blob(blob, pos/*:number*/)/*:void*/ {
|
||||
blob.l = pos;
|
||||
blob.read_shift = ReadShift;
|
||||
blob.read_shift = /*::(*/ReadShift/*:: :any)*/;
|
||||
blob.chk = CheckField;
|
||||
blob.write_shift = WriteShift;
|
||||
}
|
||||
|
||||
function parsenoop(blob, length/*:number*/) { blob.l += length; }
|
||||
function parsenoop(blob, length/*:: :number, opts?:any */) { blob.l += length; }
|
||||
function parsenooplog(blob, length/*:number*/) { if(typeof console != 'undefined') console.log(blob.slice(blob.l, blob.l + length)); blob.l += length; }
|
||||
|
||||
function writenoop(blob, length/*:number*/) { blob.l += length; }
|
||||
|
@ -33,6 +33,7 @@ var CORE_PROPS_REGEX/*:Array<RegExp>*/ = (function() {
|
||||
|
||||
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]);
|
||||
|
@ -19,6 +19,7 @@ RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relatio
|
||||
|
||||
function parse_ext_props(data, p, opts) {
|
||||
var q = {}; if(!p) p = {};
|
||||
data = utf8read(data);
|
||||
|
||||
EXT_PROPS.forEach(function(f) {
|
||||
switch(f[2]) {
|
||||
|
@ -193,7 +193,7 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
case 1252:
|
||||
case 65000: case -536:
|
||||
case 65001: case -535:
|
||||
set_cp(CodePage = PropH[piddsi.n]); break;
|
||||
set_cp(CodePage = PropH[piddsi.n]>>>0 & 0xFFFF); break;
|
||||
default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
|
||||
}
|
||||
} else {
|
||||
@ -235,6 +235,7 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
/* [MS-OLEPS] 2.21 PropertySetStream */
|
||||
function parse_PropertySetStream(file, PIDSI) {
|
||||
var blob = file.content;
|
||||
if(!blob) return ({}/*:any*/);
|
||||
prep_blob(blob, 0);
|
||||
|
||||
var NumSets, FMTID0, FMTID1, Offset0, Offset1 = 0;
|
||||
|
@ -7,7 +7,7 @@ function parse_XLSCell(blob, length)/*:Cell*/ {
|
||||
var ixfe = blob.read_shift(2);
|
||||
return ({r:rw, c:col, ixfe:ixfe}/*:any*/);
|
||||
}
|
||||
function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:number*/, o) {
|
||||
function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:?number*/, o) {
|
||||
if(!o) o = new_buf(6);
|
||||
o.write_shift(2, R);
|
||||
o.write_shift(2, C);
|
||||
|
@ -341,7 +341,7 @@ var SYLK = (function() {
|
||||
|
||||
function sheet_to_sylk(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
|
||||
var preamble/*:Array<string>*/ = ["ID;PWXL;N;E"], o/*:Array<string>*/ = [];
|
||||
var r = decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
var RS = "\r\n";
|
||||
|
||||
@ -425,7 +425,7 @@ var DIF = (function() {
|
||||
};
|
||||
return function sheet_to_dif(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
|
||||
var o/*:Array<string>*/ = [];
|
||||
var r = decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
push_field(o, "TABLE", 0, 1, "sheetjs");
|
||||
push_field(o, "VECTORS", 0, r.e.r - r.s.r + 1,"");
|
||||
@ -541,6 +541,7 @@ var PRN = (function() {
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length == 0) cell.t = 'z';
|
||||
else if(o.raw) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.trim().length == 0) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.charCodeAt(0) == 0x3D) {
|
||||
if(s.charCodeAt(1) == 0x22 && s.charCodeAt(s.length - 1) == 0x22) { cell.t = 's'; cell.v = s.slice(2,-1).replace(/""/g,'"'); }
|
||||
else if(fuzzyfmla(s)) { cell.t = 'n'; cell.f = s.substr(1); }
|
||||
@ -586,12 +587,13 @@ var PRN = (function() {
|
||||
}
|
||||
|
||||
function prn_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
|
||||
var str = "", bytes = firstbyte(d, opts);
|
||||
var str = "", bytes = opts.type == 'string' ? [0,0,0,0] : firstbyte(d, opts);
|
||||
switch(opts.type) {
|
||||
case 'base64': str = Base64.decode(d); break;
|
||||
case 'binary': str = d; break;
|
||||
case 'buffer': str = d.toString('binary'); break;
|
||||
case 'array': str = cc2str(d); break;
|
||||
case 'string': str = d; break;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
|
||||
@ -602,7 +604,7 @@ var PRN = (function() {
|
||||
|
||||
function sheet_to_prn(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
|
||||
var o/*:Array<string>*/ = [];
|
||||
var r = decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
var oo = [];
|
||||
|
@ -655,7 +655,7 @@ function parse_Rgce(blob, length, opts) {
|
||||
return ptgs;
|
||||
}
|
||||
|
||||
function stringify_array(f) {
|
||||
function stringify_array(f)/*:string*/ {
|
||||
var o = [];
|
||||
for(var i = 0; i < f.length; ++i) {
|
||||
var x = f[i], r = [];
|
||||
@ -701,7 +701,7 @@ function get_ixti_raw(supbooks, ixti/*:number*/, opts)/*:string*/ {
|
||||
function get_ixti(supbooks, ixti/*:number*/, opts)/*:string*/ {
|
||||
return formula_quote_sheet_name(get_ixti_raw(supbooks, ixti, opts));
|
||||
}
|
||||
function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, opts) {
|
||||
function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, opts)/*:string*/ {
|
||||
//console.log(formula);
|
||||
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
|
||||
var stack/*:Array<string>*/ = [], e1, e2, type, c/*:CellAddress*/, ixti=0, nameidx=0, r, sname="";
|
||||
@ -793,7 +793,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
case 'PtgFuncVar': /* 2.5.198.63 */
|
||||
//console.log(f[1]);
|
||||
/* f[1] = [argc, func, type] */
|
||||
var argc/*:number*/ = f[1][0], func/*:string*/ = f[1][1];
|
||||
var argc/*:number*/ = (f[1][0]/*:any*/), func/*:string*/ = (f[1][1]/*:any*/);
|
||||
if(!argc) argc = 0;
|
||||
var args = argc == 0 ? [] : stack.slice(-argc);
|
||||
stack.length -= argc;
|
||||
|
@ -452,7 +452,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
case 's': sstr = strs[val[1]]; p.v = sstr.t; p.r = sstr.r; break;
|
||||
case 'b': p.v = val[1] ? true : false; break;
|
||||
case 'e': p.v = val[1]; if(opts.cellText !== false) p.w = BErr[p.v]; break;
|
||||
case 'str': p.t = 's'; p.v = utf8read(val[1]); break;
|
||||
case 'str': p.t = 's'; p.v = val[1]; break;
|
||||
}
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.numFmtId,null,opts, themes, styles);
|
||||
C = val[0].c;
|
||||
|
@ -174,7 +174,10 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
||||
var opts = _opts || {};
|
||||
make_ssf(SSF);
|
||||
var str = debom(xlml_normalize(d));
|
||||
if(opts && opts.type == 'binary' && typeof cptable !== 'undefined') str = cptable.utils.decode(65001, char_codes(str));
|
||||
if(opts.type == 'binary' || opts.type == 'base64') {
|
||||
if(typeof cptable !== 'undefined') str = cptable.utils.decode(65001, char_codes(str));
|
||||
else str = utf8read(str);
|
||||
}
|
||||
var opening = str.slice(0, 1024).toLowerCase(), ishtml = false;
|
||||
if(opening.indexOf("<?xml") == -1) ["html", "table", "head", "meta", "script", "style", "div"].forEach(function(tag) { if(opening.indexOf("<" + tag) >= 0) ishtml = true; });
|
||||
if(ishtml) return HTML_.to_workbook(str, opts);
|
||||
@ -1001,12 +1004,6 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{
|
||||
case 's': t = 'String'; p = escapexml(cell.v||""); break;
|
||||
}
|
||||
var _v = (cell.v != null ? p : "");
|
||||
if(opts && opts.type == 'binary' && typeof cptable !== 'undefined' && cell.t == 's') {
|
||||
_v = cptable.utils.encode(65001, _v);
|
||||
var __v = "";
|
||||
for(var __i = 0; __i < _v.length; ++__i) __v += String.fromCharCode(_v[__i]);
|
||||
_v = __v;
|
||||
}
|
||||
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
|
||||
|
||||
if((cell.c||[]).length > 0) m += write_ws_xlml_comment(cell.c);
|
||||
|
@ -1,7 +1,8 @@
|
||||
/* [MS-OLEDS] 2.3.8 CompObjStream */
|
||||
function parse_compobj(obj) {
|
||||
function parse_compobj(obj/*:CFBEntry*/) {
|
||||
var v = {};
|
||||
var o = obj.content;
|
||||
/*:: if(o == null) return; */
|
||||
|
||||
/* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */
|
||||
var l = 28, m;
|
||||
@ -819,25 +820,31 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
}
|
||||
|
||||
/* TODO: WTF */
|
||||
function parse_props(cfb) {
|
||||
function parse_props(cfb/*:CFBContainer*/, props, o) {
|
||||
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
|
||||
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
|
||||
if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {/* empty */}
|
||||
if(DSI) try {
|
||||
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI);
|
||||
for(var d in DocSummary) props[d] = DocSummary[d];
|
||||
} catch(e) {if(o.WTF == 2) throw e;/* empty */}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
|
||||
var SI = CFB.find(cfb, '!SummaryInformation');
|
||||
if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {/* empty */}
|
||||
if(SI) try {
|
||||
var Summary = parse_PropertySetStream(SI, SummaryPIDSI);
|
||||
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
|
||||
} catch(e) {if(o.WTF == 2) throw e;/* empty */}
|
||||
}
|
||||
|
||||
function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(!options) options = {};
|
||||
fix_read_opts(options);
|
||||
reset_cp();
|
||||
var CompObj, Summary, WB/*:?any*/;
|
||||
var CompObj/*:?CFBEntry*/, Summary, WB/*:?any*/;
|
||||
if(cfb.FullPaths) {
|
||||
CompObj = CFB.find(cfb, '!CompObj');
|
||||
Summary = CFB.find(cfb, '!SummaryInformation');
|
||||
WB = CFB.find(cfb, '/Workbook');
|
||||
WB = CFB.find(cfb, '/Workbook') || CFB.find(cfb, '/Book');
|
||||
} else {
|
||||
switch(options.type) {
|
||||
case 'base64': cfb = s2a(Base64.decode(cfb)); break;
|
||||
@ -848,26 +855,24 @@ if(cfb.FullPaths) {
|
||||
prep_blob(cfb, 0);
|
||||
WB = ({content: cfb}/*:any*/);
|
||||
}
|
||||
if(!WB) WB = CFB.find(cfb, '/Book');
|
||||
var CompObjP, SummaryP, WorkbookP/*:Workbook*/;
|
||||
var CompObjP, SummaryP, WorkbookP/*:: :Workbook = XLSX.utils.book_new(); */;
|
||||
|
||||
var _data/*:?any*/;
|
||||
if(CompObj) CompObjP = parse_compobj(CompObj);
|
||||
if(options.bookProps && !options.bookSheets) WorkbookP = ({}/*:any*/);
|
||||
else {
|
||||
else/*:: if(cfb instanceof CFBContainer) */ {
|
||||
var T = has_buf ? 'buffer' : 'array';
|
||||
if(WB && WB.content) WorkbookP = parse_workbook(WB.content, options);
|
||||
/* Quattro Pro 7-8 */
|
||||
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
|
||||
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
/* Quattro Pro 9 */
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
else throw new Error("Cannot find Workbook stream");
|
||||
}
|
||||
|
||||
if(cfb.FullPaths) parse_props(cfb);
|
||||
|
||||
var props = {};
|
||||
for(var y in cfb.Summary) props[y] = cfb.Summary[y];
|
||||
for(y in cfb.DocSummary) props[y] = cfb.DocSummary[y];
|
||||
if(cfb.FullPaths) parse_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options);
|
||||
|
||||
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
|
||||
if(options.bookFiles) WorkbookP.cfb = cfb;
|
||||
/*WorkbookP.CompObjP = CompObjP; // TODO: storage? */
|
||||
|
@ -1,5 +1,5 @@
|
||||
function write_biff_rec(ba/*:BufArray*/, type/*:number|string*/, payload, length/*:?number*/) {
|
||||
var t/*:number*/ = +type || +XLSRE[type];
|
||||
var t/*:number*/ = +type || +XLSRE[/*::String(*/type/*::)*/];
|
||||
if(isNaN(t)) return;
|
||||
var len = length || (payload||[]).length || 0;
|
||||
var o = ba.next(4 + len);
|
||||
|
@ -30,7 +30,7 @@ var HTML_ = (function() {
|
||||
if((RS = +tag.rowspan)>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
|
||||
/* TODO: generate stub cells */
|
||||
if(!m.length) { C += CS; continue; }
|
||||
m = unescapexml(m).replace(/[\r\n]/g,"");
|
||||
m = htmldecode(unescapexml(m));
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
@ -38,7 +38,7 @@ var HTML_ = (function() {
|
||||
if(opts.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
if(!m.length){}
|
||||
else if(opts.raw) ws[R][C] = {t:'s', v:m};
|
||||
else if(opts.raw || !m.trim().length) ws[R][C] = {t:'s', v:m};
|
||||
else if(m === 'TRUE') ws[R][C] = {t:'b', v:true};
|
||||
else if(m === 'FALSE') ws[R][C] = {t:'b', v:false};
|
||||
else if(!isNaN(fuzzynum(m))) ws[R][C] = {t:'n', v:fuzzynum(m)};
|
||||
@ -48,6 +48,7 @@ var HTML_ = (function() {
|
||||
/* TODO: value parsing */
|
||||
if(!m.length){}
|
||||
else if(opts.raw) ws[coord] = {t:'s', v:m};
|
||||
else if(opts.raw || !m.trim().length) ws[coord] = {t:'s', v:m};
|
||||
else if(m === 'TRUE') ws[coord] = {t:'b', v:true};
|
||||
else if(m === 'FALSE') ws[coord] = {t:'b', v:false};
|
||||
else if(!isNaN(fuzzynum(m))) ws[coord] = {t:'n', v:fuzzynum(m)};
|
||||
@ -132,7 +133,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
|
||||
var row = rows[R];
|
||||
var elts = row.children;
|
||||
for(_C = C = 0; _C < elts.length; ++_C) {
|
||||
var elt = elts[_C], v = elts[_C].innerText || elts[_C].textContent || "";
|
||||
var elt = elts[_C], v = htmldecode(elts[_C].innerHTML);
|
||||
for(midx = 0; midx < merges.length; ++midx) {
|
||||
var m = merges[midx];
|
||||
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
|
||||
@ -144,6 +145,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
|
||||
if(v != null) {
|
||||
if(v.length == 0) o.t = 'z';
|
||||
else if(opts.raw){}
|
||||
else if(v.trim().length == 0) o.t = 's';
|
||||
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)};
|
||||
|
@ -464,7 +464,9 @@ function parse_ods(zip/*:ZIPFile*/, opts/*:?ParseOpts*/) {
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
var content = getzipstr(zip, 'content.xml');
|
||||
if(!content) throw new Error("Missing content.xml in " + (ods ? "ODS" : "UOF")+ " file");
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
var wb = parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
if(safegetzipfile(zip, 'meta.xml')) wb.Props = parse_core_props(getzipdata(zip, 'meta.xml'));
|
||||
return wb;
|
||||
}
|
||||
function parse_fods(data/*:string*/, opts/*:?ParseOpts*/) {
|
||||
return parse_content_xml(data, opts);
|
||||
|
@ -3,8 +3,7 @@ function get_sheet_type(n/*:string*/)/*:string*/ {
|
||||
if(RELS.CS && n == RELS.CS) return "chart";
|
||||
if(RELS.DS && n == RELS.DS) return "dialog";
|
||||
if(RELS.MS && n == RELS.MS) return "macro";
|
||||
if(!n || !n.length) return "sheet";
|
||||
return n;
|
||||
return (n && n.length) ? n : "sheet";
|
||||
}
|
||||
function safe_parse_wbrels(wbrels, sheets) {
|
||||
if(!wbrels) return 0;
|
||||
@ -88,10 +87,10 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
var props = {}, propdata = "";
|
||||
|
||||
if(dir.coreprops.length) {
|
||||
propdata = getzipstr(zip, strip_front_slash(dir.coreprops[0]), true);
|
||||
propdata = getzipdata(zip, strip_front_slash(dir.coreprops[0]), true);
|
||||
if(propdata) props = parse_core_props(propdata);
|
||||
if(dir.extprops.length !== 0) {
|
||||
propdata = getzipstr(zip, strip_front_slash(dir.extprops[0]), true);
|
||||
propdata = getzipdata(zip, strip_front_slash(dir.extprops[0]), true);
|
||||
if(propdata) parse_ext_props(propdata, props, opts);
|
||||
}
|
||||
}
|
||||
|
@ -60,13 +60,23 @@ function read_utf16(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ {
|
||||
return read_plaintext(d, o);
|
||||
}
|
||||
|
||||
function bstrify(data/*:string*/)/*:string*/ {
|
||||
return !data.match(/[^\x00-\x7F]/) ? data : utf8write(data);
|
||||
}
|
||||
|
||||
function read_prn(data, d, o, str) {
|
||||
if(str) { o.type = "string"; return PRN.to_workbook(data, o); }
|
||||
return PRN.to_workbook(d, o);
|
||||
}
|
||||
|
||||
function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
var zip, d = data, n=[0];
|
||||
var zip, d = data, n=[0], str = false;
|
||||
var o = opts||{};
|
||||
_ssfopts = {};
|
||||
if(o.dateNF) _ssfopts.dateNF = o.dateNF;
|
||||
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
|
||||
if(o.type == "file") { o.type = "buffer"; d = _fs.readFileSync(data); }
|
||||
if(o.type == "string") { str = true; o.type = "binary"; d = bstrify(data); }
|
||||
switch((n = firstbyte(d, o))[0]) {
|
||||
case 0xD0: return read_cfb(CFB.read(d, o), o);
|
||||
case 0x09: return parse_xlscfb(d, o);
|
||||
@ -74,7 +84,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
case 0x49: 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 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break;
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : PRN.to_workbook(d,o);
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
|
||||
case 0xFF: if(n[1] == 0xFE){ return read_utf16(d, o); } break;
|
||||
case 0x00: if(n[1] == 0x00 && n[2] >= 0x02 && n[3] == 0x00) return WK_.to_workbook(d, o); break;
|
||||
case 0x03: case 0x83: case 0x8B: return DBF.to_workbook(d, o);
|
||||
@ -83,7 +93,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
}
|
||||
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
|
||||
if(0x20>n[0]||n[0]>0x7F) throw new Error("Unsupported file " + n.join("|"));
|
||||
return PRN.to_workbook(d, o);
|
||||
return read_prn(data, d, o, str);
|
||||
}
|
||||
|
||||
function readFileSync(filename/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
|
@ -1,4 +1,4 @@
|
||||
function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
|
||||
var o = opts||{};
|
||||
var z = write_zip(wb, o);
|
||||
var oopts = {};
|
||||
@ -6,31 +6,51 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
switch(o.type) {
|
||||
case "base64": oopts.type = "base64"; break;
|
||||
case "binary": oopts.type = "string"; break;
|
||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + ' files');
|
||||
case "buffer":
|
||||
case "file": oopts.type = "nodebuffer"; break;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
if(o.type === "file") return _fs.writeFileSync(o.file, z.generate(oopts));
|
||||
return z.generate(oopts);
|
||||
var out = z.generate(oopts);
|
||||
// $FlowIgnore
|
||||
return o.type == "string" ? utf8read(out) : out;
|
||||
}
|
||||
|
||||
function write_cfb_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
function write_cfb_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
|
||||
var o = opts||{};
|
||||
var cfb/*:CFBContainer*/ = write_xlscfb(wb, o);
|
||||
switch(o.type) {
|
||||
case "base64": case "binary": break;
|
||||
case "buffer": case "array": o.type = ""; break;
|
||||
case "file": return _fs.writeFileSync(o.file, CFB.write(cfb, {type:'buffer'}));
|
||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + ' files');
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
return CFB.write(cfb, o);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_bstr_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/*:any*/ {
|
||||
if(!bom) bom = "";
|
||||
var o = bom + out;
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(utf8write(o));
|
||||
case "binary": return utf8write(o);
|
||||
case "string": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, o, 'utf8');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(o, 'utf8');
|
||||
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ {
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "string": return out; /* override in sheet_to_txt */
|
||||
case "file": return _fs.writeFileSync(opts.file, out, 'binary');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'binary');
|
||||
@ -41,27 +61,14 @@ function write_bstr_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_string_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, out, 'utf8');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_binary_type(out, opts/*:WriteOpts*/) {
|
||||
function write_binary_type(out, opts/*:WriteOpts*/)/*:any*/ {
|
||||
switch(opts.type) {
|
||||
case "string":
|
||||
case "base64":
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : bstr;
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : opts.type == 'string' ? utf8read(bstr) : bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
@ -77,14 +84,14 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
case 'slk':
|
||||
case 'sylk': return write_string_type(write_slk_str(wb, o), o);
|
||||
case 'html': return write_string_type(write_htm_str(wb, o), o);
|
||||
case 'txt': return write_bstr_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o);
|
||||
case 'txt': return write_stxt_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o, "\ufeff");
|
||||
case 'dif': return write_string_type(write_dif_str(wb, o), o);
|
||||
case 'prn': return write_string_type(write_prn_str(wb, o), o);
|
||||
case 'rtf': return write_string_type(write_rtf_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff3': if(!o.biff) o.biff = 3; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
|
||||
case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
|
||||
case 'biff4': if(!o.biff) o.biff = 4; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff5': if(!o.biff) o.biff = 5; return write_cfb_type(wb, o);
|
||||
case 'biff8':
|
||||
|
@ -129,8 +129,8 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
|
||||
function sheet_to_txt(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
|
||||
if(!opts) opts = {}; opts.FS = "\t"; opts.RS = "\n";
|
||||
var s = sheet_to_csv(sheet, opts);
|
||||
if(typeof cptable == 'undefined') return s;
|
||||
var o = cptable.utils.encode(1200, s);
|
||||
if(typeof cptable == 'undefined' || opts.type == 'string') return s;
|
||||
var o = cptable.utils.encode(1200, s, 'str');
|
||||
return "\xff\xfe" + o;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "js-xlsx",
|
||||
"homepage": "https://github.com/SheetJS/js-xlsx",
|
||||
"main": "dist/xlsx.core.min.js",
|
||||
"main": "dist/xlsx.full.min.js",
|
||||
"ignore": [
|
||||
"bin",
|
||||
"bits",
|
||||
|
24
dist/xlsx.core.min.js
vendored
24
dist/xlsx.core.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
vendored
2
dist/xlsx.core.min.map
vendored
File diff suppressed because one or more lines are too long
30
dist/xlsx.full.min.js
vendored
30
dist/xlsx.full.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
vendored
2
dist/xlsx.full.min.map
vendored
File diff suppressed because one or more lines are too long
230
dist/xlsx.js
vendored
230
dist/xlsx.js
vendored
@ -6,7 +6,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.11.4';
|
||||
XLSX.version = '0.11.5';
|
||||
var current_codepage = 1200;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -2039,6 +2039,31 @@ var utf8read = function utf8reada(orig) {
|
||||
return out;
|
||||
};
|
||||
|
||||
var utf8write = function(orig) {
|
||||
var out = [], i = 0, c = 0, d = 0;
|
||||
while(i < orig.length) {
|
||||
c = orig.charCodeAt(i++);
|
||||
switch(true) {
|
||||
case c < 128: out.push(String.fromCharCode(c)); break;
|
||||
case c < 2048:
|
||||
out.push(String.fromCharCode(192 + (c >> 6)));
|
||||
out.push(String.fromCharCode(128 + (c & 63)));
|
||||
break;
|
||||
case c >= 55296 && c < 57344:
|
||||
c -= 55296; d = orig.charCodeAt(i++) - 56320 + (c<<10);
|
||||
out.push(String.fromCharCode(240 + ((d >>18) & 7)));
|
||||
out.push(String.fromCharCode(144 + ((d >>12) & 63)));
|
||||
out.push(String.fromCharCode(128 + ((d >> 6) & 63)));
|
||||
out.push(String.fromCharCode(128 + (d & 63)));
|
||||
break;
|
||||
default:
|
||||
out.push(String.fromCharCode(224 + (c >> 12)));
|
||||
out.push(String.fromCharCode(128 + ((c >> 6) & 63)));
|
||||
out.push(String.fromCharCode(128 + (c & 63)));
|
||||
}
|
||||
}
|
||||
return out.join("");
|
||||
};
|
||||
|
||||
if(has_buf) {
|
||||
var utf8readb = function utf8readb(data) {
|
||||
@ -2062,6 +2087,8 @@ if(has_buf) {
|
||||
// $FlowIgnore
|
||||
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
|
||||
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
|
||||
|
||||
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
|
||||
}
|
||||
|
||||
// matches <foo>...</foo> extracts content
|
||||
@ -2074,6 +2101,10 @@ var matchtag = (function() {
|
||||
};
|
||||
})();
|
||||
|
||||
function htmldecode(str) {
|
||||
return str.trim().replace(/\s+/g, " ").replace(/<\s*[bB][rR]\s*\/?/g,"\n").replace(/<[^>]*>/g,"").replace(/ /g, " ");
|
||||
}
|
||||
|
||||
var vtregex = (function(){ var vt_cache = {};
|
||||
return function vt_regex(bt) {
|
||||
if(vt_cache[bt] !== undefined) return vt_cache[bt];
|
||||
@ -2169,37 +2200,37 @@ function write_double_le(b, v, idx) {
|
||||
b[idx + 7] = (e >> 4) | bs;
|
||||
}
|
||||
|
||||
var __toBuffer, ___toBuffer;
|
||||
__toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var __utf16le, ___utf16le;
|
||||
__utf16le = ___utf16le = function utf16le_(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var ___toBuffer = __toBuffer;
|
||||
var __utf16le = function(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var ___utf16le = __utf16le;
|
||||
var __hexlify = function(b,s,l) { var ss=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };
|
||||
var ___hexlify = __hexlify;
|
||||
var __utf8, ___utf8;
|
||||
__utf8 = ___utf8 = function(b,s,e) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
|
||||
var __lpstr, ___lpstr;
|
||||
__lpstr = ___lpstr = function lpstr_(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __lpwstr, ___lpwstr;
|
||||
__lpwstr = ___lpwstr = function lpwstr_(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __utf8 = function(b,s,e) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
|
||||
var ___utf8 = __utf8;
|
||||
var __lpstr = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpstr = __lpstr;
|
||||
var __lpwstr = function(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpwstr = __lpwstr;
|
||||
var __lpp4, ___lpp4;
|
||||
__lpp4 = ___lpp4 = function lpp4_(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : "";};
|
||||
var __8lpp4, ___8lpp4;
|
||||
__8lpp4 = ___8lpp4 = function lpp4_8(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
|
||||
var __8lpp4 = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
|
||||
var ___8lpp4 = __8lpp4;
|
||||
var __double, ___double;
|
||||
__double = ___double = function(b, idx) { return read_double_le(b, idx);};
|
||||
|
||||
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
|
||||
|
||||
if(has_buf) {
|
||||
__utf16le = function utf16le_b(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__utf16le = function(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b,i) { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
__utf8 = function utf8_b(b, s,e) { return b.toString('utf8',s,e); };
|
||||
__lpstr = function lpstr_b(b, i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b, i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b, i) { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b, i) { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
__utf8 = function utf8_b(b, s, e) { return (Buffer.isBuffer(b)) ? b.toString('utf8',s,e) : __utf8(b,s,e); };
|
||||
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
|
||||
bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); };
|
||||
__double = function double_(b,i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
|
||||
__double = function double_(b, i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
|
||||
is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
|
||||
}
|
||||
|
||||
@ -2219,7 +2250,7 @@ var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u
|
||||
var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
|
||||
var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
|
||||
|
||||
var ___unhexlify = function(s) { return s.match(/../g).map(function(x) { return parseInt(x,16);}); };
|
||||
var ___unhexlify = function(s) { return (s.match(/../g)||[]).map(function(x) { return parseInt(x,16);}); };
|
||||
var __unhexlify = typeof Buffer !== "undefined" ? function(s) { return Buffer.isBuffer(s) ? new Buffer(s, 'hex') : ___unhexlify(s); } : ___unhexlify;
|
||||
|
||||
function ReadShift(size, t) {
|
||||
@ -2295,9 +2326,9 @@ function ReadShift(size, t) {
|
||||
this.l+=size; return o;
|
||||
}
|
||||
|
||||
var __writeUInt16LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
|
||||
var __writeUInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };
|
||||
var __writeInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
|
||||
var __writeUInt16LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
|
||||
|
||||
function WriteShift(t, val, f) {
|
||||
var size = 0, i = 0;
|
||||
@ -2312,7 +2343,7 @@ for(i = 0; i != val.length; ++i) this[this.l + i] = val.charCodeAt(i) & 0xFF;
|
||||
this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;
|
||||
} return this;
|
||||
} else if(f === 'utf16le') {
|
||||
var end = this.l + t;
|
||||
var end = this.l + t;
|
||||
for(i = 0; i < Math.min(val.length, t); ++i) {
|
||||
var cc = val.charCodeAt(i);
|
||||
this[this.l++] = cc & 0xff;
|
||||
@ -2335,7 +2366,7 @@ this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;
|
||||
|
||||
function CheckField(hexstr, fld) {
|
||||
var m = __hexlify(this,this.l,hexstr.length>>1);
|
||||
if(m !== hexstr) throw fld + 'Expected ' + hexstr + ' saw ' + m;
|
||||
if(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);
|
||||
this.l += hexstr.length>>1;
|
||||
}
|
||||
|
||||
@ -3628,6 +3659,7 @@ var CORE_PROPS_REGEX = (function() {
|
||||
|
||||
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]);
|
||||
@ -3695,6 +3727,7 @@ RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relatio
|
||||
|
||||
function parse_ext_props(data, p, opts) {
|
||||
var q = {}; if(!p) p = {};
|
||||
data = utf8read(data);
|
||||
|
||||
EXT_PROPS.forEach(function(f) {
|
||||
switch(f[2]) {
|
||||
@ -4133,7 +4166,7 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
case 1252:
|
||||
case 65000: case -536:
|
||||
case 65001: case -535:
|
||||
set_cp(CodePage = PropH[piddsi.n]); break;
|
||||
set_cp(CodePage = PropH[piddsi.n]>>>0 & 0xFFFF); break;
|
||||
default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
|
||||
}
|
||||
} else {
|
||||
@ -4175,6 +4208,7 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
/* [MS-OLEPS] 2.21 PropertySetStream */
|
||||
function parse_PropertySetStream(file, PIDSI) {
|
||||
var blob = file.content;
|
||||
if(!blob) return ({});
|
||||
prep_blob(blob, 0);
|
||||
|
||||
var NumSets, FMTID0, FMTID1, Offset0, Offset1 = 0;
|
||||
@ -5685,7 +5719,7 @@ var SYLK = (function() {
|
||||
|
||||
function sheet_to_sylk(ws, opts) {
|
||||
var preamble = ["ID;PWXL;N;E"], o = [];
|
||||
var r = decode_range(ws['!ref']), cell;
|
||||
var r = safe_decode_range(ws['!ref']), cell;
|
||||
var dense = Array.isArray(ws);
|
||||
var RS = "\r\n";
|
||||
|
||||
@ -5769,7 +5803,7 @@ var DIF = (function() {
|
||||
};
|
||||
return function sheet_to_dif(ws, opts) {
|
||||
var o = [];
|
||||
var r = decode_range(ws['!ref']), cell;
|
||||
var r = safe_decode_range(ws['!ref']), cell;
|
||||
var dense = Array.isArray(ws);
|
||||
push_field(o, "TABLE", 0, 1, "sheetjs");
|
||||
push_field(o, "VECTORS", 0, r.e.r - r.s.r + 1,"");
|
||||
@ -5885,6 +5919,7 @@ var PRN = (function() {
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length == 0) cell.t = 'z';
|
||||
else if(o.raw) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.trim().length == 0) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.charCodeAt(0) == 0x3D) {
|
||||
if(s.charCodeAt(1) == 0x22 && s.charCodeAt(s.length - 1) == 0x22) { cell.t = 's'; cell.v = s.slice(2,-1).replace(/""/g,'"'); }
|
||||
else if(fuzzyfmla(s)) { cell.t = 'n'; cell.f = s.substr(1); }
|
||||
@ -5930,12 +5965,13 @@ var PRN = (function() {
|
||||
}
|
||||
|
||||
function prn_to_sheet(d, opts) {
|
||||
var str = "", bytes = firstbyte(d, opts);
|
||||
var str = "", bytes = opts.type == 'string' ? [0,0,0,0] : firstbyte(d, opts);
|
||||
switch(opts.type) {
|
||||
case 'base64': str = Base64.decode(d); break;
|
||||
case 'binary': str = d; break;
|
||||
case 'buffer': str = d.toString('binary'); break;
|
||||
case 'array': str = cc2str(d); break;
|
||||
case 'string': str = d; break;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
|
||||
@ -5946,7 +5982,7 @@ var PRN = (function() {
|
||||
|
||||
function sheet_to_prn(ws, opts) {
|
||||
var o = [];
|
||||
var r = decode_range(ws['!ref']), cell;
|
||||
var r = safe_decode_range(ws['!ref']), cell;
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
var oo = [];
|
||||
@ -9400,7 +9436,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
|
||||
case 'PtgFuncVar': /* 2.5.198.63 */
|
||||
//console.log(f[1]);
|
||||
/* f[1] = [argc, func, type] */
|
||||
var argc = f[1][0], func = f[1][1];
|
||||
var argc = (f[1][0]), func = (f[1][1]);
|
||||
if(!argc) argc = 0;
|
||||
var args = argc == 0 ? [] : stack.slice(-argc);
|
||||
stack.length -= argc;
|
||||
@ -11977,7 +12013,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) {
|
||||
case 's': sstr = strs[val[1]]; p.v = sstr.t; p.r = sstr.r; break;
|
||||
case 'b': p.v = val[1] ? true : false; break;
|
||||
case 'e': p.v = val[1]; if(opts.cellText !== false) p.w = BErr[p.v]; break;
|
||||
case 'str': p.t = 's'; p.v = utf8read(val[1]); break;
|
||||
case 'str': p.t = 's'; p.v = val[1]; break;
|
||||
}
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.numFmtId,null,opts, themes, styles);
|
||||
C = val[0].c;
|
||||
@ -13380,7 +13416,10 @@ function parse_xlml_xml(d, _opts) {
|
||||
var opts = _opts || {};
|
||||
make_ssf(SSF);
|
||||
var str = debom(xlml_normalize(d));
|
||||
if(opts && opts.type == 'binary' && typeof cptable !== 'undefined') str = cptable.utils.decode(65001, char_codes(str));
|
||||
if(opts.type == 'binary' || opts.type == 'base64') {
|
||||
if(typeof cptable !== 'undefined') str = cptable.utils.decode(65001, char_codes(str));
|
||||
else str = utf8read(str);
|
||||
}
|
||||
var opening = str.slice(0, 1024).toLowerCase(), ishtml = false;
|
||||
if(opening.indexOf("<?xml") == -1) ["html", "table", "head", "meta", "script", "style", "div"].forEach(function(tag) { if(opening.indexOf("<" + tag) >= 0) ishtml = true; });
|
||||
if(ishtml) return HTML_.to_workbook(str, opts);
|
||||
@ -14204,12 +14243,6 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
|
||||
case 's': t = 'String'; p = escapexml(cell.v||""); break;
|
||||
}
|
||||
var _v = (cell.v != null ? p : "");
|
||||
if(opts && opts.type == 'binary' && typeof cptable !== 'undefined' && cell.t == 's') {
|
||||
_v = cptable.utils.encode(65001, _v);
|
||||
var __v = "";
|
||||
for(var __i = 0; __i < _v.length; ++__i) __v += String.fromCharCode(_v[__i]);
|
||||
_v = __v;
|
||||
}
|
||||
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
|
||||
|
||||
if((cell.c||[]).length > 0) m += write_ws_xlml_comment(cell.c);
|
||||
@ -14297,8 +14330,7 @@ function write_xlml(wb, opts) {
|
||||
function parse_compobj(obj) {
|
||||
var v = {};
|
||||
var o = obj.content;
|
||||
|
||||
/* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */
|
||||
/* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */
|
||||
var l = 28, m;
|
||||
m = __lpstr(o, l);
|
||||
l += 4 + __readUInt32LE(o,l);
|
||||
@ -15113,14 +15145,20 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
||||
}
|
||||
|
||||
/* TODO: WTF */
|
||||
function parse_props(cfb) {
|
||||
function parse_props(cfb, props, o) {
|
||||
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
|
||||
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
|
||||
if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {/* empty */}
|
||||
if(DSI) try {
|
||||
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI);
|
||||
for(var d in DocSummary) props[d] = DocSummary[d];
|
||||
} catch(e) {if(o.WTF == 2) throw e;/* empty */}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
|
||||
var SI = CFB.find(cfb, '!SummaryInformation');
|
||||
if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {/* empty */}
|
||||
if(SI) try {
|
||||
var Summary = parse_PropertySetStream(SI, SummaryPIDSI);
|
||||
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
|
||||
} catch(e) {if(o.WTF == 2) throw e;/* empty */}
|
||||
}
|
||||
|
||||
function parse_xlscfb(cfb, options) {
|
||||
@ -15131,7 +15169,7 @@ var CompObj, Summary, WB;
|
||||
if(cfb.FullPaths) {
|
||||
CompObj = CFB.find(cfb, '!CompObj');
|
||||
Summary = CFB.find(cfb, '!SummaryInformation');
|
||||
WB = CFB.find(cfb, '/Workbook');
|
||||
WB = CFB.find(cfb, '/Workbook') || CFB.find(cfb, '/Book');
|
||||
} else {
|
||||
switch(options.type) {
|
||||
case 'base64': cfb = s2a(Base64.decode(cfb)); break;
|
||||
@ -15142,26 +15180,24 @@ if(cfb.FullPaths) {
|
||||
prep_blob(cfb, 0);
|
||||
WB = ({content: cfb});
|
||||
}
|
||||
if(!WB) WB = CFB.find(cfb, '/Book');
|
||||
var CompObjP, SummaryP, WorkbookP;
|
||||
|
||||
var _data;
|
||||
if(CompObj) CompObjP = parse_compobj(CompObj);
|
||||
if(options.bookProps && !options.bookSheets) WorkbookP = ({});
|
||||
else {
|
||||
var T = has_buf ? 'buffer' : 'array';
|
||||
if(WB && WB.content) WorkbookP = parse_workbook(WB.content, options);
|
||||
/* Quattro Pro 7-8 */
|
||||
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
|
||||
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
/* Quattro Pro 9 */
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
else throw new Error("Cannot find Workbook stream");
|
||||
}
|
||||
|
||||
if(cfb.FullPaths) parse_props(cfb);
|
||||
|
||||
var props = {};
|
||||
for(var y in cfb.Summary) props[y] = cfb.Summary[y];
|
||||
for(y in cfb.DocSummary) props[y] = cfb.DocSummary[y];
|
||||
if(cfb.FullPaths) parse_props(cfb, props, options);
|
||||
|
||||
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
|
||||
if(options.bookFiles) WorkbookP.cfb = cfb;
|
||||
/*WorkbookP.CompObjP = CompObjP; // TODO: storage? */
|
||||
@ -16688,7 +16724,7 @@ var HTML_ = (function() {
|
||||
if((RS = +tag.rowspan)>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
|
||||
/* TODO: generate stub cells */
|
||||
if(!m.length) { C += CS; continue; }
|
||||
m = unescapexml(m).replace(/[\r\n]/g,"");
|
||||
m = htmldecode(unescapexml(m));
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
@ -16696,7 +16732,7 @@ var HTML_ = (function() {
|
||||
if(opts.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
if(!m.length){}
|
||||
else if(opts.raw) ws[R][C] = {t:'s', v:m};
|
||||
else if(opts.raw || !m.trim().length) ws[R][C] = {t:'s', v:m};
|
||||
else if(m === 'TRUE') ws[R][C] = {t:'b', v:true};
|
||||
else if(m === 'FALSE') ws[R][C] = {t:'b', v:false};
|
||||
else if(!isNaN(fuzzynum(m))) ws[R][C] = {t:'n', v:fuzzynum(m)};
|
||||
@ -16706,6 +16742,7 @@ var HTML_ = (function() {
|
||||
/* TODO: value parsing */
|
||||
if(!m.length){}
|
||||
else if(opts.raw) ws[coord] = {t:'s', v:m};
|
||||
else if(opts.raw || !m.trim().length) ws[coord] = {t:'s', v:m};
|
||||
else if(m === 'TRUE') ws[coord] = {t:'b', v:true};
|
||||
else if(m === 'FALSE') ws[coord] = {t:'b', v:false};
|
||||
else if(!isNaN(fuzzynum(m))) ws[coord] = {t:'n', v:fuzzynum(m)};
|
||||
@ -16790,7 +16827,7 @@ function parse_dom_table(table, _opts) {
|
||||
var row = rows[R];
|
||||
var elts = row.children;
|
||||
for(_C = C = 0; _C < elts.length; ++_C) {
|
||||
var elt = elts[_C], v = elts[_C].innerText || elts[_C].textContent || "";
|
||||
var elt = elts[_C], v = htmldecode(elts[_C].innerHTML);
|
||||
for(midx = 0; midx < merges.length; ++midx) {
|
||||
var m = merges[midx];
|
||||
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
|
||||
@ -16802,6 +16839,7 @@ function parse_dom_table(table, _opts) {
|
||||
if(v != null) {
|
||||
if(v.length == 0) o.t = 'z';
|
||||
else if(opts.raw){}
|
||||
else if(v.trim().length == 0) o.t = 's';
|
||||
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)};
|
||||
@ -17291,7 +17329,9 @@ function parse_ods(zip, opts) {
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
var content = getzipstr(zip, 'content.xml');
|
||||
if(!content) throw new Error("Missing content.xml in " + (ods ? "ODS" : "UOF")+ " file");
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
var wb = parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
if(safegetzipfile(zip, 'meta.xml')) wb.Props = parse_core_props(getzipdata(zip, 'meta.xml'));
|
||||
return wb;
|
||||
}
|
||||
function parse_fods(data, opts) {
|
||||
return parse_content_xml(data, opts);
|
||||
@ -17558,8 +17598,7 @@ function get_sheet_type(n) {
|
||||
if(RELS.CS && n == RELS.CS) return "chart";
|
||||
if(RELS.DS && n == RELS.DS) return "dialog";
|
||||
if(RELS.MS && n == RELS.MS) return "macro";
|
||||
if(!n || !n.length) return "sheet";
|
||||
return n;
|
||||
return (n && n.length) ? n : "sheet";
|
||||
}
|
||||
function safe_parse_wbrels(wbrels, sheets) {
|
||||
if(!wbrels) return 0;
|
||||
@ -17643,10 +17682,10 @@ function parse_zip(zip, opts) {
|
||||
var props = {}, propdata = "";
|
||||
|
||||
if(dir.coreprops.length) {
|
||||
propdata = getzipstr(zip, strip_front_slash(dir.coreprops[0]), true);
|
||||
propdata = getzipdata(zip, strip_front_slash(dir.coreprops[0]), true);
|
||||
if(propdata) props = parse_core_props(propdata);
|
||||
if(dir.extprops.length !== 0) {
|
||||
propdata = getzipstr(zip, strip_front_slash(dir.extprops[0]), true);
|
||||
propdata = getzipdata(zip, strip_front_slash(dir.extprops[0]), true);
|
||||
if(propdata) parse_ext_props(propdata, props, opts);
|
||||
}
|
||||
}
|
||||
@ -17952,13 +17991,23 @@ function read_utf16(data, o) {
|
||||
return read_plaintext(d, o);
|
||||
}
|
||||
|
||||
function bstrify(data) {
|
||||
return !data.match(/[^\x00-\x7F]/) ? data : utf8write(data);
|
||||
}
|
||||
|
||||
function read_prn(data, d, o, str) {
|
||||
if(str) { o.type = "string"; return PRN.to_workbook(data, o); }
|
||||
return PRN.to_workbook(d, o);
|
||||
}
|
||||
|
||||
function readSync(data, opts) {
|
||||
var zip, d = data, n=[0];
|
||||
var zip, d = data, n=[0], str = false;
|
||||
var o = opts||{};
|
||||
_ssfopts = {};
|
||||
if(o.dateNF) _ssfopts.dateNF = o.dateNF;
|
||||
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
|
||||
if(o.type == "file") { o.type = "buffer"; d = _fs.readFileSync(data); }
|
||||
if(o.type == "string") { str = true; o.type = "binary"; d = bstrify(data); }
|
||||
switch((n = firstbyte(d, o))[0]) {
|
||||
case 0xD0: return read_cfb(CFB.read(d, o), o);
|
||||
case 0x09: return parse_xlscfb(d, o);
|
||||
@ -17966,7 +18015,7 @@ function readSync(data, opts) {
|
||||
case 0x49: 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 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break;
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : PRN.to_workbook(d,o);
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
|
||||
case 0xFF: if(n[1] == 0xFE){ return read_utf16(d, o); } break;
|
||||
case 0x00: if(n[1] == 0x00 && n[2] >= 0x02 && n[3] == 0x00) return WK_.to_workbook(d, o); break;
|
||||
case 0x03: case 0x83: case 0x8B: return DBF.to_workbook(d, o);
|
||||
@ -17975,7 +18024,7 @@ function readSync(data, opts) {
|
||||
}
|
||||
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
|
||||
if(0x20>n[0]||n[0]>0x7F) throw new Error("Unsupported file " + n.join("|"));
|
||||
return PRN.to_workbook(d, o);
|
||||
return read_prn(data, d, o, str);
|
||||
}
|
||||
|
||||
function readFileSync(filename, opts) {
|
||||
@ -17990,12 +18039,15 @@ function write_zip_type(wb, opts) {
|
||||
switch(o.type) {
|
||||
case "base64": oopts.type = "base64"; break;
|
||||
case "binary": oopts.type = "string"; break;
|
||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + ' files');
|
||||
case "buffer":
|
||||
case "file": oopts.type = "nodebuffer"; break;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
if(o.type === "file") return _fs.writeFileSync(o.file, z.generate(oopts));
|
||||
return z.generate(oopts);
|
||||
var out = z.generate(oopts);
|
||||
// $FlowIgnore
|
||||
return o.type == "string" ? utf8read(out) : out;
|
||||
}
|
||||
|
||||
function write_cfb_type(wb, opts) {
|
||||
@ -18005,16 +18057,33 @@ function write_cfb_type(wb, opts) {
|
||||
case "base64": case "binary": break;
|
||||
case "buffer": case "array": o.type = ""; break;
|
||||
case "file": return _fs.writeFileSync(o.file, CFB.write(cfb, {type:'buffer'}));
|
||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + ' files');
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
return CFB.write(cfb, o);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_bstr_type(out, opts) {
|
||||
function write_string_type(out, opts, bom) {
|
||||
if(!bom) bom = "";
|
||||
var o = bom + out;
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(utf8write(o));
|
||||
case "binary": return utf8write(o);
|
||||
case "string": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, o, 'utf8');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(o, 'utf8');
|
||||
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
function write_stxt_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "string": return out; /* override in sheet_to_txt */
|
||||
case "file": return _fs.writeFileSync(opts.file, out, 'binary');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'binary');
|
||||
@ -18024,28 +18093,15 @@ function write_bstr_type(out, opts) {
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_string_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, out, 'utf8');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_binary_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "string":
|
||||
case "base64":
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : bstr;
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : opts.type == 'string' ? utf8read(bstr) : bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
@ -18061,14 +18117,14 @@ function writeSync(wb, opts) {
|
||||
case 'slk':
|
||||
case 'sylk': return write_string_type(write_slk_str(wb, o), o);
|
||||
case 'html': return write_string_type(write_htm_str(wb, o), o);
|
||||
case 'txt': return write_bstr_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o);
|
||||
case 'txt': return write_stxt_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o, "\ufeff");
|
||||
case 'dif': return write_string_type(write_dif_str(wb, o), o);
|
||||
case 'prn': return write_string_type(write_prn_str(wb, o), o);
|
||||
case 'rtf': return write_string_type(write_rtf_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff3': if(!o.biff) o.biff = 3; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
|
||||
case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
|
||||
case 'biff4': if(!o.biff) o.biff = 4; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff5': if(!o.biff) o.biff = 5; return write_cfb_type(wb, o);
|
||||
case 'biff8':
|
||||
@ -18249,8 +18305,8 @@ function sheet_to_csv(sheet, opts) {
|
||||
function sheet_to_txt(sheet, opts) {
|
||||
if(!opts) opts = {}; opts.FS = "\t"; opts.RS = "\n";
|
||||
var s = sheet_to_csv(sheet, opts);
|
||||
if(typeof cptable == 'undefined') return s;
|
||||
var o = cptable.utils.encode(1200, s);
|
||||
if(typeof cptable == 'undefined' || opts.type == 'string') return s;
|
||||
var o = cptable.utils.encode(1200, s, 'str');
|
||||
return "\xff\xfe" + o;
|
||||
}
|
||||
|
||||
|
24
dist/xlsx.min.js
vendored
24
dist/xlsx.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
vendored
2
dist/xlsx.min.map
vendored
File diff suppressed because one or more lines are too long
@ -6,6 +6,9 @@ data and feeding it into the library. Here are a few common scenarios:
|
||||
<details>
|
||||
<summary><b>nodejs read a file</b> (click to show)</summary>
|
||||
|
||||
`readFile` is only available in server environments. Browsers have no API for
|
||||
reading arbitrary files given a path, so another strategy must be used.
|
||||
|
||||
```js
|
||||
if(typeof require !== 'undefined') XLSX = require('xlsx');
|
||||
var workbook = XLSX.readFile('test.xlsx');
|
||||
@ -17,11 +20,21 @@ var workbook = XLSX.readFile('test.xlsx');
|
||||
<details>
|
||||
<summary><b>Browser read TABLE element from page</b> (click to show)</summary>
|
||||
|
||||
The `table_to_book` and `table_to_sheet` utility functions take a DOM TABLE
|
||||
element and iterate through the child nodes.
|
||||
|
||||
```js
|
||||
var worksheet = XLSX.utils.table_to_book(document.getElementById('tableau'));
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
```
|
||||
|
||||
Alternatively, the HTML code can be extracted and parsed:
|
||||
|
||||
```js
|
||||
var htmlstr = document.getElementById('tableau').outerHTML;
|
||||
var worksheet = XLSX.read(htmlstr, {type:'string'});
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
@ -8,16 +8,35 @@ Assuming `workbook` is a workbook object:
|
||||
<details>
|
||||
<summary><b>nodejs write a file</b> (click to show)</summary>
|
||||
|
||||
`writeFile` is only available in server environments. Browsers have no API for
|
||||
writing arbitrary files given a path, so another strategy must be used.
|
||||
|
||||
```js
|
||||
if(typeof require !== 'undefined') XLSX = require('xlsx');
|
||||
/* output format determined by filename */
|
||||
XLSX.writeFile(workbook, 'out.xlsx');
|
||||
/* at this point, out.xlsx is a file that you can distribute */
|
||||
XLSX.writeFile(workbook, 'out.xlsb');
|
||||
/* at this point, out.xlsb is a file that you can distribute */
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Browser download file</b> (click to show)</summary>
|
||||
<summary><b>Browser add to web page</b> (click to show)</summary>
|
||||
|
||||
The `sheet_to_html` utility function generates HTML code that can be added to
|
||||
any DOM element.
|
||||
|
||||
```js
|
||||
var worksheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
var container = document.getElementById('tableau');
|
||||
container.innerHTML = XLSX.utils.sheet_to_html(worksheet);
|
||||
```
|
||||
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Browser save file</b> (click to show)</summary>
|
||||
|
||||
Note: browser generates binary blob and forces a "download" to client. This
|
||||
example uses [FileSaver](https://github.com/eligrey/FileSaver.js/):
|
||||
@ -38,6 +57,7 @@ function s2ab(s) {
|
||||
/* the saveAs call downloads a file on the local machine */
|
||||
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "test.xlsx");
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
@ -52,6 +52,7 @@ tells the library how to parse the data argument:
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (characters interpreted as UTF8) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"array"` | array: array of 8-bit unsigned int (byte `n` is `data[n]`) |
|
||||
| `"file"` | string: path of file that will be read (nodejs only) |
|
||||
|
@ -62,7 +62,7 @@ The `type` argument for `write` mirrors the `type` argument for `read`:
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (characters interpreted as UTF8) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"file"` | string: path of file that will be created (nodejs only) |
|
||||
|
||||
|
||||
|
@ -277,6 +277,9 @@ For parsing, the first step is to read the file. This involves acquiring the
|
||||
data and feeding it into the library. Here are a few common scenarios:
|
||||
|
||||
|
||||
`readFile` is only available in server environments. Browsers have no API for
|
||||
reading arbitrary files given a path, so another strategy must be used.
|
||||
|
||||
```js
|
||||
if(typeof require !== 'undefined') XLSX = require('xlsx');
|
||||
var workbook = XLSX.readFile('test.xlsx');
|
||||
@ -285,11 +288,21 @@ var workbook = XLSX.readFile('test.xlsx');
|
||||
|
||||
|
||||
|
||||
The `table_to_book` and `table_to_sheet` utility functions take a DOM TABLE
|
||||
element and iterate through the child nodes.
|
||||
|
||||
```js
|
||||
var worksheet = XLSX.utils.table_to_book(document.getElementById('tableau'));
|
||||
/* DO SOMETHING WITH workbook HERE */
|
||||
```
|
||||
|
||||
Alternatively, the HTML code can be extracted and parsed:
|
||||
|
||||
```js
|
||||
var htmlstr = document.getElementById('tableau').outerHTML;
|
||||
var worksheet = XLSX.read(htmlstr, {type:'string'});
|
||||
```
|
||||
|
||||
|
||||
|
||||
Note: for a more complete example that works in older browsers, check the demo
|
||||
@ -516,14 +529,30 @@ dissemination. The second step is to actual share the data with the end point.
|
||||
Assuming `workbook` is a workbook object:
|
||||
|
||||
|
||||
`writeFile` is only available in server environments. Browsers have no API for
|
||||
writing arbitrary files given a path, so another strategy must be used.
|
||||
|
||||
```js
|
||||
if(typeof require !== 'undefined') XLSX = require('xlsx');
|
||||
/* output format determined by filename */
|
||||
XLSX.writeFile(workbook, 'out.xlsx');
|
||||
/* at this point, out.xlsx is a file that you can distribute */
|
||||
XLSX.writeFile(workbook, 'out.xlsb');
|
||||
/* at this point, out.xlsb is a file that you can distribute */
|
||||
```
|
||||
|
||||
|
||||
|
||||
The `sheet_to_html` utility function generates HTML code that can be added to
|
||||
any DOM element.
|
||||
|
||||
```js
|
||||
var worksheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
var container = document.getElementById('tableau');
|
||||
container.innerHTML = XLSX.utils.sheet_to_html(worksheet);
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Note: browser generates binary blob and forces a "download" to client. This
|
||||
example uses [FileSaver](https://github.com/eligrey/FileSaver.js/):
|
||||
|
||||
@ -545,6 +574,7 @@ saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "test.xlsx");
|
||||
```
|
||||
|
||||
|
||||
|
||||
A complete example using XHR is [included in the XHR demo](demos/xhr/), along
|
||||
with examples for fetch and wrapper libraries. This example assumes the server
|
||||
can handle Base64-encoded files (see the demo for a basic nodejs server):
|
||||
@ -1325,6 +1355,7 @@ tells the library how to parse the data argument:
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (characters interpreted as UTF8) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"array"` | array: array of 8-bit unsigned int (byte `n` is `data[n]`) |
|
||||
| `"file"` | string: path of file that will be read (nodejs only) |
|
||||
@ -1451,10 +1482,10 @@ The `type` argument for `write` mirrors the `type` argument for `read`:
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: Base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (byte `n` is `data.charCodeAt(n)`) |
|
||||
| `"string"` | string: JS string (characters interpreted as UTF8) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"file"` | string: path of file that will be created (nodejs only) |
|
||||
|
||||
|
||||
## Utility Functions
|
||||
|
||||
The `sheet_to_*` functions accept a worksheet and an optional options object.
|
||||
|
@ -42,11 +42,15 @@ type SSFModule = {
|
||||
// ----------------------------------------------------------------------------
|
||||
// Note: The following override is needed because ReadShift includes more cases
|
||||
// ----------------------------------------------------------------------------
|
||||
type ReadShiftFunc = any;
|
||||
type WriteShiftFunc = any;
|
||||
|
||||
type CFBModule = {
|
||||
version:string;
|
||||
find:(cfb:CFBContainer, path:string)=>?CFBEntry;
|
||||
read:(blob:RawBytes|string, opts:CFBReadOpts)=>CFBContainer;
|
||||
write:(cfb:CFBContainer, opts:CFBWriteOpts)=>RawBytes|string;
|
||||
writeFile:(cfb:CFBContainer, filename:string, opts:CFBWriteOpts)=>void;
|
||||
parse:(file:RawBytes, opts:CFBReadOpts)=>CFBContainer;
|
||||
utils:CFBUtils;
|
||||
};
|
||||
@ -63,18 +67,21 @@ type RawBytes = Array<number> | Buffer | Uint8Array;
|
||||
|
||||
class CFBlobArray extends Array<number> {
|
||||
l:number;
|
||||
write_shift:WriteShiftFunc;
|
||||
read_shift:ReadShiftFunc;
|
||||
chk:CheckFieldFunc;
|
||||
};
|
||||
interface CFBlobBuffer extends Buffer {
|
||||
l:number;
|
||||
slice:(start:number, end:?number)=>Buffer;
|
||||
slice:(start?:number, end:?number)=>Buffer;
|
||||
write_shift:WriteShiftFunc;
|
||||
read_shift:ReadShiftFunc;
|
||||
chk:CheckFieldFunc;
|
||||
};
|
||||
interface CFBlobUint8 extends Uint8Array {
|
||||
l:number;
|
||||
slice:(start:number, end:?number)=>Uint8Array;
|
||||
slice:(start?:number, end:?number)=>Uint8Array;
|
||||
write_shift:WriteShiftFunc;
|
||||
read_shift:ReadShiftFunc;
|
||||
chk:CheckFieldFunc;
|
||||
};
|
||||
@ -83,13 +90,16 @@ interface CFBlobber {
|
||||
[n:number]:number;
|
||||
l:number;
|
||||
length:number;
|
||||
slice:(start:number, end:?number)=>RawBytes;
|
||||
slice:(start:?number, end:?number)=>RawBytes;
|
||||
write_shift:WriteShiftFunc;
|
||||
read_shift:ReadShiftFunc;
|
||||
chk:CheckFieldFunc;
|
||||
};
|
||||
|
||||
type CFBlob = CFBlobArray | CFBlobBuffer | CFBlobUint8;
|
||||
|
||||
type CFBWriteOpts = any;
|
||||
|
||||
interface CFBReadOpts {
|
||||
type?:string;
|
||||
};
|
||||
@ -99,14 +109,13 @@ type CFBFileIndex = Array<CFBEntry>;
|
||||
type CFBFindPath = (n:string)=>?CFBEntry;
|
||||
|
||||
type CFBContainer = {
|
||||
raw:{
|
||||
raw?:{
|
||||
header:any;
|
||||
sectors:Array<any>;
|
||||
};
|
||||
FileIndex:CFBFileIndex;
|
||||
FullPathDir:CFBDirectory;
|
||||
FullPathDir:CFBFullPathDir;
|
||||
FullPaths:Array<string>;
|
||||
find:CFBFindPath;
|
||||
}
|
||||
|
||||
type CFBEntry = {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.11.4",
|
||||
"version": "0.11.5",
|
||||
"author": "sheetjs",
|
||||
"description": "Excel (XLSB/XLSX/XLS/XML) ODS and other spreadsheet format (CSV/DIF/DBF/SYLK) parser and writer",
|
||||
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "csv", "dbf", "dif", "sylk", "office", "spreadsheet" ],
|
||||
|
11
shim.js
11
shim.js
@ -330,3 +330,14 @@ if (!Date.prototype.toISOString) {
|
||||
}());
|
||||
}
|
||||
|
||||
// note: MDN shim will not work in IE
|
||||
if(typeof Uint8Array !== 'undefined' && !Uint8Array.prototype.slice) Uint8Array.prototype.slice = function(start, end) {
|
||||
if(start < 0) { start += this.length; if(start < 0) start = 0; }
|
||||
if(start >= this.length) return new Uint8Array(0);
|
||||
if(end == null) end = this.length;
|
||||
if(end < 0) { end += this.length; if(end < 0) end = 0; }
|
||||
if(end > this.length) end = this.length;
|
||||
var out = new Uint8Array(end - start);
|
||||
while(start <= --end) out[end - start] = this[end];
|
||||
return out;
|
||||
};
|
||||
|
457
test.js
457
test.js
@ -1,5 +1,6 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint loopfunc:true, eqnull:true */
|
||||
/*jshint -W069, loopfunc:true, mocha:true */
|
||||
var X;
|
||||
var modp = './';
|
||||
//var modp = 'xlsx';
|
||||
@ -7,7 +8,7 @@ var fs = require('fs'), assert = require('assert');
|
||||
describe('source',function(){it('should load',function(){X=require(modp);});});
|
||||
var DIF_XL = true;
|
||||
|
||||
var browser = false;
|
||||
var browser = typeof document !== 'undefined';
|
||||
|
||||
var opts = {cellNF: true};
|
||||
var TYPE = browser ? "binary" : "buffer";
|
||||
@ -36,15 +37,48 @@ function fixjson(x) { return x.replace(/[\r\n]+$/,""); }
|
||||
|
||||
var dir = "./test_files/";
|
||||
|
||||
var dirwp = dir + "artifacts/wps/", dirqp = dir + "artifacts/quattro/";
|
||||
var paths = {
|
||||
afxls: dir + 'AutoFilter.xls',
|
||||
afxml: dir + 'AutoFilter.xml',
|
||||
afods: dir + 'AutoFilter.ods',
|
||||
aadbf: dirwp + 'write.dbf',
|
||||
aadif: dirwp + 'write.dif',
|
||||
aaxls: dirwp + 'write.xls',
|
||||
aaxlsx: dirwp + 'write.xlsx',
|
||||
aaxml: dirwp + 'write.xml',
|
||||
|
||||
abcsv: dirqp + 'write_.csv',
|
||||
abdif: dirqp + 'write_.dif',
|
||||
abslk: dirqp + 'write_.slk',
|
||||
abx57: dirqp + 'write_57.xls',
|
||||
abwb2: dirqp + 'write_6.wb2',
|
||||
abwb2b: dirqp + 'write_6b.wb2',
|
||||
abwb3: dirqp + 'write_8.wb3',
|
||||
abqpw: dirqp + 'write_9.qpw',
|
||||
abx97: dirqp + 'write_97.xls',
|
||||
abwks: dirqp + 'write_L1.wks',
|
||||
abwk1: dirqp + 'write_L2.wk1',
|
||||
abwk3: dirqp + 'write_L3.wk3',
|
||||
abwk4: dirqp + 'write_L45.wk4',
|
||||
ab123: dirqp + 'write_L9.123',
|
||||
ab124: dirqp + 'write_L97.123',
|
||||
abwke2: dirqp + 'write_Led.wke',
|
||||
abwq1: dirqp + 'write_qpdos.wq1',
|
||||
abwb1: dirqp + 'write_qpw.wb1',
|
||||
|
||||
afxls: dir + 'AutoFilter.xls',
|
||||
afxml: dir + 'AutoFilter.xml',
|
||||
afods: dir + 'AutoFilter.ods',
|
||||
afxlsx: dir + 'AutoFilter.xlsx',
|
||||
afxlsb: dir + 'AutoFilter.xlsb',
|
||||
|
||||
cpxls: dir + 'custom_properties.xls',
|
||||
cpxml: dir + 'custom_properties.xls.xml',
|
||||
asxls: dir + 'author_snowman.xls',
|
||||
asxls5: dir + 'author_snowman.xls5',
|
||||
asxml: dir + 'author_snowman.xml',
|
||||
asods: dir + 'author_snowman.ods',
|
||||
asxlsx: dir + 'author_snowman.xlsx',
|
||||
asxlsb: dir + 'author_snowman.xlsb',
|
||||
|
||||
cpxls: dir + 'custom_properties.xls',
|
||||
cpxml: dir + 'custom_properties.xls.xml',
|
||||
cpxlsx: dir + 'custom_properties.xlsx',
|
||||
cpxlsb: dir + 'custom_properties.xlsb',
|
||||
|
||||
@ -226,19 +260,19 @@ function parsetest(x, wb, full, ext) {
|
||||
if(fs.existsSync(dir + '2011/' + x + '.xml'))
|
||||
describe(x + ext + '.xml from 2011', function() {
|
||||
it('should parse', function() {
|
||||
var wb = X.readFile(dir + '2011/' + x + '.xml', opts);
|
||||
/*var wb = */X.readFile(dir + '2011/' + x + '.xml', opts);
|
||||
});
|
||||
});
|
||||
if(fs.existsSync(dir + '2013/' + x + '.xlsb'))
|
||||
describe(x + ext + '.xlsb from 2013', function() {
|
||||
it('should parse', function() {
|
||||
var wb = X.readFile(dir + '2013/' + x + '.xlsb', opts);
|
||||
/*var wb = */X.readFile(dir + '2013/' + x + '.xlsb', opts);
|
||||
});
|
||||
});
|
||||
if(fs.existsSync(dir + x + '.xml' + ext))
|
||||
describe(x + '.xml', function() {
|
||||
it('should parse', function() {
|
||||
var wb = X.readFile(dir + x + '.xml', opts);
|
||||
/*var wb = */X.readFile(dir + x + '.xml', opts);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -553,121 +587,94 @@ describe('parse options', function() {
|
||||
});
|
||||
|
||||
describe('input formats', function() {
|
||||
var _paths = [
|
||||
"cstods", "cstxls", "cstxlsb", "cstxlsb", "cstxml", "aadbf", "aadif",
|
||||
"aaxls", "aaxml", "aaxlsx", "ab123", "ab124", "abcsv", "abdif", "abqpw",
|
||||
"abslk", "abwb1", "abwb2", "abwb3", "abwk1", "abwk3", "abwk4", "abwks",
|
||||
"abwq1", "abx57", "abx97", "abwke2", "abwb2b"
|
||||
].map(function(x) { return paths[x]; });
|
||||
it('should read binary strings', function() {
|
||||
X.read(fs.readFileSync(paths.cstxlsx, 'binary'), {type: 'binary'});
|
||||
X.read(fs.readFileSync(paths.cstxlsb, 'binary'), {type: 'binary'});
|
||||
X.read(fs.readFileSync(paths.cstxls, 'binary'), {type: 'binary'});
|
||||
X.read(fs.readFileSync(paths.cstxml, 'binary'), {type: 'binary'});
|
||||
X.read(fs.readFileSync(paths.cstods, 'binary'), {type: 'binary'});
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, 'binary'), {type: 'binary'});
|
||||
});
|
||||
});
|
||||
it('should read base64 strings', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls, 'base64'), {type: 'base64'});
|
||||
X.read(fs.readFileSync(paths.cstxml, 'base64'), {type: 'base64'});
|
||||
X.read(fs.readFileSync(paths.cstods, 'base64'), {type: 'base64'});
|
||||
X.read(fs.readFileSync(paths.cstxlsx, 'base64'), {type: 'base64'});
|
||||
X.read(fs.readFileSync(paths.cstxlsb, 'base64'), {type: 'base64'});
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, 'base64'), {type: 'base64'});
|
||||
});
|
||||
});
|
||||
var k = browser ? 'array' : 'buffer';
|
||||
(typeof Uint8Array !== 'undefined' ? it : it.skip)('should read ' + k + 's', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls, browser ? 'buffer' : null), {type: k});
|
||||
X.read(fs.readFileSync(paths.cstxml, browser ? 'buffer' : null), {type: k});
|
||||
X.read(fs.readFileSync(paths.cstods, browser ? 'buffer' : null), {type: k});
|
||||
X.read(fs.readFileSync(paths.cstxlsx, browser ? 'buffer' : null), {type: k});
|
||||
X.read(fs.readFileSync(paths.cstxlsb, browser ? 'buffer' : null), {type: k});
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, browser ? 'buffer' : null), {type: k});
|
||||
});
|
||||
});
|
||||
(typeof Uint8Array !== 'undefined' ? it : it.skip)('should read array', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
X.read(fs.readFileSync(paths.cstxml, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
X.read(fs.readFileSync(paths.cstxlsx, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
X.read(fs.readFileSync(paths.cstxlsb, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
X.read(fs.readFileSync(paths.cstods, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
});
|
||||
});
|
||||
it('should throw if format is unknown', function() {
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstxls), {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstxml), {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstods), {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstxlsx), {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstxlsb), {type: 'dafuq'}); });
|
||||
_paths.forEach(function(pth) {
|
||||
assert.throws(function() { X.read(fs.readFileSync(pth), {type: 'dafuq'}); });
|
||||
});
|
||||
});
|
||||
|
||||
if(browser) it('should default to base64 type', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls, 'base64'));
|
||||
X.read(fs.readFileSync(paths.cstxml, 'base64'));
|
||||
X.read(fs.readFileSync(paths.cstods, 'base64'));
|
||||
X.read(fs.readFileSync(paths.cstxlsx, 'base64'));
|
||||
X.read(fs.readFileSync(paths.cstxlsb, 'base64'));
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, 'base64'));
|
||||
});
|
||||
});
|
||||
else {
|
||||
it('should infer buffer type', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls));
|
||||
X.read(fs.readFileSync(paths.cstxml));
|
||||
X.read(fs.readFileSync(paths.cstods));
|
||||
X.read(fs.readFileSync(paths.cstxlsx));
|
||||
X.read(fs.readFileSync(paths.cstxlsb));
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth));
|
||||
});
|
||||
});
|
||||
it('should read files', function() {
|
||||
X.readFile(paths.cstxls);
|
||||
X.readFile(paths.cstxml);
|
||||
X.readFile(paths.cstods);
|
||||
X.readFile(paths.cstxlsx);
|
||||
X.readFile(paths.cstxlsb);
|
||||
_paths.forEach(function(pth) {
|
||||
X.readFile(pth);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('output formats', function() {
|
||||
var wb1, wb2, wb3, wb4;
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.read(fs.readFileSync(paths.cpxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.cpxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.cpxls), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.cpxml), {type:TYPE});
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
it('should write binary strings', function() {
|
||||
if(!wb1) {
|
||||
wb1 = X.read(fs.readFileSync(paths.cpxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.cpxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.cpxls), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.cpxml), {type:TYPE});
|
||||
}
|
||||
X.write(wb1, {type: 'binary'});
|
||||
X.write(wb2, {type: 'binary'});
|
||||
X.write(wb3, {type: 'binary'});
|
||||
X.write(wb4, {type: 'binary'});
|
||||
X.read(X.write(wb1, {type: 'binary'}), {type: 'binary'});
|
||||
X.read(X.write(wb2, {type: 'binary'}), {type: 'binary'});
|
||||
X.read(X.write(wb3, {type: 'binary'}), {type: 'binary'});
|
||||
X.read(X.write(wb4, {type: 'binary'}), {type: 'binary'});
|
||||
});
|
||||
it('should write base64 strings', function() {
|
||||
X.write(wb1, {type: 'base64'});
|
||||
X.write(wb2, {type: 'base64'});
|
||||
X.write(wb3, {type: 'base64'});
|
||||
X.write(wb4, {type: 'base64'});
|
||||
X.read(X.write(wb1, {type: 'base64'}), {type: 'base64'});
|
||||
X.read(X.write(wb2, {type: 'base64'}), {type: 'base64'});
|
||||
X.read(X.write(wb3, {type: 'base64'}), {type: 'base64'});
|
||||
X.read(X.write(wb4, {type: 'base64'}), {type: 'base64'});
|
||||
});
|
||||
if(!browser) it('should write buffers', function() {
|
||||
X.write(wb1, {type: 'buffer'});
|
||||
X.write(wb2, {type: 'buffer'});
|
||||
X.write(wb3, {type: 'buffer'});
|
||||
X.write(wb4, {type: 'buffer'});
|
||||
X.read(X.write(wb1, {type: 'buffer'}), {type: 'buffer'});
|
||||
X.read(X.write(wb2, {type: 'buffer'}), {type: 'buffer'});
|
||||
X.read(X.write(wb3, {type: 'buffer'}), {type: 'buffer'});
|
||||
X.read(X.write(wb4, {type: 'buffer'}), {type: 'buffer'});
|
||||
});
|
||||
it('should throw if format is unknown', function() {
|
||||
assert.throws(function() { X.write(wb1, {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.write(wb2, {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.write(wb3, {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.write(wb4, {type: 'dafuq'}); });
|
||||
});
|
||||
var fmts = [
|
||||
/* fmt unicode str */
|
||||
["xlsx", true, false],
|
||||
["xlsb", true, false],
|
||||
["xls", true, false],
|
||||
["xlml", true, true],
|
||||
["ods", true, false],
|
||||
["fods", true, true],
|
||||
["csv", true, true],
|
||||
["txt", true, true],
|
||||
["sylk", false, true],
|
||||
["html", true, true],
|
||||
["dif", false, true],
|
||||
["prn", false, true]
|
||||
];
|
||||
function RT(T) {
|
||||
if(!X) X = require(modp);
|
||||
fmts.forEach(function(fmt) {
|
||||
var wb = X.utils.book_new();
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([['R',"\u2603"],["\u0BEE",2]]), "Sheet1");
|
||||
if(T == 'string' && !fmt[2]) return assert.throws(function() {X.write(wb, {type: T, bookType:fmt[0], WTF:1});});
|
||||
var out = X.write(wb, {type: T, bookType:fmt[0], WTF:1});
|
||||
var nwb = X.read(out, {type: T, WTF:1});
|
||||
var nws = nwb.Sheets[nwb.SheetNames[0]];
|
||||
assert.equal(get_cell(nws, "B2").v, 2);
|
||||
assert.equal(get_cell(nws, "A1").v, "R");
|
||||
if(fmt[1]) assert.equal(get_cell(nws, "A2").v, "\u0BEE");
|
||||
if(fmt[1]) assert.equal(get_cell(nws, "B1").v, "\u2603");
|
||||
});
|
||||
}
|
||||
it('should write binary strings', function() { RT('binary'); });
|
||||
it('should write base64 strings', function() { RT('base64'); });
|
||||
it('should write JS strings', function() { RT('string'); });
|
||||
if(!browser) it('should write buffers', function() { RT('buffer'); });
|
||||
it('should throw if format is unknown', function() { assert.throws(function() { RT('dafuq'); }); });
|
||||
});
|
||||
|
||||
function eqarr(a,b) {
|
||||
@ -756,30 +763,32 @@ function check_margin(margins, exp) {
|
||||
|
||||
describe('parse features', function() {
|
||||
describe('sheet visibility', function() {
|
||||
var wb1, wb2, wb3, wb4, wb5;
|
||||
var wbs = [];
|
||||
var bef = (function() {
|
||||
wb1 = X.read(fs.readFileSync(paths.svxls), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.svxls5), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.svxml), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.svxlsx), {type:TYPE});
|
||||
wb5 = X.read(fs.readFileSync(paths.svxlsb), {type:TYPE});
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.svxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.svxls5), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.svxml), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.svxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.svxlsb), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
|
||||
it('should detect visible sheets', function() {
|
||||
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||
wbs.forEach(function(wb) {
|
||||
assert(!wb.Workbook.Sheets[0].Hidden);
|
||||
});
|
||||
});
|
||||
it('should detect all hidden sheets', function() {
|
||||
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||
wbs.forEach(function(wb) {
|
||||
assert(wb.Workbook.Sheets[1].Hidden);
|
||||
assert(wb.Workbook.Sheets[2].Hidden);
|
||||
});
|
||||
});
|
||||
it('should distinguish very hidden sheets', function() {
|
||||
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||
wbs.forEach(function(wb) {
|
||||
assert.equal(wb.Workbook.Sheets[1].Hidden,1);
|
||||
assert.equal(wb.Workbook.Sheets[2].Hidden,2);
|
||||
});
|
||||
@ -822,24 +831,44 @@ describe('parse features', function() {
|
||||
});
|
||||
|
||||
describe('should parse core properties and custom properties', function() {
|
||||
var wb1, wb2, wb3, wb4;
|
||||
var wbs=[];
|
||||
var bef = (function() {
|
||||
wb1 = X.read(fs.readFileSync(paths.cpxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.cpxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.cpxls), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.cpxml), {type:TYPE});
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.cpxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.cpxlsb), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.cpxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.cpxml), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
|
||||
it(N1 + ' should parse core properties', function() { coreprop(wb1); });
|
||||
it(N2 + ' should parse core properties', function() { coreprop(wb2); });
|
||||
it(N3 + ' should parse core properties', function() { coreprop(wb3); });
|
||||
it(N4 + ' should parse core properties', function() { coreprop(wb4); });
|
||||
it(N1 + ' should parse custom properties', function() { custprop(wb1); });
|
||||
it(N2 + ' should parse custom properties', function() { custprop(wb2); });
|
||||
it(N3 + ' should parse custom properties', function() { custprop(wb3); });
|
||||
it(N4 + ' should parse custom properties', function() { custprop(wb4); });
|
||||
[N1, N2, N3, N4].forEach(function(x, i) {
|
||||
it(x + ' should parse core properties', function() { coreprop(wbs[i]); });
|
||||
it(x + ' should parse custom properties', function() { custprop(wbs[i]); });
|
||||
});
|
||||
[
|
||||
["asxls", "BIFF8", "\u2603"],
|
||||
["asxls5", "BIFF5", "_"],
|
||||
["asxml", "XLML", "\u2603"],
|
||||
["asods", "ODS", "God"],
|
||||
["asxlsx", "XLSX", "\u2603"],
|
||||
["asxlsb", "XLSB", "\u2603"]
|
||||
].forEach(function(x) {
|
||||
(fs.existsSync(paths[x[0]]) ? it : it.skip)(x[1] + ' should read unicode author', function() {
|
||||
var wb = X.read(fs.readFileSync(paths[x[0]]), {type:TYPE});
|
||||
assert.equal(wb.Props.Author, x[2]);
|
||||
}); });
|
||||
var BASE = "இராமா";
|
||||
[ "xlsx", "xlsb", "xlml"/*, "ods", "xls" */].forEach(function(n) {
|
||||
it(n + ' should round-trip unicode category', function() {
|
||||
var wb = X.utils.book_new();
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([["a"]]), "Sheet1");
|
||||
if(!wb.Props) wb.Props = {};
|
||||
wb.Props.Category = BASE;
|
||||
var wb2 = X.read(X.write(wb, {bookType:n, type:TYPE}), {type:TYPE});
|
||||
assert.equal(wb2.Props.Category,BASE);
|
||||
}); });
|
||||
});
|
||||
|
||||
describe('sheetRows', function() {
|
||||
@ -930,6 +959,7 @@ describe('parse features', function() {
|
||||
describe('row properties', function() {
|
||||
var wb1, wb2, wb3, wb4, wb5, wb6;
|
||||
var ol1, ol2, ol3, ol4, ol5;
|
||||
var ol = fs.existsSync(paths.olxls);
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.read(fs.readFileSync(paths.rhxlsx), {type:TYPE, cellStyles:true});
|
||||
@ -938,6 +968,8 @@ describe('parse features', function() {
|
||||
wb4 = X.read(fs.readFileSync(paths.rhxls5), {type:TYPE, cellStyles:true});
|
||||
wb5 = X.read(fs.readFileSync(paths.rhxml), {type:TYPE, cellStyles:true});
|
||||
wb6 = X.read(fs.readFileSync(paths.rhslk), {type:TYPE, cellStyles:true});
|
||||
/* */
|
||||
if(!ol) return;
|
||||
ol1 = X.read(fs.readFileSync(paths.olxlsx), {type:TYPE, cellStyles:true});
|
||||
ol2 = X.read(fs.readFileSync(paths.olxlsb), {type:TYPE, cellStyles:true});
|
||||
ol3 = X.read(fs.readFileSync(paths.olxls), {type:TYPE, cellStyles:true});
|
||||
@ -964,7 +996,7 @@ describe('parse features', function() {
|
||||
assert.equal(x[3].hpx, 100);
|
||||
});
|
||||
});
|
||||
it('should have correct outline levels', function() {
|
||||
(ol ? it : it.skip)('should have correct outline levels', function() {
|
||||
/* TODO: ODS */
|
||||
[ol1, ol2, ol3, ol4/*, ol5*/].map(function(x) { return x.Sheets.Sheet1; }).forEach(function(ws) {
|
||||
var rows = ws['!rows'];
|
||||
@ -973,7 +1005,7 @@ describe('parse features', function() {
|
||||
var lvl = (rows[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);
|
||||
if(cell.v === 0) assert.equal(lvl, 0);
|
||||
else assert.equal(lvl, cell.v);
|
||||
}
|
||||
}
|
||||
@ -983,47 +1015,47 @@ describe('parse features', function() {
|
||||
});
|
||||
|
||||
describe('merge cells',function() {
|
||||
var wb1, wb2, wb3, wb4, wb5;
|
||||
var wbs=[];
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.read(fs.readFileSync(paths.mcxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.mcxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.mcods), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.mcxls), {type:TYPE});
|
||||
wb5 = X.read(fs.readFileSync(paths.mcxml), {type:TYPE});
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.mcxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.mcxlsb), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.mcods), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.mcxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.mcxml), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
it('should have !merges', function() {
|
||||
assert(wb1.Sheets.Merge['!merges']);
|
||||
assert(wb2.Sheets.Merge['!merges']);
|
||||
assert(wb3.Sheets.Merge['!merges']);
|
||||
assert(wb4.Sheets.Merge['!merges']);
|
||||
assert(wb5.Sheets.Merge['!merges']);
|
||||
var m = [wb1, wb2, wb3, wb4, wb5].map(function(x) { return x.Sheets.Merge['!merges'].map(function(y) { return X.utils.encode_range(y); });});
|
||||
assert.deepEqual(m[0].sort(),m[1].sort());
|
||||
assert.deepEqual(m[0].sort(),m[2].sort());
|
||||
assert.deepEqual(m[0].sort(),m[3].sort());
|
||||
assert.deepEqual(m[0].sort(),m[4].sort());
|
||||
wbs.forEach(function(wb) {
|
||||
assert(wb.Sheets.Merge['!merges']);
|
||||
});
|
||||
var m = wbs.map(function(x) { return x.Sheets.Merge['!merges'].map(function(y) { return X.utils.encode_range(y); });});
|
||||
m.slice(1).forEach(function(x) {
|
||||
assert.deepEqual(m[0].sort(),x.sort());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('should find hyperlinks', function() {
|
||||
var wb1, wb2, wb3, wb4;
|
||||
var wbs;
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.read(fs.readFileSync(paths.hlxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.hlxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.hlxls), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.hlxml), {type:TYPE});
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.hlxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.hlxlsb), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.hlxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.hlxml), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
|
||||
it(N1, function() { hlink(wb1); });
|
||||
it(N2, function() { hlink(wb2); });
|
||||
it(N3, function() { hlink(wb3); });
|
||||
it(N4, function() { hlink(wb4); });
|
||||
[N1, N2, N3, N4].forEach(function(x, i) {
|
||||
it(x, function() { hlink(wbs[i]); });
|
||||
});
|
||||
});
|
||||
|
||||
describe('should parse cells with date type (XLSX/XLSM)', function() {
|
||||
@ -1077,7 +1109,7 @@ describe('parse features', function() {
|
||||
['xlsx', paths.dnsxlsx, true],
|
||||
['xlsb', paths.dnsxlsb, true],
|
||||
['xls', paths.dnsxls, true],
|
||||
['xlml', paths.dnsxml, false],
|
||||
['xlml', paths.dnsxml, false]
|
||||
].forEach(function(m) { it(m[0], function() {
|
||||
var wb = X.read(fs.readFileSync(m[1]), {type:TYPE});
|
||||
var names = wb.Workbook.Names;
|
||||
@ -1103,9 +1135,9 @@ describe('parse features', function() {
|
||||
['ods', paths.afods]
|
||||
].forEach(function(m) { it(m[0], function() {
|
||||
var wb = X.read(fs.readFileSync(m[1]), {type:TYPE});
|
||||
assert(wb.Sheets[wb.SheetNames[0]]['!autofilter'] == null);
|
||||
assert(!wb.Sheets[wb.SheetNames[0]]['!autofilter']);
|
||||
for(var i = 1; i < wb.SheetNames.length; ++i) {
|
||||
assert(wb.Sheets[wb.SheetNames[i]]['!autofilter'] != null);
|
||||
assert(wb.Sheets[wb.SheetNames[i]]['!autofilter']);
|
||||
assert.equal(wb.Sheets[wb.SheetNames[i]]['!autofilter'].ref,"A1:E22");
|
||||
}
|
||||
}); });
|
||||
@ -1132,15 +1164,16 @@ describe('parse features', function() {
|
||||
});
|
||||
|
||||
describe('page margins', function() {
|
||||
var wb1, wb2, wb3, wb4, wb5, wbs;
|
||||
var wbs=[];
|
||||
var bef = (function() {
|
||||
if(!fs.existsSync(paths.pmxls)) return wbs=[];
|
||||
wb1 = X.read(fs.readFileSync(paths.pmxls), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.pmxls5), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.pmxml), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.pmxlsx), {type:TYPE});
|
||||
wb5 = X.read(fs.readFileSync(paths.pmxlsb), {type:TYPE});
|
||||
wbs = [wb1, wb2, wb3, wb4, wb5];
|
||||
if(!fs.existsSync(paths.pmxls)) return;
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.pmxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.pmxls5), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.pmxml), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.pmxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.pmxlsb), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
@ -1149,17 +1182,17 @@ describe('parse features', function() {
|
||||
check_margin(wb.Sheets["Normal"]["!margins"], [0.7, 0.7, 0.75, 0.75, 0.3, 0.3]);
|
||||
});
|
||||
});
|
||||
it('should parse wide margins ', function() {
|
||||
it('should parse wide margins', function() {
|
||||
wbs.forEach(function(wb) {
|
||||
check_margin(wb.Sheets["Wide"]["!margins"], [1, 1, 1, 1, 0.5, 0.5]);
|
||||
});
|
||||
});
|
||||
it('should parse narrow margins ', function() {
|
||||
it('should parse narrow margins', function() {
|
||||
wbs.forEach(function(wb) {
|
||||
check_margin(wb.Sheets["Narrow"]["!margins"], [0.25, 0.25, 0.75, 0.75, 0.3, 0.3]);
|
||||
});
|
||||
});
|
||||
it('should parse custom margins ', function() {
|
||||
it('should parse custom margins', function() {
|
||||
wbs.forEach(function(wb) {
|
||||
check_margin(wb.Sheets["Custom 1 Inch Centered"]["!margins"], [1, 1, 1, 1, 0.3, 0.3]);
|
||||
check_margin(wb.Sheets["1 Inch HF"]["!margins"], [0.7, 0.7, 0.75, 0.75, 1, 1]);
|
||||
@ -1255,7 +1288,7 @@ describe('write features', function() {
|
||||
baseprops = {
|
||||
Category: "Newspaper",
|
||||
ContentStatus: "Published",
|
||||
Keywords: "print",
|
||||
Keywords: "☃",
|
||||
LastAuthor: "Perry White",
|
||||
LastPrinted: "1978-12-15",
|
||||
RevNumber: 6969,
|
||||
@ -1271,7 +1304,7 @@ describe('write features', function() {
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
['xlml', 'xlsx', 'xlsb'].forEach(function(w) { it(w, function() {
|
||||
wb = {
|
||||
var wb = {
|
||||
Props: {},
|
||||
SheetNames: ["Sheet1"],
|
||||
Sheets: {Sheet1: ws}
|
||||
@ -1389,7 +1422,7 @@ describe('roundtrip features', function() {
|
||||
|
||||
if(m[0].t === 'n' && m[1].t === 'n') assert.equal(m[0].v, m[1].v);
|
||||
else if(m[0].t === 'd' && m[1].t === 'd') assert.equal(m[0].v.toString(), m[1].v.toString());
|
||||
else if(m[1].t === 'n') assert(Math.abs(datenum(new Date(m[0].v)) - m[1].v) < 0.01);
|
||||
else if(m[1].t === 'n') assert(Math.abs(datenum(browser ? parseDate(m[0].v) : new Date(m[0].v)) - m[1].v) < 0.01);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1543,10 +1576,9 @@ describe('invalid files', function() {
|
||||
});
|
||||
describe('write', function() {
|
||||
it('should pass -> XLSX', function() {
|
||||
X.write(X.read(fs.readFileSync(paths.fstxlsb), {type:TYPE}), {type:TYPE});
|
||||
X.write(X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE}), {type:TYPE});
|
||||
X.write(X.read(fs.readFileSync(paths.fstxls), {type:TYPE}), {type:TYPE});
|
||||
X.write(X.read(fs.readFileSync(paths.fstxml), {type:TYPE}), {type:TYPE});
|
||||
["fstxlsb", "fstxlsx", "fstxls", "fstxml"].forEach(function(n) {
|
||||
X.write(X.read(fs.readFileSync(paths[n]), {type:TYPE}), {type:TYPE});
|
||||
});
|
||||
});
|
||||
it('should pass if a sheet is missing', function() {
|
||||
var wb = X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE}); delete wb.Sheets[wb.SheetNames[0]];
|
||||
@ -1700,16 +1732,16 @@ describe('json output', function() {
|
||||
var _data = [["S","h","e","e","t","J","S"],[1,2,3,4,5,6,7],[],[2,3,4,5,6,7,8]];
|
||||
var _ws = X.utils.aoa_to_sheet(_data);
|
||||
var json1 = X.utils.sheet_to_json(_ws);
|
||||
var json2 = X.utils.sheet_to_json(_ws, {header:1});
|
||||
var json3 = X.utils.sheet_to_json(_ws, {blankrows:true});
|
||||
var json4 = X.utils.sheet_to_json(_ws, {blankrows:true, header:1});
|
||||
var json5 = X.utils.sheet_to_json(_ws, {blankrows:false});
|
||||
var json6 = X.utils.sheet_to_json(_ws, {blankrows:false, header:1});
|
||||
assert.equal(json1.length, 2); // = 2 non-empty records
|
||||
var json2 = X.utils.sheet_to_json(_ws, {header:1});
|
||||
assert.equal(json2.length, 4); // = 4 sheet rows
|
||||
var json3 = X.utils.sheet_to_json(_ws, {blankrows:true});
|
||||
assert.equal(json3.length, 3); // = 2 records + 1 blank row
|
||||
var json4 = X.utils.sheet_to_json(_ws, {blankrows:true, header:1});
|
||||
assert.equal(json4.length, 4); // = 4 sheet rows
|
||||
var json5 = X.utils.sheet_to_json(_ws, {blankrows:false});
|
||||
assert.equal(json5.length, 2); // = 2 records
|
||||
var json6 = X.utils.sheet_to_json(_ws, {blankrows:false, header:1});
|
||||
assert.equal(json6.length, 3); // = 4 sheet rows - 1 blank row
|
||||
});
|
||||
it('should have an index that starts with zero when selecting range', function() {
|
||||
@ -1724,36 +1756,40 @@ describe('json output', function() {
|
||||
});
|
||||
|
||||
|
||||
var codes = [["あ 1", "\u00E3\u0081\u0082 1"]]
|
||||
var codes = [["あ 1", "\u00E3\u0081\u0082 1"]];
|
||||
var plaintext_val = [
|
||||
["A1", 'n', -0.08, "-0.08"],
|
||||
["B1", 'n', 4001, "4,001"],
|
||||
["C1", 's', "あ 1", "あ 1"],
|
||||
["A2", 'n', 41.08, "$41.08"],
|
||||
["B2", 'n', 0.11, "11%"],
|
||||
["B3", 'b', true, "TRUE"],
|
||||
["C3", 'b', false, "FALSE"],
|
||||
["A3"]];
|
||||
function plaintext_test(wb, raw, sn) {
|
||||
var sheet = wb.Sheets[sn || wb.SheetNames[0]];
|
||||
["C3", 'b', true, "TRUE"],
|
||||
["D3", 'b', false, "FALSE"],
|
||||
["B3", 's', " ", " "],
|
||||
["A3"]
|
||||
];
|
||||
function plaintext_test(wb, raw, t) {
|
||||
var sheet = wb.Sheets[wb.SheetNames[0]];
|
||||
plaintext_val.forEach(function(x) {
|
||||
var cell = get_cell(sheet, x[0]);
|
||||
var tcval = x[2+!!raw];
|
||||
var type = raw ? 's' : x[1]; // != 's' ? x[1] : tcval.length === 0 ? 'z' : 's';
|
||||
if(x.length == 1) { if(cell) { assert.equal(cell.t, 'z'); assert(!cell.v); } return; }
|
||||
assert.equal(cell.v, x[2+!!raw]); assert.equal(cell.t, raw ? 's' : x[1]);
|
||||
assert.equal(cell.v, tcval); assert.equal(cell.t, type);
|
||||
});
|
||||
}
|
||||
function make_html_str(idx) { return ["<table>",
|
||||
"<tr><td>-0.08</td><td>4,001</td><td>", codes[0][idx], "</td></tr>",
|
||||
"<tr><td>$41.08</td><td>11%</td></tr>",
|
||||
"<tr><td></td><td>TRUE</td><td>FALSE</td></tr>",
|
||||
"<tr><td></td><td> \n </td><td>TRUE</td><td>FALSE</td></tr>",
|
||||
"</table>" ].join(""); }
|
||||
function make_csv_str(idx) { return [ '\u00EF\u00BB\u00BF' +
|
||||
function make_csv_str(idx) { return [ (idx == 1 ? '\u00EF\u00BB\u00BF' : "") +
|
||||
'-0.08,"4,001",' + codes[0][idx] + '',
|
||||
'$41.08,11%',
|
||||
',TRUE,FALSE'
|
||||
', ,TRUE,FALSE'
|
||||
].join("\n"); }
|
||||
var html_bstr = make_html_str(1), html_str = make_html_str(0);
|
||||
var csv_bstr = make_csv_str(1);
|
||||
var csv_bstr = make_csv_str(1), csv_str = make_csv_str(0);
|
||||
|
||||
|
||||
describe('csv', function() {
|
||||
@ -1779,7 +1815,7 @@ describe('csv', function() {
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '2/19/14');
|
||||
opts.cellDates = true;
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '2/19/14');
|
||||
});
|
||||
it('should honor dateNF override', function() {
|
||||
@ -1788,7 +1824,7 @@ describe('csv', function() {
|
||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||
assert(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '14-02-19');
|
||||
});
|
||||
it('should interpret dateNF', function() {
|
||||
@ -1802,8 +1838,8 @@ describe('csv', function() {
|
||||
assert.equal(cell.v.getMonth(), 2);
|
||||
assert.equal(cell.w, "2/3/14");
|
||||
});
|
||||
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_bstr, {type:"binary", raw:true}), true); });
|
||||
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false, false); });
|
||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_bstr, {type:"binary", raw:true}), true, false); });
|
||||
it('should handle formulae', function() {
|
||||
var bb = '=,=1+1,="100"';
|
||||
var sheet = X.read(bb, {type:"binary"}).Sheets.Sheet1;
|
||||
@ -1903,12 +1939,13 @@ function get_dom_element(html) {
|
||||
|
||||
describe('HTML', function() {
|
||||
describe('input string', function(){
|
||||
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 interpret values by default', function() { plaintext_test(X.read(html_bstr, {type:"binary"}), false, false); });
|
||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(html_bstr, {type:"binary", raw:true}), true, false); });
|
||||
it('should handle "string" type', function() { plaintext_test(X.read(html_str, {type:"string"}), false, false); });
|
||||
});
|
||||
(domtest ? describe : describe.skip)('input DOM', function() {
|
||||
it('should interpret values by default', function() { plaintext_test(X.utils.table_to_book(get_dom_element(html_str)), false); });
|
||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.utils.table_to_book(get_dom_element(html_str), {raw:true}), true); });
|
||||
it('should interpret values by default', function() { plaintext_test(X.utils.table_to_book(get_dom_element(html_str)), false, true); });
|
||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.utils.table_to_book(get_dom_element(html_str), {raw:true}), true, true); });
|
||||
});
|
||||
});
|
||||
|
||||
@ -1933,25 +1970,14 @@ describe('js -> file -> js', function() {
|
||||
ofmt.forEach(function(f) {
|
||||
it(f, function() {
|
||||
var newwb = X.read(X.write(wb, {type:BIN, bookType: f}), {type:BIN});
|
||||
/* int */
|
||||
eqcell(wb, newwb, 'Sheet1', 'A1');
|
||||
eqcell(wb, newwb, 'Sheet1', 'B1');
|
||||
eqcell(wb, newwb, 'Sheet1', 'C1');
|
||||
/* double */
|
||||
eqcell(wb, newwb, 'Sheet1', 'B4');
|
||||
/* bool */
|
||||
eqcell(wb, newwb, 'Sheet1', 'A2');
|
||||
eqcell(wb, newwb, 'Sheet1', 'B2');
|
||||
/* string */
|
||||
eqcell(wb, newwb, 'Sheet1', 'D2');
|
||||
eqcell(wb, newwb, 'Sheet1', 'A3');
|
||||
eqcell(wb, newwb, 'Sheet1', 'B3');
|
||||
eqcell(wb, newwb, 'Sheet1', 'A4');
|
||||
eqcell(wb, newwb, 'Sheet1', 'C4');
|
||||
var cb = function(cell) { eqcell(wb, newwb, 'Sheet1', cell); };
|
||||
['A1', 'B1', 'C1'].forEach(cb); /* int */
|
||||
['B4'].forEach(cb); /* double */
|
||||
['A2', 'B2'].forEach(cb); /* bool */
|
||||
['D2', 'A3', 'B3', 'A4', 'C4'].forEach(cb); /* string */
|
||||
if(!DIF_XL) cb('C3'); /* date */
|
||||
if(DIF_XL && f == "dif") assert.equal(get_cell(newwb.Sheets["Sheet1"], 'D3').v, '=""0.3""');// dif forces string formula
|
||||
else eqcell(wb, newwb, 'Sheet1', 'D3');
|
||||
/* date */
|
||||
if(!DIF_XL) eqcell(wb, newwb, 'Sheet1', 'C3');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1997,12 +2023,13 @@ describe('corner cases', function() {
|
||||
});
|
||||
it('SSF oddities', function() {
|
||||
var ssfdata = require('./misc/ssf.json');
|
||||
var cb = function(d, j) { return function() { return X.SSF.format(d[0], d[j][0]); }; };
|
||||
ssfdata.forEach(function(d) {
|
||||
for(var j=1;j<d.length;++j) {
|
||||
if(d[j].length == 2) {
|
||||
var expected = d[j][1], actual = X.SSF.format(d[0], d[j][0], {});
|
||||
assert.equal(actual, expected);
|
||||
} else if(d[j][2] !== "#") assert.throws(function() { SSF.format(d[0], d[j][0]); });
|
||||
} else if(d[j][2] !== "#") assert.throws(cb(d, j));
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -2031,7 +2058,7 @@ describe('encryption', function() {
|
||||
}
|
||||
});
|
||||
it.skip('should decrypt file', function() {
|
||||
var wb = X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
|
||||
/*var wb = */X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit a9c6bbb161ca45a077779ecbe434d8c5d614ee37
|
||||
Subproject commit 936478fc713e5ee59c35a49bce4f61ea397284e5
|
457
tests/core.js
457
tests/core.js
@ -1,5 +1,6 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint loopfunc:true, eqnull:true */
|
||||
/*jshint -W069, loopfunc:true, mocha:true */
|
||||
var X;
|
||||
var modp = './';
|
||||
//var modp = 'xlsx';
|
||||
@ -7,7 +8,7 @@ var fs = require('fs'), assert = require('assert');
|
||||
describe('source',function(){it('should load',function(){X=require(modp);});});
|
||||
var DIF_XL = true;
|
||||
|
||||
var browser = true;
|
||||
var browser = typeof document !== 'undefined';
|
||||
|
||||
var opts = {cellNF: true};
|
||||
var TYPE = browser ? "binary" : "buffer";
|
||||
@ -36,15 +37,48 @@ function fixjson(x) { return x.replace(/[\r\n]+$/,""); }
|
||||
|
||||
var dir = "./test_files/";
|
||||
|
||||
var dirwp = dir + "artifacts/wps/", dirqp = dir + "artifacts/quattro/";
|
||||
var paths = {
|
||||
afxls: dir + 'AutoFilter.xls',
|
||||
afxml: dir + 'AutoFilter.xml',
|
||||
afods: dir + 'AutoFilter.ods',
|
||||
aadbf: dirwp + 'write.dbf',
|
||||
aadif: dirwp + 'write.dif',
|
||||
aaxls: dirwp + 'write.xls',
|
||||
aaxlsx: dirwp + 'write.xlsx',
|
||||
aaxml: dirwp + 'write.xml',
|
||||
|
||||
abcsv: dirqp + 'write_.csv',
|
||||
abdif: dirqp + 'write_.dif',
|
||||
abslk: dirqp + 'write_.slk',
|
||||
abx57: dirqp + 'write_57.xls',
|
||||
abwb2: dirqp + 'write_6.wb2',
|
||||
abwb2b: dirqp + 'write_6b.wb2',
|
||||
abwb3: dirqp + 'write_8.wb3',
|
||||
abqpw: dirqp + 'write_9.qpw',
|
||||
abx97: dirqp + 'write_97.xls',
|
||||
abwks: dirqp + 'write_L1.wks',
|
||||
abwk1: dirqp + 'write_L2.wk1',
|
||||
abwk3: dirqp + 'write_L3.wk3',
|
||||
abwk4: dirqp + 'write_L45.wk4',
|
||||
ab123: dirqp + 'write_L9.123',
|
||||
ab124: dirqp + 'write_L97.123',
|
||||
abwke2: dirqp + 'write_Led.wke',
|
||||
abwq1: dirqp + 'write_qpdos.wq1',
|
||||
abwb1: dirqp + 'write_qpw.wb1',
|
||||
|
||||
afxls: dir + 'AutoFilter.xls',
|
||||
afxml: dir + 'AutoFilter.xml',
|
||||
afods: dir + 'AutoFilter.ods',
|
||||
afxlsx: dir + 'AutoFilter.xlsx',
|
||||
afxlsb: dir + 'AutoFilter.xlsb',
|
||||
|
||||
cpxls: dir + 'custom_properties.xls',
|
||||
cpxml: dir + 'custom_properties.xls.xml',
|
||||
asxls: dir + 'author_snowman.xls',
|
||||
asxls5: dir + 'author_snowman.xls5',
|
||||
asxml: dir + 'author_snowman.xml',
|
||||
asods: dir + 'author_snowman.ods',
|
||||
asxlsx: dir + 'author_snowman.xlsx',
|
||||
asxlsb: dir + 'author_snowman.xlsb',
|
||||
|
||||
cpxls: dir + 'custom_properties.xls',
|
||||
cpxml: dir + 'custom_properties.xls.xml',
|
||||
cpxlsx: dir + 'custom_properties.xlsx',
|
||||
cpxlsb: dir + 'custom_properties.xlsb',
|
||||
|
||||
@ -226,19 +260,19 @@ function parsetest(x, wb, full, ext) {
|
||||
if(fs.existsSync(dir + '2011/' + x + '.xml'))
|
||||
describe(x + ext + '.xml from 2011', function() {
|
||||
it('should parse', function() {
|
||||
var wb = X.readFile(dir + '2011/' + x + '.xml', opts);
|
||||
/*var wb = */X.readFile(dir + '2011/' + x + '.xml', opts);
|
||||
});
|
||||
});
|
||||
if(fs.existsSync(dir + '2013/' + x + '.xlsb'))
|
||||
describe(x + ext + '.xlsb from 2013', function() {
|
||||
it('should parse', function() {
|
||||
var wb = X.readFile(dir + '2013/' + x + '.xlsb', opts);
|
||||
/*var wb = */X.readFile(dir + '2013/' + x + '.xlsb', opts);
|
||||
});
|
||||
});
|
||||
if(fs.existsSync(dir + x + '.xml' + ext))
|
||||
describe(x + '.xml', function() {
|
||||
it('should parse', function() {
|
||||
var wb = X.readFile(dir + x + '.xml', opts);
|
||||
/*var wb = */X.readFile(dir + x + '.xml', opts);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -553,121 +587,94 @@ describe('parse options', function() {
|
||||
});
|
||||
|
||||
describe('input formats', function() {
|
||||
var _paths = [
|
||||
"cstods", "cstxls", "cstxlsb", "cstxlsb", "cstxml", "aadbf", "aadif",
|
||||
"aaxls", "aaxml", "aaxlsx", "ab123", "ab124", "abcsv", "abdif", "abqpw",
|
||||
"abslk", "abwb1", "abwb2", "abwb3", "abwk1", "abwk3", "abwk4", "abwks",
|
||||
"abwq1", "abx57", "abx97", "abwke2", "abwb2b"
|
||||
].map(function(x) { return paths[x]; });
|
||||
it('should read binary strings', function() {
|
||||
X.read(fs.readFileSync(paths.cstxlsx, 'binary'), {type: 'binary'});
|
||||
X.read(fs.readFileSync(paths.cstxlsb, 'binary'), {type: 'binary'});
|
||||
X.read(fs.readFileSync(paths.cstxls, 'binary'), {type: 'binary'});
|
||||
X.read(fs.readFileSync(paths.cstxml, 'binary'), {type: 'binary'});
|
||||
X.read(fs.readFileSync(paths.cstods, 'binary'), {type: 'binary'});
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, 'binary'), {type: 'binary'});
|
||||
});
|
||||
});
|
||||
it('should read base64 strings', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls, 'base64'), {type: 'base64'});
|
||||
X.read(fs.readFileSync(paths.cstxml, 'base64'), {type: 'base64'});
|
||||
X.read(fs.readFileSync(paths.cstods, 'base64'), {type: 'base64'});
|
||||
X.read(fs.readFileSync(paths.cstxlsx, 'base64'), {type: 'base64'});
|
||||
X.read(fs.readFileSync(paths.cstxlsb, 'base64'), {type: 'base64'});
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, 'base64'), {type: 'base64'});
|
||||
});
|
||||
});
|
||||
var k = browser ? 'array' : 'buffer';
|
||||
(typeof Uint8Array !== 'undefined' ? it : it.skip)('should read ' + k + 's', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls, browser ? 'buffer' : null), {type: k});
|
||||
X.read(fs.readFileSync(paths.cstxml, browser ? 'buffer' : null), {type: k});
|
||||
X.read(fs.readFileSync(paths.cstods, browser ? 'buffer' : null), {type: k});
|
||||
X.read(fs.readFileSync(paths.cstxlsx, browser ? 'buffer' : null), {type: k});
|
||||
X.read(fs.readFileSync(paths.cstxlsb, browser ? 'buffer' : null), {type: k});
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, browser ? 'buffer' : null), {type: k});
|
||||
});
|
||||
});
|
||||
(typeof Uint8Array !== 'undefined' ? it : it.skip)('should read array', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
X.read(fs.readFileSync(paths.cstxml, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
X.read(fs.readFileSync(paths.cstxlsx, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
X.read(fs.readFileSync(paths.cstxlsb, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
X.read(fs.readFileSync(paths.cstods, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
|
||||
});
|
||||
});
|
||||
it('should throw if format is unknown', function() {
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstxls), {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstxml), {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstods), {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstxlsx), {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.read(fs.readFileSync(paths.cstxlsb), {type: 'dafuq'}); });
|
||||
_paths.forEach(function(pth) {
|
||||
assert.throws(function() { X.read(fs.readFileSync(pth), {type: 'dafuq'}); });
|
||||
});
|
||||
});
|
||||
|
||||
if(browser) it('should default to base64 type', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls, 'base64'));
|
||||
X.read(fs.readFileSync(paths.cstxml, 'base64'));
|
||||
X.read(fs.readFileSync(paths.cstods, 'base64'));
|
||||
X.read(fs.readFileSync(paths.cstxlsx, 'base64'));
|
||||
X.read(fs.readFileSync(paths.cstxlsb, 'base64'));
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth, 'base64'));
|
||||
});
|
||||
});
|
||||
else {
|
||||
it('should infer buffer type', function() {
|
||||
X.read(fs.readFileSync(paths.cstxls));
|
||||
X.read(fs.readFileSync(paths.cstxml));
|
||||
X.read(fs.readFileSync(paths.cstods));
|
||||
X.read(fs.readFileSync(paths.cstxlsx));
|
||||
X.read(fs.readFileSync(paths.cstxlsb));
|
||||
_paths.forEach(function(pth) {
|
||||
X.read(fs.readFileSync(pth));
|
||||
});
|
||||
});
|
||||
it('should read files', function() {
|
||||
X.readFile(paths.cstxls);
|
||||
X.readFile(paths.cstxml);
|
||||
X.readFile(paths.cstods);
|
||||
X.readFile(paths.cstxlsx);
|
||||
X.readFile(paths.cstxlsb);
|
||||
_paths.forEach(function(pth) {
|
||||
X.readFile(pth);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('output formats', function() {
|
||||
var wb1, wb2, wb3, wb4;
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.read(fs.readFileSync(paths.cpxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.cpxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.cpxls), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.cpxml), {type:TYPE});
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
it('should write binary strings', function() {
|
||||
if(!wb1) {
|
||||
wb1 = X.read(fs.readFileSync(paths.cpxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.cpxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.cpxls), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.cpxml), {type:TYPE});
|
||||
}
|
||||
X.write(wb1, {type: 'binary'});
|
||||
X.write(wb2, {type: 'binary'});
|
||||
X.write(wb3, {type: 'binary'});
|
||||
X.write(wb4, {type: 'binary'});
|
||||
X.read(X.write(wb1, {type: 'binary'}), {type: 'binary'});
|
||||
X.read(X.write(wb2, {type: 'binary'}), {type: 'binary'});
|
||||
X.read(X.write(wb3, {type: 'binary'}), {type: 'binary'});
|
||||
X.read(X.write(wb4, {type: 'binary'}), {type: 'binary'});
|
||||
});
|
||||
it('should write base64 strings', function() {
|
||||
X.write(wb1, {type: 'base64'});
|
||||
X.write(wb2, {type: 'base64'});
|
||||
X.write(wb3, {type: 'base64'});
|
||||
X.write(wb4, {type: 'base64'});
|
||||
X.read(X.write(wb1, {type: 'base64'}), {type: 'base64'});
|
||||
X.read(X.write(wb2, {type: 'base64'}), {type: 'base64'});
|
||||
X.read(X.write(wb3, {type: 'base64'}), {type: 'base64'});
|
||||
X.read(X.write(wb4, {type: 'base64'}), {type: 'base64'});
|
||||
});
|
||||
if(!browser) it('should write buffers', function() {
|
||||
X.write(wb1, {type: 'buffer'});
|
||||
X.write(wb2, {type: 'buffer'});
|
||||
X.write(wb3, {type: 'buffer'});
|
||||
X.write(wb4, {type: 'buffer'});
|
||||
X.read(X.write(wb1, {type: 'buffer'}), {type: 'buffer'});
|
||||
X.read(X.write(wb2, {type: 'buffer'}), {type: 'buffer'});
|
||||
X.read(X.write(wb3, {type: 'buffer'}), {type: 'buffer'});
|
||||
X.read(X.write(wb4, {type: 'buffer'}), {type: 'buffer'});
|
||||
});
|
||||
it('should throw if format is unknown', function() {
|
||||
assert.throws(function() { X.write(wb1, {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.write(wb2, {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.write(wb3, {type: 'dafuq'}); });
|
||||
assert.throws(function() { X.write(wb4, {type: 'dafuq'}); });
|
||||
});
|
||||
var fmts = [
|
||||
/* fmt unicode str */
|
||||
["xlsx", true, false],
|
||||
["xlsb", true, false],
|
||||
["xls", true, false],
|
||||
["xlml", true, true],
|
||||
["ods", true, false],
|
||||
["fods", true, true],
|
||||
["csv", true, true],
|
||||
["txt", true, true],
|
||||
["sylk", false, true],
|
||||
["html", true, true],
|
||||
["dif", false, true],
|
||||
["prn", false, true]
|
||||
];
|
||||
function RT(T) {
|
||||
if(!X) X = require(modp);
|
||||
fmts.forEach(function(fmt) {
|
||||
var wb = X.utils.book_new();
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([['R',"\u2603"],["\u0BEE",2]]), "Sheet1");
|
||||
if(T == 'string' && !fmt[2]) return assert.throws(function() {X.write(wb, {type: T, bookType:fmt[0], WTF:1});});
|
||||
var out = X.write(wb, {type: T, bookType:fmt[0], WTF:1});
|
||||
var nwb = X.read(out, {type: T, WTF:1});
|
||||
var nws = nwb.Sheets[nwb.SheetNames[0]];
|
||||
assert.equal(get_cell(nws, "B2").v, 2);
|
||||
assert.equal(get_cell(nws, "A1").v, "R");
|
||||
if(fmt[1]) assert.equal(get_cell(nws, "A2").v, "\u0BEE");
|
||||
if(fmt[1]) assert.equal(get_cell(nws, "B1").v, "\u2603");
|
||||
});
|
||||
}
|
||||
it('should write binary strings', function() { RT('binary'); });
|
||||
it('should write base64 strings', function() { RT('base64'); });
|
||||
it('should write JS strings', function() { RT('string'); });
|
||||
if(!browser) it('should write buffers', function() { RT('buffer'); });
|
||||
it('should throw if format is unknown', function() { assert.throws(function() { RT('dafuq'); }); });
|
||||
});
|
||||
|
||||
function eqarr(a,b) {
|
||||
@ -756,30 +763,32 @@ function check_margin(margins, exp) {
|
||||
|
||||
describe('parse features', function() {
|
||||
describe('sheet visibility', function() {
|
||||
var wb1, wb2, wb3, wb4, wb5;
|
||||
var wbs = [];
|
||||
var bef = (function() {
|
||||
wb1 = X.read(fs.readFileSync(paths.svxls), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.svxls5), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.svxml), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.svxlsx), {type:TYPE});
|
||||
wb5 = X.read(fs.readFileSync(paths.svxlsb), {type:TYPE});
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.svxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.svxls5), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.svxml), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.svxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.svxlsb), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
|
||||
it('should detect visible sheets', function() {
|
||||
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||
wbs.forEach(function(wb) {
|
||||
assert(!wb.Workbook.Sheets[0].Hidden);
|
||||
});
|
||||
});
|
||||
it('should detect all hidden sheets', function() {
|
||||
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||
wbs.forEach(function(wb) {
|
||||
assert(wb.Workbook.Sheets[1].Hidden);
|
||||
assert(wb.Workbook.Sheets[2].Hidden);
|
||||
});
|
||||
});
|
||||
it('should distinguish very hidden sheets', function() {
|
||||
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||
wbs.forEach(function(wb) {
|
||||
assert.equal(wb.Workbook.Sheets[1].Hidden,1);
|
||||
assert.equal(wb.Workbook.Sheets[2].Hidden,2);
|
||||
});
|
||||
@ -822,24 +831,44 @@ describe('parse features', function() {
|
||||
});
|
||||
|
||||
describe('should parse core properties and custom properties', function() {
|
||||
var wb1, wb2, wb3, wb4;
|
||||
var wbs=[];
|
||||
var bef = (function() {
|
||||
wb1 = X.read(fs.readFileSync(paths.cpxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.cpxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.cpxls), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.cpxml), {type:TYPE});
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.cpxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.cpxlsb), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.cpxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.cpxml), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
|
||||
it(N1 + ' should parse core properties', function() { coreprop(wb1); });
|
||||
it(N2 + ' should parse core properties', function() { coreprop(wb2); });
|
||||
it(N3 + ' should parse core properties', function() { coreprop(wb3); });
|
||||
it(N4 + ' should parse core properties', function() { coreprop(wb4); });
|
||||
it(N1 + ' should parse custom properties', function() { custprop(wb1); });
|
||||
it(N2 + ' should parse custom properties', function() { custprop(wb2); });
|
||||
it(N3 + ' should parse custom properties', function() { custprop(wb3); });
|
||||
it(N4 + ' should parse custom properties', function() { custprop(wb4); });
|
||||
[N1, N2, N3, N4].forEach(function(x, i) {
|
||||
it(x + ' should parse core properties', function() { coreprop(wbs[i]); });
|
||||
it(x + ' should parse custom properties', function() { custprop(wbs[i]); });
|
||||
});
|
||||
[
|
||||
["asxls", "BIFF8", "\u2603"],
|
||||
["asxls5", "BIFF5", "_"],
|
||||
["asxml", "XLML", "\u2603"],
|
||||
["asods", "ODS", "God"],
|
||||
["asxlsx", "XLSX", "\u2603"],
|
||||
["asxlsb", "XLSB", "\u2603"]
|
||||
].forEach(function(x) {
|
||||
(fs.existsSync(paths[x[0]]) ? it : it.skip)(x[1] + ' should read unicode author', function() {
|
||||
var wb = X.read(fs.readFileSync(paths[x[0]]), {type:TYPE});
|
||||
assert.equal(wb.Props.Author, x[2]);
|
||||
}); });
|
||||
var BASE = "இராமா";
|
||||
[ "xlsx", "xlsb", "xlml"/*, "ods", "xls" */].forEach(function(n) {
|
||||
it(n + ' should round-trip unicode category', function() {
|
||||
var wb = X.utils.book_new();
|
||||
X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([["a"]]), "Sheet1");
|
||||
if(!wb.Props) wb.Props = {};
|
||||
wb.Props.Category = BASE;
|
||||
var wb2 = X.read(X.write(wb, {bookType:n, type:TYPE}), {type:TYPE});
|
||||
assert.equal(wb2.Props.Category,BASE);
|
||||
}); });
|
||||
});
|
||||
|
||||
describe('sheetRows', function() {
|
||||
@ -930,6 +959,7 @@ describe('parse features', function() {
|
||||
describe('row properties', function() {
|
||||
var wb1, wb2, wb3, wb4, wb5, wb6;
|
||||
var ol1, ol2, ol3, ol4, ol5;
|
||||
var ol = fs.existsSync(paths.olxls);
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.read(fs.readFileSync(paths.rhxlsx), {type:TYPE, cellStyles:true});
|
||||
@ -938,6 +968,8 @@ describe('parse features', function() {
|
||||
wb4 = X.read(fs.readFileSync(paths.rhxls5), {type:TYPE, cellStyles:true});
|
||||
wb5 = X.read(fs.readFileSync(paths.rhxml), {type:TYPE, cellStyles:true});
|
||||
wb6 = X.read(fs.readFileSync(paths.rhslk), {type:TYPE, cellStyles:true});
|
||||
/* */
|
||||
if(!ol) return;
|
||||
ol1 = X.read(fs.readFileSync(paths.olxlsx), {type:TYPE, cellStyles:true});
|
||||
ol2 = X.read(fs.readFileSync(paths.olxlsb), {type:TYPE, cellStyles:true});
|
||||
ol3 = X.read(fs.readFileSync(paths.olxls), {type:TYPE, cellStyles:true});
|
||||
@ -964,7 +996,7 @@ describe('parse features', function() {
|
||||
assert.equal(x[3].hpx, 100);
|
||||
});
|
||||
});
|
||||
it('should have correct outline levels', function() {
|
||||
(ol ? it : it.skip)('should have correct outline levels', function() {
|
||||
/* TODO: ODS */
|
||||
[ol1, ol2, ol3, ol4/*, ol5*/].map(function(x) { return x.Sheets.Sheet1; }).forEach(function(ws) {
|
||||
var rows = ws['!rows'];
|
||||
@ -973,7 +1005,7 @@ describe('parse features', function() {
|
||||
var lvl = (rows[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);
|
||||
if(cell.v === 0) assert.equal(lvl, 0);
|
||||
else assert.equal(lvl, cell.v);
|
||||
}
|
||||
}
|
||||
@ -983,47 +1015,47 @@ describe('parse features', function() {
|
||||
});
|
||||
|
||||
describe('merge cells',function() {
|
||||
var wb1, wb2, wb3, wb4, wb5;
|
||||
var wbs=[];
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.read(fs.readFileSync(paths.mcxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.mcxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.mcods), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.mcxls), {type:TYPE});
|
||||
wb5 = X.read(fs.readFileSync(paths.mcxml), {type:TYPE});
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.mcxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.mcxlsb), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.mcods), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.mcxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.mcxml), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
it('should have !merges', function() {
|
||||
assert(wb1.Sheets.Merge['!merges']);
|
||||
assert(wb2.Sheets.Merge['!merges']);
|
||||
assert(wb3.Sheets.Merge['!merges']);
|
||||
assert(wb4.Sheets.Merge['!merges']);
|
||||
assert(wb5.Sheets.Merge['!merges']);
|
||||
var m = [wb1, wb2, wb3, wb4, wb5].map(function(x) { return x.Sheets.Merge['!merges'].map(function(y) { return X.utils.encode_range(y); });});
|
||||
assert.deepEqual(m[0].sort(),m[1].sort());
|
||||
assert.deepEqual(m[0].sort(),m[2].sort());
|
||||
assert.deepEqual(m[0].sort(),m[3].sort());
|
||||
assert.deepEqual(m[0].sort(),m[4].sort());
|
||||
wbs.forEach(function(wb) {
|
||||
assert(wb.Sheets.Merge['!merges']);
|
||||
});
|
||||
var m = wbs.map(function(x) { return x.Sheets.Merge['!merges'].map(function(y) { return X.utils.encode_range(y); });});
|
||||
m.slice(1).forEach(function(x) {
|
||||
assert.deepEqual(m[0].sort(),x.sort());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('should find hyperlinks', function() {
|
||||
var wb1, wb2, wb3, wb4;
|
||||
var wbs;
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.read(fs.readFileSync(paths.hlxlsx), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.hlxlsb), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.hlxls), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.hlxml), {type:TYPE});
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.hlxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.hlxlsb), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.hlxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.hlxml), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
|
||||
it(N1, function() { hlink(wb1); });
|
||||
it(N2, function() { hlink(wb2); });
|
||||
it(N3, function() { hlink(wb3); });
|
||||
it(N4, function() { hlink(wb4); });
|
||||
[N1, N2, N3, N4].forEach(function(x, i) {
|
||||
it(x, function() { hlink(wbs[i]); });
|
||||
});
|
||||
});
|
||||
|
||||
describe('should parse cells with date type (XLSX/XLSM)', function() {
|
||||
@ -1077,7 +1109,7 @@ describe('parse features', function() {
|
||||
['xlsx', paths.dnsxlsx, true],
|
||||
['xlsb', paths.dnsxlsb, true],
|
||||
['xls', paths.dnsxls, true],
|
||||
['xlml', paths.dnsxml, false],
|
||||
['xlml', paths.dnsxml, false]
|
||||
].forEach(function(m) { it(m[0], function() {
|
||||
var wb = X.read(fs.readFileSync(m[1]), {type:TYPE});
|
||||
var names = wb.Workbook.Names;
|
||||
@ -1103,9 +1135,9 @@ describe('parse features', function() {
|
||||
['ods', paths.afods]
|
||||
].forEach(function(m) { it(m[0], function() {
|
||||
var wb = X.read(fs.readFileSync(m[1]), {type:TYPE});
|
||||
assert(wb.Sheets[wb.SheetNames[0]]['!autofilter'] == null);
|
||||
assert(!wb.Sheets[wb.SheetNames[0]]['!autofilter']);
|
||||
for(var i = 1; i < wb.SheetNames.length; ++i) {
|
||||
assert(wb.Sheets[wb.SheetNames[i]]['!autofilter'] != null);
|
||||
assert(wb.Sheets[wb.SheetNames[i]]['!autofilter']);
|
||||
assert.equal(wb.Sheets[wb.SheetNames[i]]['!autofilter'].ref,"A1:E22");
|
||||
}
|
||||
}); });
|
||||
@ -1132,15 +1164,16 @@ describe('parse features', function() {
|
||||
});
|
||||
|
||||
describe('page margins', function() {
|
||||
var wb1, wb2, wb3, wb4, wb5, wbs;
|
||||
var wbs=[];
|
||||
var bef = (function() {
|
||||
if(!fs.existsSync(paths.pmxls)) return wbs=[];
|
||||
wb1 = X.read(fs.readFileSync(paths.pmxls), {type:TYPE});
|
||||
wb2 = X.read(fs.readFileSync(paths.pmxls5), {type:TYPE});
|
||||
wb3 = X.read(fs.readFileSync(paths.pmxml), {type:TYPE});
|
||||
wb4 = X.read(fs.readFileSync(paths.pmxlsx), {type:TYPE});
|
||||
wb5 = X.read(fs.readFileSync(paths.pmxlsb), {type:TYPE});
|
||||
wbs = [wb1, wb2, wb3, wb4, wb5];
|
||||
if(!fs.existsSync(paths.pmxls)) return;
|
||||
wbs = [
|
||||
X.read(fs.readFileSync(paths.pmxls), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.pmxls5), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.pmxml), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.pmxlsx), {type:TYPE}),
|
||||
X.read(fs.readFileSync(paths.pmxlsb), {type:TYPE})
|
||||
];
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
@ -1149,17 +1182,17 @@ describe('parse features', function() {
|
||||
check_margin(wb.Sheets["Normal"]["!margins"], [0.7, 0.7, 0.75, 0.75, 0.3, 0.3]);
|
||||
});
|
||||
});
|
||||
it('should parse wide margins ', function() {
|
||||
it('should parse wide margins', function() {
|
||||
wbs.forEach(function(wb) {
|
||||
check_margin(wb.Sheets["Wide"]["!margins"], [1, 1, 1, 1, 0.5, 0.5]);
|
||||
});
|
||||
});
|
||||
it('should parse narrow margins ', function() {
|
||||
it('should parse narrow margins', function() {
|
||||
wbs.forEach(function(wb) {
|
||||
check_margin(wb.Sheets["Narrow"]["!margins"], [0.25, 0.25, 0.75, 0.75, 0.3, 0.3]);
|
||||
});
|
||||
});
|
||||
it('should parse custom margins ', function() {
|
||||
it('should parse custom margins', function() {
|
||||
wbs.forEach(function(wb) {
|
||||
check_margin(wb.Sheets["Custom 1 Inch Centered"]["!margins"], [1, 1, 1, 1, 0.3, 0.3]);
|
||||
check_margin(wb.Sheets["1 Inch HF"]["!margins"], [0.7, 0.7, 0.75, 0.75, 1, 1]);
|
||||
@ -1255,7 +1288,7 @@ describe('write features', function() {
|
||||
baseprops = {
|
||||
Category: "Newspaper",
|
||||
ContentStatus: "Published",
|
||||
Keywords: "print",
|
||||
Keywords: "☃",
|
||||
LastAuthor: "Perry White",
|
||||
LastPrinted: "1978-12-15",
|
||||
RevNumber: 6969,
|
||||
@ -1271,7 +1304,7 @@ describe('write features', function() {
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
['xlml', 'xlsx', 'xlsb'].forEach(function(w) { it(w, function() {
|
||||
wb = {
|
||||
var wb = {
|
||||
Props: {},
|
||||
SheetNames: ["Sheet1"],
|
||||
Sheets: {Sheet1: ws}
|
||||
@ -1389,7 +1422,7 @@ describe('roundtrip features', function() {
|
||||
|
||||
if(m[0].t === 'n' && m[1].t === 'n') assert.equal(m[0].v, m[1].v);
|
||||
else if(m[0].t === 'd' && m[1].t === 'd') assert.equal(m[0].v.toString(), m[1].v.toString());
|
||||
else if(m[1].t === 'n') assert(Math.abs(datenum(parseDate(m[0].v)) - m[1].v) < 0.01);
|
||||
else if(m[1].t === 'n') assert(Math.abs(datenum(browser ? parseDate(m[0].v) : new Date(m[0].v)) - m[1].v) < 0.01);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1543,10 +1576,9 @@ describe('invalid files', function() {
|
||||
});
|
||||
describe('write', function() {
|
||||
it('should pass -> XLSX', function() {
|
||||
X.write(X.read(fs.readFileSync(paths.fstxlsb), {type:TYPE}), {type:TYPE});
|
||||
X.write(X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE}), {type:TYPE});
|
||||
X.write(X.read(fs.readFileSync(paths.fstxls), {type:TYPE}), {type:TYPE});
|
||||
X.write(X.read(fs.readFileSync(paths.fstxml), {type:TYPE}), {type:TYPE});
|
||||
["fstxlsb", "fstxlsx", "fstxls", "fstxml"].forEach(function(n) {
|
||||
X.write(X.read(fs.readFileSync(paths[n]), {type:TYPE}), {type:TYPE});
|
||||
});
|
||||
});
|
||||
it('should pass if a sheet is missing', function() {
|
||||
var wb = X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE}); delete wb.Sheets[wb.SheetNames[0]];
|
||||
@ -1700,16 +1732,16 @@ describe('json output', function() {
|
||||
var _data = [["S","h","e","e","t","J","S"],[1,2,3,4,5,6,7],[],[2,3,4,5,6,7,8]];
|
||||
var _ws = X.utils.aoa_to_sheet(_data);
|
||||
var json1 = X.utils.sheet_to_json(_ws);
|
||||
var json2 = X.utils.sheet_to_json(_ws, {header:1});
|
||||
var json3 = X.utils.sheet_to_json(_ws, {blankrows:true});
|
||||
var json4 = X.utils.sheet_to_json(_ws, {blankrows:true, header:1});
|
||||
var json5 = X.utils.sheet_to_json(_ws, {blankrows:false});
|
||||
var json6 = X.utils.sheet_to_json(_ws, {blankrows:false, header:1});
|
||||
assert.equal(json1.length, 2); // = 2 non-empty records
|
||||
var json2 = X.utils.sheet_to_json(_ws, {header:1});
|
||||
assert.equal(json2.length, 4); // = 4 sheet rows
|
||||
var json3 = X.utils.sheet_to_json(_ws, {blankrows:true});
|
||||
assert.equal(json3.length, 3); // = 2 records + 1 blank row
|
||||
var json4 = X.utils.sheet_to_json(_ws, {blankrows:true, header:1});
|
||||
assert.equal(json4.length, 4); // = 4 sheet rows
|
||||
var json5 = X.utils.sheet_to_json(_ws, {blankrows:false});
|
||||
assert.equal(json5.length, 2); // = 2 records
|
||||
var json6 = X.utils.sheet_to_json(_ws, {blankrows:false, header:1});
|
||||
assert.equal(json6.length, 3); // = 4 sheet rows - 1 blank row
|
||||
});
|
||||
it('should have an index that starts with zero when selecting range', function() {
|
||||
@ -1724,36 +1756,40 @@ describe('json output', function() {
|
||||
});
|
||||
|
||||
|
||||
var codes = [["あ 1", "\u00E3\u0081\u0082 1"]]
|
||||
var codes = [["あ 1", "\u00E3\u0081\u0082 1"]];
|
||||
var plaintext_val = [
|
||||
["A1", 'n', -0.08, "-0.08"],
|
||||
["B1", 'n', 4001, "4,001"],
|
||||
["C1", 's', "あ 1", "あ 1"],
|
||||
["A2", 'n', 41.08, "$41.08"],
|
||||
["B2", 'n', 0.11, "11%"],
|
||||
["B3", 'b', true, "TRUE"],
|
||||
["C3", 'b', false, "FALSE"],
|
||||
["A3"]];
|
||||
function plaintext_test(wb, raw, sn) {
|
||||
var sheet = wb.Sheets[sn || wb.SheetNames[0]];
|
||||
["C3", 'b', true, "TRUE"],
|
||||
["D3", 'b', false, "FALSE"],
|
||||
["B3", 's', " ", " "],
|
||||
["A3"]
|
||||
];
|
||||
function plaintext_test(wb, raw, t) {
|
||||
var sheet = wb.Sheets[wb.SheetNames[0]];
|
||||
plaintext_val.forEach(function(x) {
|
||||
var cell = get_cell(sheet, x[0]);
|
||||
var tcval = x[2+!!raw];
|
||||
var type = raw ? 's' : x[1]; // != 's' ? x[1] : tcval.length === 0 ? 'z' : 's';
|
||||
if(x.length == 1) { if(cell) { assert.equal(cell.t, 'z'); assert(!cell.v); } return; }
|
||||
assert.equal(cell.v, x[2+!!raw]); assert.equal(cell.t, raw ? 's' : x[1]);
|
||||
assert.equal(cell.v, tcval); assert.equal(cell.t, type);
|
||||
});
|
||||
}
|
||||
function make_html_str(idx) { return ["<table>",
|
||||
"<tr><td>-0.08</td><td>4,001</td><td>", codes[0][idx], "</td></tr>",
|
||||
"<tr><td>$41.08</td><td>11%</td></tr>",
|
||||
"<tr><td></td><td>TRUE</td><td>FALSE</td></tr>",
|
||||
"<tr><td></td><td> \n </td><td>TRUE</td><td>FALSE</td></tr>",
|
||||
"</table>" ].join(""); }
|
||||
function make_csv_str(idx) { return [ '\u00EF\u00BB\u00BF' +
|
||||
function make_csv_str(idx) { return [ (idx == 1 ? '\u00EF\u00BB\u00BF' : "") +
|
||||
'-0.08,"4,001",' + codes[0][idx] + '',
|
||||
'$41.08,11%',
|
||||
',TRUE,FALSE'
|
||||
', ,TRUE,FALSE'
|
||||
].join("\n"); }
|
||||
var html_bstr = make_html_str(1), html_str = make_html_str(0);
|
||||
var csv_bstr = make_csv_str(1);
|
||||
var csv_bstr = make_csv_str(1), csv_str = make_csv_str(0);
|
||||
|
||||
|
||||
describe('csv', function() {
|
||||
@ -1779,7 +1815,7 @@ describe('csv', function() {
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '2/19/14');
|
||||
opts.cellDates = true;
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '2/19/14');
|
||||
});
|
||||
it('should honor dateNF override', function() {
|
||||
@ -1788,7 +1824,7 @@ describe('csv', function() {
|
||||
/* NOTE: IE interprets 2-digit years as 19xx */
|
||||
assert(cell.w == '2014-02-19' || cell.w == '1914-02-19');
|
||||
opts.cellDates = true; opts.dateNF = "YY-MM-DD";
|
||||
var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3");
|
||||
assert.equal(cell.w, '14-02-19');
|
||||
});
|
||||
it('should interpret dateNF', function() {
|
||||
@ -1802,8 +1838,8 @@ describe('csv', function() {
|
||||
assert.equal(cell.v.getMonth(), 2);
|
||||
assert.equal(cell.w, "2/3/14");
|
||||
});
|
||||
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_bstr, {type:"binary", raw:true}), true); });
|
||||
it('should interpret values by default', function() { plaintext_test(X.read(csv_bstr, {type:"binary"}), false, false); });
|
||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(csv_bstr, {type:"binary", raw:true}), true, false); });
|
||||
it('should handle formulae', function() {
|
||||
var bb = '=,=1+1,="100"';
|
||||
var sheet = X.read(bb, {type:"binary"}).Sheets.Sheet1;
|
||||
@ -1903,12 +1939,13 @@ function get_dom_element(html) {
|
||||
|
||||
describe('HTML', function() {
|
||||
describe('input string', function(){
|
||||
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 interpret values by default', function() { plaintext_test(X.read(html_bstr, {type:"binary"}), false, false); });
|
||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.read(html_bstr, {type:"binary", raw:true}), true, false); });
|
||||
it('should handle "string" type', function() { plaintext_test(X.read(html_str, {type:"string"}), false, false); });
|
||||
});
|
||||
(domtest ? describe : describe.skip)('input DOM', function() {
|
||||
it('should interpret values by default', function() { plaintext_test(X.utils.table_to_book(get_dom_element(html_str)), false); });
|
||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.utils.table_to_book(get_dom_element(html_str), {raw:true}), true); });
|
||||
it('should interpret values by default', function() { plaintext_test(X.utils.table_to_book(get_dom_element(html_str)), false, true); });
|
||||
it('should generate strings if raw option is passed', function() { plaintext_test(X.utils.table_to_book(get_dom_element(html_str), {raw:true}), true, true); });
|
||||
});
|
||||
});
|
||||
|
||||
@ -1933,25 +1970,14 @@ describe('js -> file -> js', function() {
|
||||
ofmt.forEach(function(f) {
|
||||
it(f, function() {
|
||||
var newwb = X.read(X.write(wb, {type:BIN, bookType: f}), {type:BIN});
|
||||
/* int */
|
||||
eqcell(wb, newwb, 'Sheet1', 'A1');
|
||||
eqcell(wb, newwb, 'Sheet1', 'B1');
|
||||
eqcell(wb, newwb, 'Sheet1', 'C1');
|
||||
/* double */
|
||||
eqcell(wb, newwb, 'Sheet1', 'B4');
|
||||
/* bool */
|
||||
eqcell(wb, newwb, 'Sheet1', 'A2');
|
||||
eqcell(wb, newwb, 'Sheet1', 'B2');
|
||||
/* string */
|
||||
eqcell(wb, newwb, 'Sheet1', 'D2');
|
||||
eqcell(wb, newwb, 'Sheet1', 'A3');
|
||||
eqcell(wb, newwb, 'Sheet1', 'B3');
|
||||
eqcell(wb, newwb, 'Sheet1', 'A4');
|
||||
eqcell(wb, newwb, 'Sheet1', 'C4');
|
||||
var cb = function(cell) { eqcell(wb, newwb, 'Sheet1', cell); };
|
||||
['A1', 'B1', 'C1'].forEach(cb); /* int */
|
||||
['B4'].forEach(cb); /* double */
|
||||
['A2', 'B2'].forEach(cb); /* bool */
|
||||
['D2', 'A3', 'B3', 'A4', 'C4'].forEach(cb); /* string */
|
||||
if(!DIF_XL) cb('C3'); /* date */
|
||||
if(DIF_XL && f == "dif") assert.equal(get_cell(newwb.Sheets["Sheet1"], 'D3').v, '=""0.3""');// dif forces string formula
|
||||
else eqcell(wb, newwb, 'Sheet1', 'D3');
|
||||
/* date */
|
||||
if(!DIF_XL) eqcell(wb, newwb, 'Sheet1', 'C3');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1997,12 +2023,13 @@ describe('corner cases', function() {
|
||||
});
|
||||
it('SSF oddities', function() {
|
||||
var ssfdata = require('./misc/ssf.json');
|
||||
var cb = function(d, j) { return function() { return X.SSF.format(d[0], d[j][0]); }; };
|
||||
ssfdata.forEach(function(d) {
|
||||
for(var j=1;j<d.length;++j) {
|
||||
if(d[j].length == 2) {
|
||||
var expected = d[j][1], actual = X.SSF.format(d[0], d[j][0], {});
|
||||
assert.equal(actual, expected);
|
||||
} else if(d[j][2] !== "#") assert.throws(function() { SSF.format(d[0], d[j][0]); });
|
||||
} else if(d[j][2] !== "#") assert.throws(cb(d, j));
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -2031,7 +2058,7 @@ describe('encryption', function() {
|
||||
}
|
||||
});
|
||||
it.skip('should decrypt file', function() {
|
||||
var wb = X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
|
||||
/*var wb = */X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,3 +1,33 @@
|
||||
./test_files/artifacts/quattro/write_.csv
|
||||
./test_files/artifacts/quattro/write_.dif
|
||||
./test_files/artifacts/quattro/write_.slk
|
||||
./test_files/artifacts/quattro/write_57.xls
|
||||
./test_files/artifacts/quattro/write_6.wb2
|
||||
./test_files/artifacts/quattro/write_6b.wb2
|
||||
./test_files/artifacts/quattro/write_8.wb3
|
||||
./test_files/artifacts/quattro/write_9.qpw
|
||||
./test_files/artifacts/quattro/write_97.xls
|
||||
./test_files/artifacts/quattro/write_L1.wks
|
||||
./test_files/artifacts/quattro/write_L2.wk1
|
||||
./test_files/artifacts/quattro/write_L3.wk3
|
||||
./test_files/artifacts/quattro/write_L45.wk4
|
||||
./test_files/artifacts/quattro/write_L9.123
|
||||
./test_files/artifacts/quattro/write_L97.123
|
||||
./test_files/artifacts/quattro/write_Led.wke
|
||||
./test_files/artifacts/quattro/write_qpdos.wq1
|
||||
./test_files/artifacts/quattro/write_qpw.wb1
|
||||
./test_files/artifacts/wps/write.dbf
|
||||
./test_files/artifacts/wps/write.dif
|
||||
./test_files/artifacts/wps/write.et
|
||||
./test_files/artifacts/wps/write.xls
|
||||
./test_files/artifacts/wps/write.xlsx
|
||||
./test_files/artifacts/wps/write.xml
|
||||
./test_files/author_snowman.xls
|
||||
./test_files/author_snowman.xls5
|
||||
./test_files/author_snowman.xlsb
|
||||
./test_files/author_snowman.xlsx
|
||||
./test_files/author_snowman.xml
|
||||
./test_files/author_snowman.ods
|
||||
./test_files/AutoFilter.xls
|
||||
./test_files/AutoFilter.xml
|
||||
./test_files/AutoFilter.ods
|
||||
|
@ -6,7 +6,7 @@ var data = [
|
||||
[1, 2, 3],
|
||||
[true, false, null, "sheetjs"],
|
||||
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
|
||||
["baz", null, "qux", 3.14159],
|
||||
["baz", null, "\u0BEE", 3.14159],
|
||||
["hidden"],
|
||||
["visible"]
|
||||
];
|
||||
|
305
xlsx.flow.js
305
xlsx.flow.js
@ -6,7 +6,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.11.4';
|
||||
XLSX.version = '0.11.5';
|
||||
var current_codepage = 1200;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true */
|
||||
@ -1974,7 +1974,7 @@ function getzipfile(zip, file/*:string*/) {
|
||||
return o;
|
||||
}
|
||||
|
||||
function getzipdata(zip, file/*:string*/, safe/*:?boolean*/) {
|
||||
function getzipdata(zip, file/*:string*/, safe/*:?boolean*/)/*:any*/ {
|
||||
if(!safe) return getdata(getzipfile(zip, file));
|
||||
if(!file) return null;
|
||||
try { return getzipdata(zip, file); } catch(e) { return null; }
|
||||
@ -2111,6 +2111,31 @@ var utf8read/*:StringConv*/ = function utf8reada(orig) {
|
||||
return out;
|
||||
};
|
||||
|
||||
var utf8write/*:StringConv*/ = function(orig) {
|
||||
var out = [], i = 0, c = 0, d = 0;
|
||||
while(i < orig.length) {
|
||||
c = orig.charCodeAt(i++);
|
||||
switch(true) {
|
||||
case c < 128: out.push(String.fromCharCode(c)); break;
|
||||
case c < 2048:
|
||||
out.push(String.fromCharCode(192 + (c >> 6)));
|
||||
out.push(String.fromCharCode(128 + (c & 63)));
|
||||
break;
|
||||
case c >= 55296 && c < 57344:
|
||||
c -= 55296; d = orig.charCodeAt(i++) - 56320 + (c<<10);
|
||||
out.push(String.fromCharCode(240 + ((d >>18) & 7)));
|
||||
out.push(String.fromCharCode(144 + ((d >>12) & 63)));
|
||||
out.push(String.fromCharCode(128 + ((d >> 6) & 63)));
|
||||
out.push(String.fromCharCode(128 + (d & 63)));
|
||||
break;
|
||||
default:
|
||||
out.push(String.fromCharCode(224 + (c >> 12)));
|
||||
out.push(String.fromCharCode(128 + ((c >> 6) & 63)));
|
||||
out.push(String.fromCharCode(128 + (c & 63)));
|
||||
}
|
||||
}
|
||||
return out.join("");
|
||||
};
|
||||
|
||||
if(has_buf) {
|
||||
var utf8readb = function utf8readb(data) {
|
||||
@ -2134,6 +2159,8 @@ if(has_buf) {
|
||||
// $FlowIgnore
|
||||
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
|
||||
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
|
||||
|
||||
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
|
||||
}
|
||||
|
||||
// matches <foo>...</foo> extracts content
|
||||
@ -2146,6 +2173,10 @@ var matchtag = (function() {
|
||||
};
|
||||
})();
|
||||
|
||||
function htmldecode(str/*:string*/)/*:string*/ {
|
||||
return str.trim().replace(/\s+/g, " ").replace(/<\s*[bB][rR]\s*\/?/g,"\n").replace(/<[^>]*>/g,"").replace(/ /g, " ");
|
||||
}
|
||||
|
||||
var vtregex = (function(){ var vt_cache = {};
|
||||
return function vt_regex(bt) {
|
||||
if(vt_cache[bt] !== undefined) return vt_cache[bt];
|
||||
@ -2214,7 +2245,7 @@ var XLMLNS = ({
|
||||
'v': 'urn:schemas-microsoft-com:vml',
|
||||
'html': 'http://www.w3.org/TR/REC-html40'
|
||||
}/*:any*/);
|
||||
function read_double_le(b, idx/*:number*/)/*:number*/ {
|
||||
function read_double_le(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ {
|
||||
var s = 1 - 2 * (b[idx + 7] >>> 7);
|
||||
var e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f);
|
||||
var m = (b[idx+6]&0x0f);
|
||||
@ -2225,7 +2256,7 @@ function read_double_le(b, idx/*:number*/)/*:number*/ {
|
||||
return s * Math.pow(2, e - 52) * m;
|
||||
}
|
||||
|
||||
function write_double_le(b, v/*:number*/, idx/*:number*/) {
|
||||
function write_double_le(b/*:RawBytes|CFBlob*/, v/*:number*/, idx/*:number*/) {
|
||||
var bs = ((v < 0 || 1/v == -Infinity) ? 1 : 0) << 7, e = 0, m = 0;
|
||||
var av = bs ? -v : v;
|
||||
if(!isFinite(av)) { e = 0x7ff; m = isNaN(v) ? 0x6969 : 0; }
|
||||
@ -2241,61 +2272,61 @@ function write_double_le(b, v/*:number*/, idx/*:number*/) {
|
||||
b[idx + 7] = (e >> 4) | bs;
|
||||
}
|
||||
|
||||
var __toBuffer, ___toBuffer;
|
||||
__toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var __utf16le, ___utf16le;
|
||||
__utf16le = ___utf16le = function utf16le_(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var ___toBuffer = __toBuffer;
|
||||
var __utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var ___utf16le = __utf16le;
|
||||
var __hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };
|
||||
var ___hexlify = __hexlify;
|
||||
var __utf8, ___utf8;
|
||||
__utf8 = ___utf8 = function(b,s,e) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
|
||||
var __lpstr, ___lpstr;
|
||||
__lpstr = ___lpstr = function lpstr_(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __lpwstr, ___lpwstr;
|
||||
__lpwstr = ___lpwstr = function lpwstr_(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
|
||||
var ___utf8 = __utf8;
|
||||
var __lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpstr = __lpstr;
|
||||
var __lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpwstr = __lpwstr;
|
||||
var __lpp4, ___lpp4;
|
||||
__lpp4 = ___lpp4 = function lpp4_(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : "";};
|
||||
var __8lpp4, ___8lpp4;
|
||||
__8lpp4 = ___8lpp4 = function lpp4_8(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
|
||||
__lpp4 = ___lpp4 = function lpp4_(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : "";};
|
||||
var __8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
|
||||
var ___8lpp4 = __8lpp4;
|
||||
var __double, ___double;
|
||||
__double = ___double = function(b, idx) { return read_double_le(b, idx);};
|
||||
|
||||
__double = ___double = function(b/*:RawBytes|CFBlob*/, idx/*:number*/) { return read_double_le(b, idx);};
|
||||
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
|
||||
if(has_buf/*:: && typeof Buffer != 'undefined'*/) {
|
||||
__utf16le = function utf16le_b(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b,i) { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
__utf8 = function utf8_b(b, s,e) { return b.toString('utf8',s,e); };
|
||||
|
||||
if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { return Buffer.isBuffer(b)/*:: && b instanceof Buffer*/ ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
__utf8 = function utf8_b(b/*:RawBytes|CFBlob*/, s/*:number*/, e/*:number*/) { return (Buffer.isBuffer(b)/*:: && (b instanceof Buffer)*/) ? b.toString('utf8',s,e) : __utf8(b,s,e); };
|
||||
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
|
||||
bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); };
|
||||
__double = function double_(b,i) { if(Buffer.isBuffer(b)/*::&& b instanceof Buffer*/) return b.readDoubleLE(i); return ___double(b,i); };
|
||||
__double = function double_(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(Buffer.isBuffer(b)/*::&& b instanceof Buffer*/) return b.readDoubleLE(i); return ___double(b,i); };
|
||||
is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
|
||||
}
|
||||
|
||||
/* from js-xls */
|
||||
if(typeof cptable !== 'undefined') {
|
||||
__utf16le = function(b,s,e) { return cptable.utils.decode(1200, b.slice(s,e)); };
|
||||
__utf8 = function(b,s,e) { return cptable.utils.decode(65001, b.slice(s,e)); };
|
||||
__lpstr = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpwstr = function(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
|
||||
__lpp4 = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
|
||||
__8lpp4 = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
|
||||
__utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(1200, b.slice(s,e)); };
|
||||
__utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return cptable.utils.decode(65001, b.slice(s,e)); };
|
||||
__lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
|
||||
__lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
|
||||
__lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
|
||||
__8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
|
||||
}
|
||||
|
||||
var __readUInt8 = function(b, idx/*:number*/)/*:number*/ { return b[idx]; };
|
||||
var __readUInt16LE = function(b, idx/*:number*/)/*:number*/ { return b[idx+1]*(1<<8)+b[idx]; };
|
||||
var __readInt16LE = function(b, idx/*:number*/)/*:number*/ { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
|
||||
var __readUInt32LE = function(b, idx/*:number*/)/*:number*/ { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
|
||||
var __readInt32LE = function(b, idx/*:number*/)/*:number*/ { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
|
||||
var __readUInt8 = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx]; };
|
||||
var __readUInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx+1]*(1<<8)+b[idx]; };
|
||||
var __readInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
|
||||
var __readUInt32LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
|
||||
var __readInt32LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
|
||||
|
||||
var ___unhexlify = function(s) { return s.match(/../g).map(function(x) { return parseInt(x,16);}); };
|
||||
var __unhexlify = typeof Buffer !== "undefined" ? function(s) { return Buffer.isBuffer(s) ? new Buffer(s, 'hex') : ___unhexlify(s); } : ___unhexlify;
|
||||
var ___unhexlify = function(s/*:string*/)/*:Array<number>*/ { return (s.match(/../g)||[]).map(function(x) { return parseInt(x,16);}); };
|
||||
var __unhexlify = typeof Buffer !== "undefined" ? function(s/*:string*/)/*:Array<number>|Buffer*/ { return Buffer.isBuffer(s) ? new Buffer(s, 'hex') : ___unhexlify(s); } : ___unhexlify;
|
||||
|
||||
function ReadShift(size/*:number*/, t/*:?string*/) {
|
||||
var o="", oI, oR, oo=[], w, vv, i, loc;
|
||||
function ReadShift(size/*:number*/, t/*:?string*/)/*:number|string*/ {
|
||||
var o="", oI/*:: :number = 0*/, oR, oo=[], w, vv, i, loc;
|
||||
switch(t) {
|
||||
case 'dbcs':
|
||||
loc = this.l;
|
||||
@ -2367,11 +2398,11 @@ function ReadShift(size/*:number*/, t/*:?string*/) {
|
||||
this.l+=size; return o;
|
||||
}
|
||||
|
||||
var __writeUInt16LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
|
||||
var __writeUInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };
|
||||
var __writeInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
|
||||
var __writeUInt32LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };
|
||||
var __writeInt32LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
|
||||
var __writeUInt16LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
|
||||
|
||||
function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/) {
|
||||
function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/)/*:any*/ {
|
||||
var size = 0, i = 0;
|
||||
if(f === 'dbcs') {
|
||||
/*:: if(typeof val !== 'string') throw new Error("unreachable"); */
|
||||
@ -2387,6 +2418,7 @@ function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/) {
|
||||
this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;
|
||||
} return this;
|
||||
} else if(f === 'utf16le') {
|
||||
/*:: if(typeof val !== "string") throw new Error("unreachable"); */
|
||||
var end/*:number*/ = this.l + t;
|
||||
for(i = 0; i < Math.min(val.length, t); ++i) {
|
||||
var cc = val.charCodeAt(i);
|
||||
@ -2408,20 +2440,20 @@ function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/) {
|
||||
this.l += size; return this;
|
||||
}
|
||||
|
||||
function CheckField(hexstr, fld) {
|
||||
function CheckField(hexstr/*:string*/, fld/*:string*/)/*:void*/ {
|
||||
var m = __hexlify(this,this.l,hexstr.length>>1);
|
||||
if(m !== hexstr) throw fld + 'Expected ' + hexstr + ' saw ' + m;
|
||||
if(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);
|
||||
this.l += hexstr.length>>1;
|
||||
}
|
||||
|
||||
function prep_blob(blob, pos/*:number*/) {
|
||||
function prep_blob(blob, pos/*:number*/)/*:void*/ {
|
||||
blob.l = pos;
|
||||
blob.read_shift = ReadShift;
|
||||
blob.read_shift = /*::(*/ReadShift/*:: :any)*/;
|
||||
blob.chk = CheckField;
|
||||
blob.write_shift = WriteShift;
|
||||
}
|
||||
|
||||
function parsenoop(blob, length/*:number*/) { blob.l += length; }
|
||||
function parsenoop(blob, length/*:: :number, opts?:any */) { blob.l += length; }
|
||||
function parsenooplog(blob, length/*:number*/) { if(typeof console != 'undefined') console.log(blob.slice(blob.l, blob.l + length)); blob.l += length; }
|
||||
|
||||
function writenoop(blob, length/*:number*/) { blob.l += length; }
|
||||
@ -3709,6 +3741,7 @@ var CORE_PROPS_REGEX/*:Array<RegExp>*/ = (function() {
|
||||
|
||||
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]);
|
||||
@ -3776,6 +3809,7 @@ RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relatio
|
||||
|
||||
function parse_ext_props(data, p, opts) {
|
||||
var q = {}; if(!p) p = {};
|
||||
data = utf8read(data);
|
||||
|
||||
EXT_PROPS.forEach(function(f) {
|
||||
switch(f[2]) {
|
||||
@ -4216,7 +4250,7 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
case 1252:
|
||||
case 65000: case -536:
|
||||
case 65001: case -535:
|
||||
set_cp(CodePage = PropH[piddsi.n]); break;
|
||||
set_cp(CodePage = PropH[piddsi.n]>>>0 & 0xFFFF); break;
|
||||
default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
|
||||
}
|
||||
} else {
|
||||
@ -4258,6 +4292,7 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
/* [MS-OLEPS] 2.21 PropertySetStream */
|
||||
function parse_PropertySetStream(file, PIDSI) {
|
||||
var blob = file.content;
|
||||
if(!blob) return ({}/*:any*/);
|
||||
prep_blob(blob, 0);
|
||||
|
||||
var NumSets, FMTID0, FMTID1, Offset0, Offset1 = 0;
|
||||
@ -4478,7 +4513,7 @@ function parse_XLSCell(blob, length)/*:Cell*/ {
|
||||
var ixfe = blob.read_shift(2);
|
||||
return ({r:rw, c:col, ixfe:ixfe}/*:any*/);
|
||||
}
|
||||
function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:number*/, o) {
|
||||
function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:?number*/, o) {
|
||||
if(!o) o = new_buf(6);
|
||||
o.write_shift(2, R);
|
||||
o.write_shift(2, C);
|
||||
@ -5768,7 +5803,7 @@ var SYLK = (function() {
|
||||
|
||||
function sheet_to_sylk(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
|
||||
var preamble/*:Array<string>*/ = ["ID;PWXL;N;E"], o/*:Array<string>*/ = [];
|
||||
var r = decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
var RS = "\r\n";
|
||||
|
||||
@ -5852,7 +5887,7 @@ var DIF = (function() {
|
||||
};
|
||||
return function sheet_to_dif(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
|
||||
var o/*:Array<string>*/ = [];
|
||||
var r = decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
push_field(o, "TABLE", 0, 1, "sheetjs");
|
||||
push_field(o, "VECTORS", 0, r.e.r - r.s.r + 1,"");
|
||||
@ -5968,6 +6003,7 @@ var PRN = (function() {
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length == 0) cell.t = 'z';
|
||||
else if(o.raw) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.trim().length == 0) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.charCodeAt(0) == 0x3D) {
|
||||
if(s.charCodeAt(1) == 0x22 && s.charCodeAt(s.length - 1) == 0x22) { cell.t = 's'; cell.v = s.slice(2,-1).replace(/""/g,'"'); }
|
||||
else if(fuzzyfmla(s)) { cell.t = 'n'; cell.f = s.substr(1); }
|
||||
@ -6013,12 +6049,13 @@ var PRN = (function() {
|
||||
}
|
||||
|
||||
function prn_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
|
||||
var str = "", bytes = firstbyte(d, opts);
|
||||
var str = "", bytes = opts.type == 'string' ? [0,0,0,0] : firstbyte(d, opts);
|
||||
switch(opts.type) {
|
||||
case 'base64': str = Base64.decode(d); break;
|
||||
case 'binary': str = d; break;
|
||||
case 'buffer': str = d.toString('binary'); break;
|
||||
case 'array': str = cc2str(d); break;
|
||||
case 'string': str = d; break;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
|
||||
@ -6029,7 +6066,7 @@ var PRN = (function() {
|
||||
|
||||
function sheet_to_prn(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
|
||||
var o/*:Array<string>*/ = [];
|
||||
var r = decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
var oo = [];
|
||||
@ -9349,7 +9386,7 @@ function parse_Rgce(blob, length, opts) {
|
||||
return ptgs;
|
||||
}
|
||||
|
||||
function stringify_array(f) {
|
||||
function stringify_array(f)/*:string*/ {
|
||||
var o = [];
|
||||
for(var i = 0; i < f.length; ++i) {
|
||||
var x = f[i], r = [];
|
||||
@ -9395,7 +9432,7 @@ function get_ixti_raw(supbooks, ixti/*:number*/, opts)/*:string*/ {
|
||||
function get_ixti(supbooks, ixti/*:number*/, opts)/*:string*/ {
|
||||
return formula_quote_sheet_name(get_ixti_raw(supbooks, ixti, opts));
|
||||
}
|
||||
function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, opts) {
|
||||
function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, opts)/*:string*/ {
|
||||
//console.log(formula);
|
||||
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
|
||||
var stack/*:Array<string>*/ = [], e1, e2, type, c/*:CellAddress*/, ixti=0, nameidx=0, r, sname="";
|
||||
@ -9487,7 +9524,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
||||
case 'PtgFuncVar': /* 2.5.198.63 */
|
||||
//console.log(f[1]);
|
||||
/* f[1] = [argc, func, type] */
|
||||
var argc/*:number*/ = f[1][0], func/*:string*/ = f[1][1];
|
||||
var argc/*:number*/ = (f[1][0]/*:any*/), func/*:string*/ = (f[1][1]/*:any*/);
|
||||
if(!argc) argc = 0;
|
||||
var args = argc == 0 ? [] : stack.slice(-argc);
|
||||
stack.length -= argc;
|
||||
@ -12065,7 +12102,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
case 's': sstr = strs[val[1]]; p.v = sstr.t; p.r = sstr.r; break;
|
||||
case 'b': p.v = val[1] ? true : false; break;
|
||||
case 'e': p.v = val[1]; if(opts.cellText !== false) p.w = BErr[p.v]; break;
|
||||
case 'str': p.t = 's'; p.v = utf8read(val[1]); break;
|
||||
case 'str': p.t = 's'; p.v = val[1]; break;
|
||||
}
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.numFmtId,null,opts, themes, styles);
|
||||
C = val[0].c;
|
||||
@ -13471,7 +13508,10 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
|
||||
var opts = _opts || {};
|
||||
make_ssf(SSF);
|
||||
var str = debom(xlml_normalize(d));
|
||||
if(opts && opts.type == 'binary' && typeof cptable !== 'undefined') str = cptable.utils.decode(65001, char_codes(str));
|
||||
if(opts.type == 'binary' || opts.type == 'base64') {
|
||||
if(typeof cptable !== 'undefined') str = cptable.utils.decode(65001, char_codes(str));
|
||||
else str = utf8read(str);
|
||||
}
|
||||
var opening = str.slice(0, 1024).toLowerCase(), ishtml = false;
|
||||
if(opening.indexOf("<?xml") == -1) ["html", "table", "head", "meta", "script", "style", "div"].forEach(function(tag) { if(opening.indexOf("<" + tag) >= 0) ishtml = true; });
|
||||
if(ishtml) return HTML_.to_workbook(str, opts);
|
||||
@ -14298,12 +14338,6 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{
|
||||
case 's': t = 'String'; p = escapexml(cell.v||""); break;
|
||||
}
|
||||
var _v = (cell.v != null ? p : "");
|
||||
if(opts && opts.type == 'binary' && typeof cptable !== 'undefined' && cell.t == 's') {
|
||||
_v = cptable.utils.encode(65001, _v);
|
||||
var __v = "";
|
||||
for(var __i = 0; __i < _v.length; ++__i) __v += String.fromCharCode(_v[__i]);
|
||||
_v = __v;
|
||||
}
|
||||
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
|
||||
|
||||
if((cell.c||[]).length > 0) m += write_ws_xlml_comment(cell.c);
|
||||
@ -14388,9 +14422,10 @@ function write_xlml(wb, opts)/*:string*/ {
|
||||
});
|
||||
}
|
||||
/* [MS-OLEDS] 2.3.8 CompObjStream */
|
||||
function parse_compobj(obj) {
|
||||
function parse_compobj(obj/*:CFBEntry*/) {
|
||||
var v = {};
|
||||
var o = obj.content;
|
||||
/*:: if(o == null) return; */
|
||||
|
||||
/* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */
|
||||
var l = 28, m;
|
||||
@ -15208,25 +15243,31 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
}
|
||||
|
||||
/* TODO: WTF */
|
||||
function parse_props(cfb) {
|
||||
function parse_props(cfb/*:CFBContainer*/, props, o) {
|
||||
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
|
||||
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
|
||||
if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {/* empty */}
|
||||
if(DSI) try {
|
||||
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI);
|
||||
for(var d in DocSummary) props[d] = DocSummary[d];
|
||||
} catch(e) {if(o.WTF == 2) throw e;/* empty */}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
|
||||
var SI = CFB.find(cfb, '!SummaryInformation');
|
||||
if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {/* empty */}
|
||||
if(SI) try {
|
||||
var Summary = parse_PropertySetStream(SI, SummaryPIDSI);
|
||||
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
|
||||
} catch(e) {if(o.WTF == 2) throw e;/* empty */}
|
||||
}
|
||||
|
||||
function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
if(!options) options = {};
|
||||
fix_read_opts(options);
|
||||
reset_cp();
|
||||
var CompObj, Summary, WB/*:?any*/;
|
||||
var CompObj/*:?CFBEntry*/, Summary, WB/*:?any*/;
|
||||
if(cfb.FullPaths) {
|
||||
CompObj = CFB.find(cfb, '!CompObj');
|
||||
Summary = CFB.find(cfb, '!SummaryInformation');
|
||||
WB = CFB.find(cfb, '/Workbook');
|
||||
WB = CFB.find(cfb, '/Workbook') || CFB.find(cfb, '/Book');
|
||||
} else {
|
||||
switch(options.type) {
|
||||
case 'base64': cfb = s2a(Base64.decode(cfb)); break;
|
||||
@ -15237,26 +15278,24 @@ if(cfb.FullPaths) {
|
||||
prep_blob(cfb, 0);
|
||||
WB = ({content: cfb}/*:any*/);
|
||||
}
|
||||
if(!WB) WB = CFB.find(cfb, '/Book');
|
||||
var CompObjP, SummaryP, WorkbookP/*:Workbook*/;
|
||||
var CompObjP, SummaryP, WorkbookP/*:: :Workbook = XLSX.utils.book_new(); */;
|
||||
|
||||
var _data/*:?any*/;
|
||||
if(CompObj) CompObjP = parse_compobj(CompObj);
|
||||
if(options.bookProps && !options.bookSheets) WorkbookP = ({}/*:any*/);
|
||||
else {
|
||||
else/*:: if(cfb instanceof CFBContainer) */ {
|
||||
var T = has_buf ? 'buffer' : 'array';
|
||||
if(WB && WB.content) WorkbookP = parse_workbook(WB.content, options);
|
||||
/* Quattro Pro 7-8 */
|
||||
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
|
||||
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
/* Quattro Pro 9 */
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
else throw new Error("Cannot find Workbook stream");
|
||||
}
|
||||
|
||||
if(cfb.FullPaths) parse_props(cfb);
|
||||
|
||||
var props = {};
|
||||
for(var y in cfb.Summary) props[y] = cfb.Summary[y];
|
||||
for(y in cfb.DocSummary) props[y] = cfb.DocSummary[y];
|
||||
if(cfb.FullPaths) parse_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options);
|
||||
|
||||
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
|
||||
if(options.bookFiles) WorkbookP.cfb = cfb;
|
||||
/*WorkbookP.CompObjP = CompObjP; // TODO: storage? */
|
||||
@ -16534,7 +16573,7 @@ var XLSRecordEnum = {
|
||||
|
||||
var XLSRE = evert_key(XLSRecordEnum, 'n');
|
||||
function write_biff_rec(ba/*:BufArray*/, type/*:number|string*/, payload, length/*:?number*/) {
|
||||
var t/*:number*/ = +type || +XLSRE[type];
|
||||
var t/*:number*/ = +type || +XLSRE[/*::String(*/type/*::)*/];
|
||||
if(isNaN(t)) return;
|
||||
var len = length || (payload||[]).length || 0;
|
||||
var o = ba.next(4 + len);
|
||||
@ -16783,7 +16822,7 @@ var HTML_ = (function() {
|
||||
if((RS = +tag.rowspan)>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
|
||||
/* TODO: generate stub cells */
|
||||
if(!m.length) { C += CS; continue; }
|
||||
m = unescapexml(m).replace(/[\r\n]/g,"");
|
||||
m = htmldecode(unescapexml(m));
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
@ -16791,7 +16830,7 @@ var HTML_ = (function() {
|
||||
if(opts.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
if(!m.length){}
|
||||
else if(opts.raw) ws[R][C] = {t:'s', v:m};
|
||||
else if(opts.raw || !m.trim().length) ws[R][C] = {t:'s', v:m};
|
||||
else if(m === 'TRUE') ws[R][C] = {t:'b', v:true};
|
||||
else if(m === 'FALSE') ws[R][C] = {t:'b', v:false};
|
||||
else if(!isNaN(fuzzynum(m))) ws[R][C] = {t:'n', v:fuzzynum(m)};
|
||||
@ -16801,6 +16840,7 @@ var HTML_ = (function() {
|
||||
/* TODO: value parsing */
|
||||
if(!m.length){}
|
||||
else if(opts.raw) ws[coord] = {t:'s', v:m};
|
||||
else if(opts.raw || !m.trim().length) ws[coord] = {t:'s', v:m};
|
||||
else if(m === 'TRUE') ws[coord] = {t:'b', v:true};
|
||||
else if(m === 'FALSE') ws[coord] = {t:'b', v:false};
|
||||
else if(!isNaN(fuzzynum(m))) ws[coord] = {t:'n', v:fuzzynum(m)};
|
||||
@ -16885,7 +16925,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
|
||||
var row = rows[R];
|
||||
var elts = row.children;
|
||||
for(_C = C = 0; _C < elts.length; ++_C) {
|
||||
var elt = elts[_C], v = elts[_C].innerText || elts[_C].textContent || "";
|
||||
var elt = elts[_C], v = htmldecode(elts[_C].innerHTML);
|
||||
for(midx = 0; midx < merges.length; ++midx) {
|
||||
var m = merges[midx];
|
||||
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
|
||||
@ -16897,6 +16937,7 @@ function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
|
||||
if(v != null) {
|
||||
if(v.length == 0) o.t = 'z';
|
||||
else if(opts.raw){}
|
||||
else if(v.trim().length == 0) o.t = 's';
|
||||
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)};
|
||||
@ -17386,7 +17427,9 @@ function parse_ods(zip/*:ZIPFile*/, opts/*:?ParseOpts*/) {
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
var content = getzipstr(zip, 'content.xml');
|
||||
if(!content) throw new Error("Missing content.xml in " + (ods ? "ODS" : "UOF")+ " file");
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
var wb = parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
if(safegetzipfile(zip, 'meta.xml')) wb.Props = parse_core_props(getzipdata(zip, 'meta.xml'));
|
||||
return wb;
|
||||
}
|
||||
function parse_fods(data/*:string*/, opts/*:?ParseOpts*/) {
|
||||
return parse_content_xml(data, opts);
|
||||
@ -17654,8 +17697,7 @@ function get_sheet_type(n/*:string*/)/*:string*/ {
|
||||
if(RELS.CS && n == RELS.CS) return "chart";
|
||||
if(RELS.DS && n == RELS.DS) return "dialog";
|
||||
if(RELS.MS && n == RELS.MS) return "macro";
|
||||
if(!n || !n.length) return "sheet";
|
||||
return n;
|
||||
return (n && n.length) ? n : "sheet";
|
||||
}
|
||||
function safe_parse_wbrels(wbrels, sheets) {
|
||||
if(!wbrels) return 0;
|
||||
@ -17739,10 +17781,10 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
var props = {}, propdata = "";
|
||||
|
||||
if(dir.coreprops.length) {
|
||||
propdata = getzipstr(zip, strip_front_slash(dir.coreprops[0]), true);
|
||||
propdata = getzipdata(zip, strip_front_slash(dir.coreprops[0]), true);
|
||||
if(propdata) props = parse_core_props(propdata);
|
||||
if(dir.extprops.length !== 0) {
|
||||
propdata = getzipstr(zip, strip_front_slash(dir.extprops[0]), true);
|
||||
propdata = getzipdata(zip, strip_front_slash(dir.extprops[0]), true);
|
||||
if(propdata) parse_ext_props(propdata, props, opts);
|
||||
}
|
||||
}
|
||||
@ -18051,13 +18093,23 @@ function read_utf16(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ {
|
||||
return read_plaintext(d, o);
|
||||
}
|
||||
|
||||
function bstrify(data/*:string*/)/*:string*/ {
|
||||
return !data.match(/[^\x00-\x7F]/) ? data : utf8write(data);
|
||||
}
|
||||
|
||||
function read_prn(data, d, o, str) {
|
||||
if(str) { o.type = "string"; return PRN.to_workbook(data, o); }
|
||||
return PRN.to_workbook(d, o);
|
||||
}
|
||||
|
||||
function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
var zip, d = data, n=[0];
|
||||
var zip, d = data, n=[0], str = false;
|
||||
var o = opts||{};
|
||||
_ssfopts = {};
|
||||
if(o.dateNF) _ssfopts.dateNF = o.dateNF;
|
||||
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
|
||||
if(o.type == "file") { o.type = "buffer"; d = _fs.readFileSync(data); }
|
||||
if(o.type == "string") { str = true; o.type = "binary"; d = bstrify(data); }
|
||||
switch((n = firstbyte(d, o))[0]) {
|
||||
case 0xD0: return read_cfb(CFB.read(d, o), o);
|
||||
case 0x09: return parse_xlscfb(d, o);
|
||||
@ -18065,7 +18117,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
case 0x49: 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 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break;
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : PRN.to_workbook(d,o);
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
|
||||
case 0xFF: if(n[1] == 0xFE){ return read_utf16(d, o); } break;
|
||||
case 0x00: if(n[1] == 0x00 && n[2] >= 0x02 && n[3] == 0x00) return WK_.to_workbook(d, o); break;
|
||||
case 0x03: case 0x83: case 0x8B: return DBF.to_workbook(d, o);
|
||||
@ -18074,14 +18126,14 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
}
|
||||
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
|
||||
if(0x20>n[0]||n[0]>0x7F) throw new Error("Unsupported file " + n.join("|"));
|
||||
return PRN.to_workbook(d, o);
|
||||
return read_prn(data, d, o, str);
|
||||
}
|
||||
|
||||
function readFileSync(filename/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
var o = opts||{}; o.type = 'file';
|
||||
return readSync(filename, o);
|
||||
}
|
||||
function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
|
||||
var o = opts||{};
|
||||
var z = write_zip(wb, o);
|
||||
var oopts = {};
|
||||
@ -18089,31 +18141,51 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
switch(o.type) {
|
||||
case "base64": oopts.type = "base64"; break;
|
||||
case "binary": oopts.type = "string"; break;
|
||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + ' files');
|
||||
case "buffer":
|
||||
case "file": oopts.type = "nodebuffer"; break;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
if(o.type === "file") return _fs.writeFileSync(o.file, z.generate(oopts));
|
||||
return z.generate(oopts);
|
||||
var out = z.generate(oopts);
|
||||
// $FlowIgnore
|
||||
return o.type == "string" ? utf8read(out) : out;
|
||||
}
|
||||
|
||||
function write_cfb_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
function write_cfb_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
|
||||
var o = opts||{};
|
||||
var cfb/*:CFBContainer*/ = write_xlscfb(wb, o);
|
||||
switch(o.type) {
|
||||
case "base64": case "binary": break;
|
||||
case "buffer": case "array": o.type = ""; break;
|
||||
case "file": return _fs.writeFileSync(o.file, CFB.write(cfb, {type:'buffer'}));
|
||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + ' files');
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
return CFB.write(cfb, o);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_bstr_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/*:any*/ {
|
||||
if(!bom) bom = "";
|
||||
var o = bom + out;
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(utf8write(o));
|
||||
case "binary": return utf8write(o);
|
||||
case "string": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, o, 'utf8');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(o, 'utf8');
|
||||
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ {
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "string": return out; /* override in sheet_to_txt */
|
||||
case "file": return _fs.writeFileSync(opts.file, out, 'binary');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'binary');
|
||||
@ -18124,27 +18196,14 @@ function write_bstr_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_string_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, out, 'utf8');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_binary_type(out, opts/*:WriteOpts*/) {
|
||||
function write_binary_type(out, opts/*:WriteOpts*/)/*:any*/ {
|
||||
switch(opts.type) {
|
||||
case "string":
|
||||
case "base64":
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : bstr;
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : opts.type == 'string' ? utf8read(bstr) : bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
@ -18160,14 +18219,14 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
case 'slk':
|
||||
case 'sylk': return write_string_type(write_slk_str(wb, o), o);
|
||||
case 'html': return write_string_type(write_htm_str(wb, o), o);
|
||||
case 'txt': return write_bstr_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o);
|
||||
case 'txt': return write_stxt_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o, "\ufeff");
|
||||
case 'dif': return write_string_type(write_dif_str(wb, o), o);
|
||||
case 'prn': return write_string_type(write_prn_str(wb, o), o);
|
||||
case 'rtf': return write_string_type(write_rtf_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff3': if(!o.biff) o.biff = 3; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
|
||||
case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
|
||||
case 'biff4': if(!o.biff) o.biff = 4; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff5': if(!o.biff) o.biff = 5; return write_cfb_type(wb, o);
|
||||
case 'biff8':
|
||||
@ -18348,8 +18407,8 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
|
||||
function sheet_to_txt(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
|
||||
if(!opts) opts = {}; opts.FS = "\t"; opts.RS = "\n";
|
||||
var s = sheet_to_csv(sheet, opts);
|
||||
if(typeof cptable == 'undefined') return s;
|
||||
var o = cptable.utils.encode(1200, s);
|
||||
if(typeof cptable == 'undefined' || opts.type == 'string') return s;
|
||||
var o = cptable.utils.encode(1200, s, 'str');
|
||||
return "\xff\xfe" + o;
|
||||
}
|
||||
|
||||
|
230
xlsx.js
230
xlsx.js
@ -6,7 +6,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.11.4';
|
||||
XLSX.version = '0.11.5';
|
||||
var current_codepage = 1200;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -2039,6 +2039,31 @@ var utf8read = function utf8reada(orig) {
|
||||
return out;
|
||||
};
|
||||
|
||||
var utf8write = function(orig) {
|
||||
var out = [], i = 0, c = 0, d = 0;
|
||||
while(i < orig.length) {
|
||||
c = orig.charCodeAt(i++);
|
||||
switch(true) {
|
||||
case c < 128: out.push(String.fromCharCode(c)); break;
|
||||
case c < 2048:
|
||||
out.push(String.fromCharCode(192 + (c >> 6)));
|
||||
out.push(String.fromCharCode(128 + (c & 63)));
|
||||
break;
|
||||
case c >= 55296 && c < 57344:
|
||||
c -= 55296; d = orig.charCodeAt(i++) - 56320 + (c<<10);
|
||||
out.push(String.fromCharCode(240 + ((d >>18) & 7)));
|
||||
out.push(String.fromCharCode(144 + ((d >>12) & 63)));
|
||||
out.push(String.fromCharCode(128 + ((d >> 6) & 63)));
|
||||
out.push(String.fromCharCode(128 + (d & 63)));
|
||||
break;
|
||||
default:
|
||||
out.push(String.fromCharCode(224 + (c >> 12)));
|
||||
out.push(String.fromCharCode(128 + ((c >> 6) & 63)));
|
||||
out.push(String.fromCharCode(128 + (c & 63)));
|
||||
}
|
||||
}
|
||||
return out.join("");
|
||||
};
|
||||
|
||||
if(has_buf) {
|
||||
var utf8readb = function utf8readb(data) {
|
||||
@ -2062,6 +2087,8 @@ if(has_buf) {
|
||||
// $FlowIgnore
|
||||
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
|
||||
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
|
||||
|
||||
utf8write = function(data) { return new Buffer(data, 'utf8').toString("binary"); };
|
||||
}
|
||||
|
||||
// matches <foo>...</foo> extracts content
|
||||
@ -2074,6 +2101,10 @@ var matchtag = (function() {
|
||||
};
|
||||
})();
|
||||
|
||||
function htmldecode(str) {
|
||||
return str.trim().replace(/\s+/g, " ").replace(/<\s*[bB][rR]\s*\/?/g,"\n").replace(/<[^>]*>/g,"").replace(/ /g, " ");
|
||||
}
|
||||
|
||||
var vtregex = (function(){ var vt_cache = {};
|
||||
return function vt_regex(bt) {
|
||||
if(vt_cache[bt] !== undefined) return vt_cache[bt];
|
||||
@ -2169,37 +2200,37 @@ function write_double_le(b, v, idx) {
|
||||
b[idx + 7] = (e >> 4) | bs;
|
||||
}
|
||||
|
||||
var __toBuffer, ___toBuffer;
|
||||
__toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var __utf16le, ___utf16le;
|
||||
__utf16le = ___utf16le = function utf16le_(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var __toBuffer = function(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
|
||||
var ___toBuffer = __toBuffer;
|
||||
var __utf16le = function(b,s,e) { var ss=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join(""); };
|
||||
var ___utf16le = __utf16le;
|
||||
var __hexlify = function(b,s,l) { var ss=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };
|
||||
var ___hexlify = __hexlify;
|
||||
var __utf8, ___utf8;
|
||||
__utf8 = ___utf8 = function(b,s,e) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
|
||||
var __lpstr, ___lpstr;
|
||||
__lpstr = ___lpstr = function lpstr_(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __lpwstr, ___lpwstr;
|
||||
__lpwstr = ___lpwstr = function lpwstr_(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var __utf8 = function(b,s,e) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
|
||||
var ___utf8 = __utf8;
|
||||
var __lpstr = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpstr = __lpstr;
|
||||
var __lpwstr = function(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
|
||||
var ___lpwstr = __lpwstr;
|
||||
var __lpp4, ___lpp4;
|
||||
__lpp4 = ___lpp4 = function lpp4_(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : "";};
|
||||
var __8lpp4, ___8lpp4;
|
||||
__8lpp4 = ___8lpp4 = function lpp4_8(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
|
||||
var __8lpp4 = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
|
||||
var ___8lpp4 = __8lpp4;
|
||||
var __double, ___double;
|
||||
__double = ___double = function(b, idx) { return read_double_le(b, idx);};
|
||||
|
||||
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
|
||||
|
||||
if(has_buf) {
|
||||
__utf16le = function utf16le_b(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__utf16le = function(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); };
|
||||
__hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); };
|
||||
__lpstr = function lpstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b,i) { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
__utf8 = function utf8_b(b, s,e) { return b.toString('utf8',s,e); };
|
||||
__lpstr = function lpstr_b(b, i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
|
||||
__lpwstr = function lpwstr_b(b, i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
|
||||
__lpp4 = function lpp4_b(b, i) { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
|
||||
__8lpp4 = function lpp4_8b(b, i) { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
|
||||
__utf8 = function utf8_b(b, s, e) { return (Buffer.isBuffer(b)) ? b.toString('utf8',s,e) : __utf8(b,s,e); };
|
||||
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
|
||||
bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); };
|
||||
__double = function double_(b,i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
|
||||
__double = function double_(b, i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
|
||||
is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
|
||||
}
|
||||
|
||||
@ -2219,7 +2250,7 @@ var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u
|
||||
var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
|
||||
var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
|
||||
|
||||
var ___unhexlify = function(s) { return s.match(/../g).map(function(x) { return parseInt(x,16);}); };
|
||||
var ___unhexlify = function(s) { return (s.match(/../g)||[]).map(function(x) { return parseInt(x,16);}); };
|
||||
var __unhexlify = typeof Buffer !== "undefined" ? function(s) { return Buffer.isBuffer(s) ? new Buffer(s, 'hex') : ___unhexlify(s); } : ___unhexlify;
|
||||
|
||||
function ReadShift(size, t) {
|
||||
@ -2295,9 +2326,9 @@ function ReadShift(size, t) {
|
||||
this.l+=size; return o;
|
||||
}
|
||||
|
||||
var __writeUInt16LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
|
||||
var __writeUInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };
|
||||
var __writeInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
|
||||
var __writeUInt16LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
|
||||
|
||||
function WriteShift(t, val, f) {
|
||||
var size = 0, i = 0;
|
||||
@ -2312,7 +2343,7 @@ for(i = 0; i != val.length; ++i) this[this.l + i] = val.charCodeAt(i) & 0xFF;
|
||||
this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;
|
||||
} return this;
|
||||
} else if(f === 'utf16le') {
|
||||
var end = this.l + t;
|
||||
var end = this.l + t;
|
||||
for(i = 0; i < Math.min(val.length, t); ++i) {
|
||||
var cc = val.charCodeAt(i);
|
||||
this[this.l++] = cc & 0xff;
|
||||
@ -2335,7 +2366,7 @@ this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;
|
||||
|
||||
function CheckField(hexstr, fld) {
|
||||
var m = __hexlify(this,this.l,hexstr.length>>1);
|
||||
if(m !== hexstr) throw fld + 'Expected ' + hexstr + ' saw ' + m;
|
||||
if(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);
|
||||
this.l += hexstr.length>>1;
|
||||
}
|
||||
|
||||
@ -3628,6 +3659,7 @@ var CORE_PROPS_REGEX = (function() {
|
||||
|
||||
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]);
|
||||
@ -3695,6 +3727,7 @@ RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relatio
|
||||
|
||||
function parse_ext_props(data, p, opts) {
|
||||
var q = {}; if(!p) p = {};
|
||||
data = utf8read(data);
|
||||
|
||||
EXT_PROPS.forEach(function(f) {
|
||||
switch(f[2]) {
|
||||
@ -4133,7 +4166,7 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
case 1252:
|
||||
case 65000: case -536:
|
||||
case 65001: case -535:
|
||||
set_cp(CodePage = PropH[piddsi.n]); break;
|
||||
set_cp(CodePage = PropH[piddsi.n]>>>0 & 0xFFFF); break;
|
||||
default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
|
||||
}
|
||||
} else {
|
||||
@ -4175,6 +4208,7 @@ function parse_PropertySet(blob, PIDSI) {
|
||||
/* [MS-OLEPS] 2.21 PropertySetStream */
|
||||
function parse_PropertySetStream(file, PIDSI) {
|
||||
var blob = file.content;
|
||||
if(!blob) return ({});
|
||||
prep_blob(blob, 0);
|
||||
|
||||
var NumSets, FMTID0, FMTID1, Offset0, Offset1 = 0;
|
||||
@ -5685,7 +5719,7 @@ var SYLK = (function() {
|
||||
|
||||
function sheet_to_sylk(ws, opts) {
|
||||
var preamble = ["ID;PWXL;N;E"], o = [];
|
||||
var r = decode_range(ws['!ref']), cell;
|
||||
var r = safe_decode_range(ws['!ref']), cell;
|
||||
var dense = Array.isArray(ws);
|
||||
var RS = "\r\n";
|
||||
|
||||
@ -5769,7 +5803,7 @@ var DIF = (function() {
|
||||
};
|
||||
return function sheet_to_dif(ws, opts) {
|
||||
var o = [];
|
||||
var r = decode_range(ws['!ref']), cell;
|
||||
var r = safe_decode_range(ws['!ref']), cell;
|
||||
var dense = Array.isArray(ws);
|
||||
push_field(o, "TABLE", 0, 1, "sheetjs");
|
||||
push_field(o, "VECTORS", 0, r.e.r - r.s.r + 1,"");
|
||||
@ -5885,6 +5919,7 @@ var PRN = (function() {
|
||||
if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
|
||||
if(s.length == 0) cell.t = 'z';
|
||||
else if(o.raw) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.trim().length == 0) { cell.t = 's'; cell.v = s; }
|
||||
else if(s.charCodeAt(0) == 0x3D) {
|
||||
if(s.charCodeAt(1) == 0x22 && s.charCodeAt(s.length - 1) == 0x22) { cell.t = 's'; cell.v = s.slice(2,-1).replace(/""/g,'"'); }
|
||||
else if(fuzzyfmla(s)) { cell.t = 'n'; cell.f = s.substr(1); }
|
||||
@ -5930,12 +5965,13 @@ var PRN = (function() {
|
||||
}
|
||||
|
||||
function prn_to_sheet(d, opts) {
|
||||
var str = "", bytes = firstbyte(d, opts);
|
||||
var str = "", bytes = opts.type == 'string' ? [0,0,0,0] : firstbyte(d, opts);
|
||||
switch(opts.type) {
|
||||
case 'base64': str = Base64.decode(d); break;
|
||||
case 'binary': str = d; break;
|
||||
case 'buffer': str = d.toString('binary'); break;
|
||||
case 'array': str = cc2str(d); break;
|
||||
case 'string': str = d; break;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
|
||||
@ -5946,7 +5982,7 @@ var PRN = (function() {
|
||||
|
||||
function sheet_to_prn(ws, opts) {
|
||||
var o = [];
|
||||
var r = decode_range(ws['!ref']), cell;
|
||||
var r = safe_decode_range(ws['!ref']), cell;
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) {
|
||||
var oo = [];
|
||||
@ -9400,7 +9436,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
|
||||
case 'PtgFuncVar': /* 2.5.198.63 */
|
||||
//console.log(f[1]);
|
||||
/* f[1] = [argc, func, type] */
|
||||
var argc = f[1][0], func = f[1][1];
|
||||
var argc = (f[1][0]), func = (f[1][1]);
|
||||
if(!argc) argc = 0;
|
||||
var args = argc == 0 ? [] : stack.slice(-argc);
|
||||
stack.length -= argc;
|
||||
@ -11977,7 +12013,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) {
|
||||
case 's': sstr = strs[val[1]]; p.v = sstr.t; p.r = sstr.r; break;
|
||||
case 'b': p.v = val[1] ? true : false; break;
|
||||
case 'e': p.v = val[1]; if(opts.cellText !== false) p.w = BErr[p.v]; break;
|
||||
case 'str': p.t = 's'; p.v = utf8read(val[1]); break;
|
||||
case 'str': p.t = 's'; p.v = val[1]; break;
|
||||
}
|
||||
if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.numFmtId,null,opts, themes, styles);
|
||||
C = val[0].c;
|
||||
@ -13380,7 +13416,10 @@ function parse_xlml_xml(d, _opts) {
|
||||
var opts = _opts || {};
|
||||
make_ssf(SSF);
|
||||
var str = debom(xlml_normalize(d));
|
||||
if(opts && opts.type == 'binary' && typeof cptable !== 'undefined') str = cptable.utils.decode(65001, char_codes(str));
|
||||
if(opts.type == 'binary' || opts.type == 'base64') {
|
||||
if(typeof cptable !== 'undefined') str = cptable.utils.decode(65001, char_codes(str));
|
||||
else str = utf8read(str);
|
||||
}
|
||||
var opening = str.slice(0, 1024).toLowerCase(), ishtml = false;
|
||||
if(opening.indexOf("<?xml") == -1) ["html", "table", "head", "meta", "script", "style", "div"].forEach(function(tag) { if(opening.indexOf("<" + tag) >= 0) ishtml = true; });
|
||||
if(ishtml) return HTML_.to_workbook(str, opts);
|
||||
@ -14204,12 +14243,6 @@ function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
|
||||
case 's': t = 'String'; p = escapexml(cell.v||""); break;
|
||||
}
|
||||
var _v = (cell.v != null ? p : "");
|
||||
if(opts && opts.type == 'binary' && typeof cptable !== 'undefined' && cell.t == 's') {
|
||||
_v = cptable.utils.encode(65001, _v);
|
||||
var __v = "";
|
||||
for(var __i = 0; __i < _v.length; ++__i) __v += String.fromCharCode(_v[__i]);
|
||||
_v = __v;
|
||||
}
|
||||
var m = '<Data ss:Type="' + t + '">' + _v + '</Data>';
|
||||
|
||||
if((cell.c||[]).length > 0) m += write_ws_xlml_comment(cell.c);
|
||||
@ -14297,8 +14330,7 @@ function write_xlml(wb, opts) {
|
||||
function parse_compobj(obj) {
|
||||
var v = {};
|
||||
var o = obj.content;
|
||||
|
||||
/* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */
|
||||
/* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */
|
||||
var l = 28, m;
|
||||
m = __lpstr(o, l);
|
||||
l += 4 + __readUInt32LE(o,l);
|
||||
@ -15113,14 +15145,20 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
||||
}
|
||||
|
||||
/* TODO: WTF */
|
||||
function parse_props(cfb) {
|
||||
function parse_props(cfb, props, o) {
|
||||
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
|
||||
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
|
||||
if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {/* empty */}
|
||||
if(DSI) try {
|
||||
var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI);
|
||||
for(var d in DocSummary) props[d] = DocSummary[d];
|
||||
} catch(e) {if(o.WTF == 2) throw e;/* empty */}
|
||||
|
||||
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
|
||||
var SI = CFB.find(cfb, '!SummaryInformation');
|
||||
if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {/* empty */}
|
||||
if(SI) try {
|
||||
var Summary = parse_PropertySetStream(SI, SummaryPIDSI);
|
||||
for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
|
||||
} catch(e) {if(o.WTF == 2) throw e;/* empty */}
|
||||
}
|
||||
|
||||
function parse_xlscfb(cfb, options) {
|
||||
@ -15131,7 +15169,7 @@ var CompObj, Summary, WB;
|
||||
if(cfb.FullPaths) {
|
||||
CompObj = CFB.find(cfb, '!CompObj');
|
||||
Summary = CFB.find(cfb, '!SummaryInformation');
|
||||
WB = CFB.find(cfb, '/Workbook');
|
||||
WB = CFB.find(cfb, '/Workbook') || CFB.find(cfb, '/Book');
|
||||
} else {
|
||||
switch(options.type) {
|
||||
case 'base64': cfb = s2a(Base64.decode(cfb)); break;
|
||||
@ -15142,26 +15180,24 @@ if(cfb.FullPaths) {
|
||||
prep_blob(cfb, 0);
|
||||
WB = ({content: cfb});
|
||||
}
|
||||
if(!WB) WB = CFB.find(cfb, '/Book');
|
||||
var CompObjP, SummaryP, WorkbookP;
|
||||
|
||||
var _data;
|
||||
if(CompObj) CompObjP = parse_compobj(CompObj);
|
||||
if(options.bookProps && !options.bookSheets) WorkbookP = ({});
|
||||
else {
|
||||
var T = has_buf ? 'buffer' : 'array';
|
||||
if(WB && WB.content) WorkbookP = parse_workbook(WB.content, options);
|
||||
/* Quattro Pro 7-8 */
|
||||
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
|
||||
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
/* Quattro Pro 9 */
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
|
||||
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
|
||||
else throw new Error("Cannot find Workbook stream");
|
||||
}
|
||||
|
||||
if(cfb.FullPaths) parse_props(cfb);
|
||||
|
||||
var props = {};
|
||||
for(var y in cfb.Summary) props[y] = cfb.Summary[y];
|
||||
for(y in cfb.DocSummary) props[y] = cfb.DocSummary[y];
|
||||
if(cfb.FullPaths) parse_props(cfb, props, options);
|
||||
|
||||
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
|
||||
if(options.bookFiles) WorkbookP.cfb = cfb;
|
||||
/*WorkbookP.CompObjP = CompObjP; // TODO: storage? */
|
||||
@ -16688,7 +16724,7 @@ var HTML_ = (function() {
|
||||
if((RS = +tag.rowspan)>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
|
||||
/* TODO: generate stub cells */
|
||||
if(!m.length) { C += CS; continue; }
|
||||
m = unescapexml(m).replace(/[\r\n]/g,"");
|
||||
m = htmldecode(unescapexml(m));
|
||||
if(range.s.r > R) range.s.r = R;
|
||||
if(range.e.r < R) range.e.r = R;
|
||||
if(range.s.c > C) range.s.c = C;
|
||||
@ -16696,7 +16732,7 @@ var HTML_ = (function() {
|
||||
if(opts.dense) {
|
||||
if(!ws[R]) ws[R] = [];
|
||||
if(!m.length){}
|
||||
else if(opts.raw) ws[R][C] = {t:'s', v:m};
|
||||
else if(opts.raw || !m.trim().length) ws[R][C] = {t:'s', v:m};
|
||||
else if(m === 'TRUE') ws[R][C] = {t:'b', v:true};
|
||||
else if(m === 'FALSE') ws[R][C] = {t:'b', v:false};
|
||||
else if(!isNaN(fuzzynum(m))) ws[R][C] = {t:'n', v:fuzzynum(m)};
|
||||
@ -16706,6 +16742,7 @@ var HTML_ = (function() {
|
||||
/* TODO: value parsing */
|
||||
if(!m.length){}
|
||||
else if(opts.raw) ws[coord] = {t:'s', v:m};
|
||||
else if(opts.raw || !m.trim().length) ws[coord] = {t:'s', v:m};
|
||||
else if(m === 'TRUE') ws[coord] = {t:'b', v:true};
|
||||
else if(m === 'FALSE') ws[coord] = {t:'b', v:false};
|
||||
else if(!isNaN(fuzzynum(m))) ws[coord] = {t:'n', v:fuzzynum(m)};
|
||||
@ -16790,7 +16827,7 @@ function parse_dom_table(table, _opts) {
|
||||
var row = rows[R];
|
||||
var elts = row.children;
|
||||
for(_C = C = 0; _C < elts.length; ++_C) {
|
||||
var elt = elts[_C], v = elts[_C].innerText || elts[_C].textContent || "";
|
||||
var elt = elts[_C], v = htmldecode(elts[_C].innerHTML);
|
||||
for(midx = 0; midx < merges.length; ++midx) {
|
||||
var m = merges[midx];
|
||||
if(m.s.c == C && m.s.r <= R && R <= m.e.r) { C = m.e.c+1; midx = -1; }
|
||||
@ -16802,6 +16839,7 @@ function parse_dom_table(table, _opts) {
|
||||
if(v != null) {
|
||||
if(v.length == 0) o.t = 'z';
|
||||
else if(opts.raw){}
|
||||
else if(v.trim().length == 0) o.t = 's';
|
||||
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)};
|
||||
@ -17291,7 +17329,9 @@ function parse_ods(zip, opts) {
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
var content = getzipstr(zip, 'content.xml');
|
||||
if(!content) throw new Error("Missing content.xml in " + (ods ? "ODS" : "UOF")+ " file");
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
var wb = parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
if(safegetzipfile(zip, 'meta.xml')) wb.Props = parse_core_props(getzipdata(zip, 'meta.xml'));
|
||||
return wb;
|
||||
}
|
||||
function parse_fods(data, opts) {
|
||||
return parse_content_xml(data, opts);
|
||||
@ -17558,8 +17598,7 @@ function get_sheet_type(n) {
|
||||
if(RELS.CS && n == RELS.CS) return "chart";
|
||||
if(RELS.DS && n == RELS.DS) return "dialog";
|
||||
if(RELS.MS && n == RELS.MS) return "macro";
|
||||
if(!n || !n.length) return "sheet";
|
||||
return n;
|
||||
return (n && n.length) ? n : "sheet";
|
||||
}
|
||||
function safe_parse_wbrels(wbrels, sheets) {
|
||||
if(!wbrels) return 0;
|
||||
@ -17643,10 +17682,10 @@ function parse_zip(zip, opts) {
|
||||
var props = {}, propdata = "";
|
||||
|
||||
if(dir.coreprops.length) {
|
||||
propdata = getzipstr(zip, strip_front_slash(dir.coreprops[0]), true);
|
||||
propdata = getzipdata(zip, strip_front_slash(dir.coreprops[0]), true);
|
||||
if(propdata) props = parse_core_props(propdata);
|
||||
if(dir.extprops.length !== 0) {
|
||||
propdata = getzipstr(zip, strip_front_slash(dir.extprops[0]), true);
|
||||
propdata = getzipdata(zip, strip_front_slash(dir.extprops[0]), true);
|
||||
if(propdata) parse_ext_props(propdata, props, opts);
|
||||
}
|
||||
}
|
||||
@ -17952,13 +17991,23 @@ function read_utf16(data, o) {
|
||||
return read_plaintext(d, o);
|
||||
}
|
||||
|
||||
function bstrify(data) {
|
||||
return !data.match(/[^\x00-\x7F]/) ? data : utf8write(data);
|
||||
}
|
||||
|
||||
function read_prn(data, d, o, str) {
|
||||
if(str) { o.type = "string"; return PRN.to_workbook(data, o); }
|
||||
return PRN.to_workbook(d, o);
|
||||
}
|
||||
|
||||
function readSync(data, opts) {
|
||||
var zip, d = data, n=[0];
|
||||
var zip, d = data, n=[0], str = false;
|
||||
var o = opts||{};
|
||||
_ssfopts = {};
|
||||
if(o.dateNF) _ssfopts.dateNF = o.dateNF;
|
||||
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
|
||||
if(o.type == "file") { o.type = "buffer"; d = _fs.readFileSync(data); }
|
||||
if(o.type == "string") { str = true; o.type = "binary"; d = bstrify(data); }
|
||||
switch((n = firstbyte(d, o))[0]) {
|
||||
case 0xD0: return read_cfb(CFB.read(d, o), o);
|
||||
case 0x09: return parse_xlscfb(d, o);
|
||||
@ -17966,7 +18015,7 @@ function readSync(data, opts) {
|
||||
case 0x49: 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 0x50: if(n[1] == 0x4B && n[2] < 0x20 && n[3] < 0x20) return read_zip(d, o); break;
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : PRN.to_workbook(d,o);
|
||||
case 0xEF: return n[3] == 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
|
||||
case 0xFF: if(n[1] == 0xFE){ return read_utf16(d, o); } break;
|
||||
case 0x00: if(n[1] == 0x00 && n[2] >= 0x02 && n[3] == 0x00) return WK_.to_workbook(d, o); break;
|
||||
case 0x03: case 0x83: case 0x8B: return DBF.to_workbook(d, o);
|
||||
@ -17975,7 +18024,7 @@ function readSync(data, opts) {
|
||||
}
|
||||
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
|
||||
if(0x20>n[0]||n[0]>0x7F) throw new Error("Unsupported file " + n.join("|"));
|
||||
return PRN.to_workbook(d, o);
|
||||
return read_prn(data, d, o, str);
|
||||
}
|
||||
|
||||
function readFileSync(filename, opts) {
|
||||
@ -17990,12 +18039,15 @@ function write_zip_type(wb, opts) {
|
||||
switch(o.type) {
|
||||
case "base64": oopts.type = "base64"; break;
|
||||
case "binary": oopts.type = "string"; break;
|
||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + ' files');
|
||||
case "buffer":
|
||||
case "file": oopts.type = "nodebuffer"; break;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
if(o.type === "file") return _fs.writeFileSync(o.file, z.generate(oopts));
|
||||
return z.generate(oopts);
|
||||
var out = z.generate(oopts);
|
||||
// $FlowIgnore
|
||||
return o.type == "string" ? utf8read(out) : out;
|
||||
}
|
||||
|
||||
function write_cfb_type(wb, opts) {
|
||||
@ -18005,16 +18057,33 @@ function write_cfb_type(wb, opts) {
|
||||
case "base64": case "binary": break;
|
||||
case "buffer": case "array": o.type = ""; break;
|
||||
case "file": return _fs.writeFileSync(o.file, CFB.write(cfb, {type:'buffer'}));
|
||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + ' files');
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
return CFB.write(cfb, o);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_bstr_type(out, opts) {
|
||||
function write_string_type(out, opts, bom) {
|
||||
if(!bom) bom = "";
|
||||
var o = bom + out;
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(utf8write(o));
|
||||
case "binary": return utf8write(o);
|
||||
case "string": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, o, 'utf8');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(o, 'utf8');
|
||||
else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
function write_stxt_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "string": return out; /* override in sheet_to_txt */
|
||||
case "file": return _fs.writeFileSync(opts.file, out, 'binary');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'binary');
|
||||
@ -18024,28 +18093,15 @@ function write_bstr_type(out, opts) {
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_string_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, out, 'utf8');
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_binary_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "string":
|
||||
case "base64":
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : bstr;
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : opts.type == 'string' ? utf8read(bstr) : bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
@ -18061,14 +18117,14 @@ function writeSync(wb, opts) {
|
||||
case 'slk':
|
||||
case 'sylk': return write_string_type(write_slk_str(wb, o), o);
|
||||
case 'html': return write_string_type(write_htm_str(wb, o), o);
|
||||
case 'txt': return write_bstr_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o);
|
||||
case 'txt': return write_stxt_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o, "\ufeff");
|
||||
case 'dif': return write_string_type(write_dif_str(wb, o), o);
|
||||
case 'prn': return write_string_type(write_prn_str(wb, o), o);
|
||||
case 'rtf': return write_string_type(write_rtf_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff3': if(!o.biff) o.biff = 3; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
|
||||
case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
|
||||
case 'biff4': if(!o.biff) o.biff = 4; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff5': if(!o.biff) o.biff = 5; return write_cfb_type(wb, o);
|
||||
case 'biff8':
|
||||
@ -18249,8 +18305,8 @@ function sheet_to_csv(sheet, opts) {
|
||||
function sheet_to_txt(sheet, opts) {
|
||||
if(!opts) opts = {}; opts.FS = "\t"; opts.RS = "\n";
|
||||
var s = sheet_to_csv(sheet, opts);
|
||||
if(typeof cptable == 'undefined') return s;
|
||||
var o = cptable.utils.encode(1200, s);
|
||||
if(typeof cptable == 'undefined' || opts.type == 'string') return s;
|
||||
var o = cptable.utils.encode(1200, s, 'str');
|
||||
return "\xff\xfe" + o;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*:: declare var XLSX: XLSXModule; */
|
||||
/*:: declare var self: DedicatedWorkerGlobalScope; */
|
||||
importScripts('shim.js');
|
||||
/* uncomment the next line for encoding support */
|
||||
importScripts('dist/cpexcel.js');
|
||||
importScripts('jszip.js');
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
importScripts('shim.js');
|
||||
/* uncomment the next line for encoding support */
|
||||
importScripts('dist/cpexcel.js');
|
||||
importScripts('jszip.js');
|
||||
|
Loading…
Reference in New Issue
Block a user