version bump 0.11.1: dist cleanup

- dist scripts properly export library
- XLS/XLSB formulae quote sheet names containing spaces
- skipHidden ported to streaming CSV write
- updated codepage to 1.11.0
- flow and TS updates
- webpack demo example using dist scripts
- requirejs demo
This commit is contained in:
SheetJS 2017-08-05 02:32:57 -04:00
parent 0f39f2818f
commit 935821423f
59 changed files with 1466 additions and 964 deletions

View File

@ -1,5 +1,6 @@
bits/
demos/
dist/
docbits/
misc/
node_modules/

View File

@ -50,17 +50,17 @@ init: ## Initial setup for development
git submodule foreach make
mkdir -p tmp
DISTHDR=misc/suppress_export.js
.PHONY: dist
dist: dist-deps $(TARGET) bower.json ## Prepare JS files for distribution
<$(TARGET) sed "s/require('stream')/{}/g;s/require('.*')/null/g" > dist/$(TARGET)
<$(TARGET) sed "s/require('stream')/{}/g;s/require('....*')/undefined/g" > dist/$(TARGET)
cp LICENSE dist/
uglifyjs dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(DISTHDR) dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/$(LIB).min.js
uglifyjs $(REQS) dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).core.min.js --source-map dist/$(LIB).core.min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(DISTHDR) $(REQS) dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).core.min.js --source-map dist/$(LIB).core.min.map --preamble "$$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/$(LIB).core.min.js
uglifyjs $(REQS) $(ADDONS) dist/$(TARGET) $(AUXTARGETS) $(UGLIFYOPTS) -o dist/$(LIB).full.min.js --source-map dist/$(LIB).full.min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(DISTHDR) $(REQS) $(ADDONS) dist/$(TARGET) $(AUXTARGETS) $(UGLIFYOPTS) -o dist/$(LIB).full.min.js --source-map dist/$(LIB).full.min.map --preamble "$$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/$(LIB).full.min.js
cat <(head -n 1 bits/00_header.js) $(REQS) $(ADDONS) $(TARGET) $(AUXTARGETS) > demos/requirejs/$(LIB).full.js
.PHONY: dist-deps
dist-deps: ## Copy dependencies for distribution

View File

@ -1 +1 @@
XLSX.version = '0.11.0';
XLSX.version = '0.11.1';

View File

@ -33,7 +33,7 @@ var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
var dnthresh = basedate.getTime() + (new Date().getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
var epoch = v.getTime();
if(date1904) epoch += 1462*24*60*60*1000;
if(date1904) epoch -= 1462*24*60*60*1000;
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
}
function numdate(v/*:number*/)/*:Date*/ {

View File

@ -58,7 +58,7 @@ if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(typeof jszip === 'undefined') jszip = require('./jszip.js');
_fs = require('fs');
try { _fs = require('fs'); } catch(e) { }
}
}

View File

@ -28,8 +28,8 @@ function parse_VtStringBase(blob, stringType, pad) {
return parse_lpstr(blob, stringType, pad);
}
function parse_VtString(blob, t/*:number*/, pad/*:number*/) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); }
function parse_VtUnalignedString(blob, t/*:number*/) { if(!t) throw new Error("dafuq?"); return parse_VtStringBase(blob, t, 0); }
function parse_VtString(blob, t/*:number*/, pad/*:?boolean*/) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); }
function parse_VtUnalignedString(blob, t/*:number*/) { if(!t) throw new Error("VtUnalignedString must have positive length"); return parse_VtStringBase(blob, t, 0); }
/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
function parse_VtVecUnalignedLpstrValue(blob) {
@ -123,7 +123,7 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts) {
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw && 4).replace(chr0,'');
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw).replace(chr0,'');
case 0x51 /*VT_USTR*/: return parse_VtUnalignedString(blob, t/*, 4*/).replace(chr0,'');
case 0x100C /*VT_VECTOR|VT_VARIANT*/: return parse_VtVecHeadingPair(blob);
case 0x101E /*VT_LPSTR*/: return parse_VtVecUnalignedLpstr(blob);

View File

@ -294,7 +294,7 @@ function parse_FilePassHeader(blob, length/*:number*/, oo) {
return o;
}
function parse_FilePass(blob, length/*:number*/, opts) {
var o = { Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }; /* wEncryptionType */
var o = ({ Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }/*:any*/); /* wEncryptionType */
if(o.Type) parse_FilePassHeader(blob, length-2, o);
else parse_XORObfuscation(blob, length-2, opts, o);
return o;

24
bits/45_rtf.js Normal file
View File

@ -0,0 +1,24 @@
var RTF = (function() {
function rtf_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
switch(opts.type) {
case 'base64': return rtf_to_sheet_str(Base64.decode(d), opts);
case 'binary': return rtf_to_sheet_str(d, opts);
case 'buffer': return rtf_to_sheet_str(d.toString('binary'), opts);
case 'array': return rtf_to_sheet_str(cc2str(d), opts);
}
throw new Error("Unrecognized type " + opts.type);
}
function rtf_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
throw new Error("Unsupported RTF");
}
function rtf_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(rtf_to_sheet(d, opts), opts); }
function sheet_to_rtf() { throw new Error("Unsupported"); }
return {
to_workbook: rtf_to_workbook,
to_sheet: rtf_to_sheet,
from_sheet: sheet_to_rtf
};
})();

View File

@ -75,8 +75,9 @@ function parse_fills(t, styles, themes, opts) {
case '<fills': case '<fills>': case '</fills>': break;
/* 18.8.20 fill CT_Fill */
case '<fill>': case '<fill': break;
case '</fill>': styles.Fills.push(fill); fill = {}; break;
case '<fill>': case '<fill': case '<fill/>':
fill = {}; styles.Fills.push(fill); break;
case '</fill>': break;
/* 18.8.24 gradientFill CT_GradientFill */
case '<gradientFill>': break;

View File

@ -102,6 +102,7 @@ var XLSBFillPTNames = [
];
var rev_XLSBFillPTNames/*:EvertNumType*/ = (evert(XLSBFillPTNames)/*:any*/);
/* TODO: gradient fill representation */
var parse_BrtFill = parsenoop;
function write_BrtFill(fill, o) {
if(!o) o = new_buf(4*3 + 8*7 + 16*1);
var fls/*:number*/ = rev_XLSBFillPTNames[fill.patternType];
@ -164,6 +165,7 @@ function write_Blxf(data, o) {
return o;
}
/* [MS-XLSB] 2.4.299 BrtBorder TODO */
var parse_BrtBorder = parsenoop;
function write_BrtBorder(border, o) {
if(!o) o = new_buf(51);
o.write_shift(1, 0); /* diagonal */

View File

@ -690,9 +690,17 @@ var PtgBinOp = {
PtgPower: "^",
PtgSub: "-"
};
function get_ixti(supbooks, ixti/*:number*/, opts)/*:string*/ {
function formula_quote_sheet_name(sname/*:string*/)/*:string*/ {
if(!sname) return "";
if(sname.indexOf(" ") > -1) return "'" + sname + "'";
return sname;
}
function get_ixti_raw(supbooks, ixti/*:number*/, opts)/*:string*/ {
return supbooks.SheetNames[ixti];
}
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) {
//console.log(formula);
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};

View File

@ -60,7 +60,7 @@ function get_cell_style(styles, cell, opts) {
return len;
}
function safe_format(p, fmtid/*:number*/, fillid/*:number*/, opts, themes, styles) {
function safe_format(p, fmtid/*:number*/, fillid/*:?number*/, opts, themes, styles) {
if(p.t === 'z') return;
if(p.t === 'd' && typeof p.v === 'string') p.v = parseDate(p.v);
try {
@ -84,7 +84,8 @@ function safe_format(p, fmtid/*:number*/, fillid/*:number*/, opts, themes, style
else if(p.t === 'd') p.w = SSF.format(fmtid,datenum(p.v),_ssfopts);
else p.w = SSF.format(fmtid,p.v,_ssfopts);
} catch(e) { if(opts.WTF) throw e; }
if(fillid) try {
if(!opts.cellStyles) return;
if(fillid != null) try {
p.s = styles.Fills[fillid];
if (p.s.fgColor && p.s.fgColor.theme && !p.s.fgColor.rgb) {
p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
@ -94,5 +95,5 @@ function safe_format(p, fmtid/*:number*/, fillid/*:number*/, opts, themes, style
p.s.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.bgColor.theme].rgb, p.s.bgColor.tint || 0);
if(opts.WTF) p.s.bgColor.raw_rgb = themes.themeElements.clrScheme[p.s.bgColor.theme].rgb;
}
} catch(e) { if(opts.WTF) throw e; }
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
}

View File

@ -817,12 +817,14 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
return out;
}
function parse_xlml(data/*:RawBytes*/, opts)/*:Workbook*/ {
function arr2str(data/*:any*/)/*:string*/ { return data.map(_chr).join(""); }
function parse_xlml(data/*:RawBytes|string*/, opts)/*:Workbook*/ {
fix_read_opts(opts=opts||{});
switch(opts.type||"base64") {
case "base64": return parse_xlml_xml(Base64.decode(data), opts);
case "binary": case "buffer": case "file": return parse_xlml_xml(data, opts);
case "array": return parse_xlml_xml(data.map(_chr).join(""), opts);
case "array": return parse_xlml_xml(arr2str(data), opts);
}
/*:: throw new Error("unsupported type " + opts.type); */
}

View File

@ -38,8 +38,8 @@ var XLSBRecordEnum = {
/*::[*/0x002A/*::]*/: { n:"BrtIndexBlock", f:parsenoop },
/*::[*/0x002B/*::]*/: { n:"BrtFont", f:parse_BrtFont },
/*::[*/0x002C/*::]*/: { n:"BrtFmt", f:parse_BrtFmt },
/*::[*/0x002D/*::]*/: { n:"BrtFill", f:parsenoop },
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parsenoop },
/*::[*/0x002D/*::]*/: { n:"BrtFill", f:parse_BrtFill },
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parse_BrtBorder },
/*::[*/0x002F/*::]*/: { n:"BrtXF", f:parse_BrtXF },
/*::[*/0x0030/*::]*/: { n:"BrtStyle", f:parsenoop },
/*::[*/0x0031/*::]*/: { n:"BrtCellMeta", f:parsenoop },

View File

@ -4,10 +4,10 @@ var HTML_ = (function() {
var opts = _opts || {};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
var ws/*:Worksheet*/ = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
var mtch = str.match(/<table/i);
var mtch/*:any*/ = str.match(/<table/i);
if(!mtch) throw new Error("Invalid HTML: could not find <table>");
var mtch2 = str.match(/<\/table/i);
var i = mtch.index, j = mtch2 && mtch2.index || str.length;
var mtch2/*:any*/ = str.match(/<\/table/i);
var i/*:number*/ = mtch.index, j/*:number*/ = mtch2 && mtch2.index || str.length;
var rows = str.slice(i, j).split(/(:?<tr[^>]*>)/i);
var R = -1, C = 0, RS = 0, CS = 0;
var range = {s:{r:10000000, c:10000000},e:{r:0,c:0}};

View File

@ -13,4 +13,5 @@ var write_csv_str = write_obj_str({from_sheet:sheet_to_csv});
var write_slk_str = write_obj_str(SYLK);
var write_dif_str = write_obj_str(DIF);
var write_prn_str = write_obj_str(PRN);
var write_rtf_str = write_obj_str(RTF);
var write_txt_str = write_obj_str({from_sheet:sheet_to_txt});

View File

@ -78,7 +78,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
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);
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) throw new Error("Unsupported RTF"); break;
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) return RTF.to_workbook(d, o); break;
case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
}
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);

View File

@ -69,6 +69,7 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
case 'csv': return write_string_type(write_csv_str(wb, o), o);
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': return write_binary_type(write_biff_buf(wb, o), o);
case 'xlsx':
@ -95,6 +96,7 @@ function resolve_book_type(o/*?WriteFileOpts*/) {
case '.txt': o.bookType = 'txt'; break;
case '.dif': o.bookType = 'dif'; break;
case '.prn': o.bookType = 'prn'; break;
case '.rtf': o.bookType = 'rtf'; break;
case '.slk': o.bookType = 'sylk'; break;
case '.htm': o.bookType = 'html'; break;
}

View File

@ -112,11 +112,11 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row = "", cols = [];
o.dense = Array.isArray(sheet);
var colInfos = o.skipHidden ? sheet["!cols"] : undefined;
var rowInfos = o.skipHidden ? sheet["!rows"] : undefined;
for(var C = r.s.c; C <= r.e.c; ++C) if (!colInfos || !colInfos[C] || !colInfos[C].hidden) cols[C] = encode_col(C);
var colInfos = o.skipHidden && sheet["!cols"] || [];
var rowInfos = o.skipHidden && sheet["!rows"] || [];
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
for(var R = r.s.r; R <= r.e.r; ++R) {
if (rowInfos && rowInfos[R] && rowInfos[R].hidden) continue;
if ((rowInfos[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
if(row == null) { continue; }
if(o.strip) row = row.replace(endregex,"");

View File

@ -12,13 +12,16 @@ if(has_buf && typeof require != 'undefined') (function() {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row/*:?string*/ = "", cols = [];
o.dense = Array.isArray(sheet);
for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
var colInfos = o.skipHidden && sheet["!cols"] || [];
var rowInfos = o.skipHidden && sheet["!rows"] || [];
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
var R = r.s.r;
stream._read = function() {
if(R > r.e.r) return stream.push(null);
while(R <= r.e.r) {
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
++R;
if ((rowInfos[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
if(row != null) {
if(o.strip) row = row.replace(endregex,"");
stream.push(row + RS);

View File

@ -6,4 +6,5 @@ all: $(TOOL).js
$(TOOL).js:
if [ ! -e require.js ]; then curl -O http://requirejs.org/docs/release/2.3.3/comments/require.js; fi
if [ ! -e r.js ]; then curl -O http://requirejs.org/docs/release/2.3.3/r.js; fi
rm -f xlsx.full.min.js; ln -s ../../dist/xlsx.full.min.js
node r.js -o build.js

11
demos/requirejs/README.md Normal file
View File

@ -0,0 +1,11 @@
# RequireJS
The minified dist files trip up the RequireJS mechanism. To bypass, the scripts
automatically expose an `XLSX` variable that can be used if the require callback
argument is `_XLSX` rather than `XLSX`:
```js
require(["xlsx.full.min"], function(_XLSX) { /* ... */ });
```
This demo uses the `r.js` optimizer to build a source file.

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<!-- xlsx.js (C) 2013-present SheetJS http://sheetjs.com -->
<!-- vim: set ts=2: -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JS-XLSX Live Demo</title>
<style>
#drop{
border:2px dashed #bbb;
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
padding:25px;
text-align:center;
font:20pt bold,"Vollkorn";color:#bbb
}
#b64data{
width:100%;
}
</style>
</head>
<body>
<b>JS-XLSX Live Demo</b><br />
Output Format:
<select name="format">
<option value="csv" selected> CSV</option>
<option value="json"> JSON</option>
<option value="form"> FORMULAE</option>
</select><br />
<div id="drop">Drop a spreadsheet file here to see sheet data</div>
<p><input type="file" name="xlfile" id="xlf" /> ... or click here to select a file</p>
<textarea id="b64data">... or paste a base64-encoding here</textarea>
<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
Advanced Demo Options: <br />
Use Web Workers: (when available) <input type="checkbox" name="useworker" checked><br />
Use Transferrables: (when available) <input type="checkbox" name="xferable" checked><br />
Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" checked><br />
<pre id="out"></pre>
<br />
<script src="require.js"></script>
<script>
var XW = {
/* worker message */
msg: 'xlsx',
/* worker scripts */
rABS: './xlsxworker2.js',
norABS: './xlsxworker1.js',
noxfer: './xlsxworker.js'
};
</script>
<script src="requirejs-built.js"></script>
</body>
</html>

View File

@ -1,4 +1,4 @@
require(["xlsx.full"], function(_XLSX) {
require(["xlsx.full.min"], function(_XLSX) {
var X = XLSX;
var rABS = typeof FileReader !== "undefined" && typeof FileReader.prototype !== "undefined" && typeof FileReader.prototype.readAsBinaryString !== "undefined";

View File

@ -1,2 +1,3 @@
webpack.js
webpack.min.js
*.out.js

View File

@ -1,10 +1,15 @@
TOOL=webpack
WPOPTS=--display-modules --display-reasons --profile
.PHONY: all
all: $(TOOL).min.js
all: $(TOOL).min.js core.out.js full.out.js
$(TOOL).min.js: $(TOOL).js
uglifyjs $< > $@
.PHONY: $(TOOL).js
$(TOOL).js:
webpack main.js --output-filename $@ --display-modules --profile
webpack main.js --output-filename $@ $(WPOPTS)
.PHONY: core.out.js full.out.js
core.out.js full.out.js: %.out.js: %.js
webpack $< --output-filename $@ $(WPOPTS)

View File

@ -40,3 +40,16 @@ the module can be omitted by aliasing the dependency:
alias: { "./dist/cpexcel.js": "" }
},
```
## Bower and minified versions
The minified versions, used in Bower, require `module.noParse` configuration:
```js
module: {
noParse: [
/xlsx.core.min.js/,
/xlsx.full.min.js/
]
}
```

227
demos/webpack/app.js Normal file
View File

@ -0,0 +1,227 @@
/*jshint browser:true */
/*global XLSX */
var X = XLSX;
var rABS = typeof FileReader !== "undefined" && typeof FileReader.prototype !== "undefined" && typeof FileReader.prototype.readAsBinaryString !== "undefined";
if(!rABS) {
document.getElementsByName("userabs")[0].disabled = true;
document.getElementsByName("userabs")[0].checked = false;
}
var use_worker = typeof Worker !== 'undefined';
if(!use_worker) {
document.getElementsByName("useworker")[0].disabled = true;
document.getElementsByName("useworker")[0].checked = false;
}
var transferable = use_worker;
if(!transferable) {
document.getElementsByName("xferable")[0].disabled = true;
document.getElementsByName("xferable")[0].checked = false;
}
var wtf_mode = false;
function fixdata(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
function ab2str(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint16Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint16Array(data.slice(l*w)));
return o;
}
function s2ab(s) {
var b = new ArrayBuffer(s.length*2), v = new Uint16Array(b);
for (var i=0; i != s.length; ++i) v[i] = s.charCodeAt(i);
return [v, b];
}
function xw_noxfer(data, cb) {
var worker = new Worker(XW.noxfer);
worker.onmessage = function(e) {
switch(e.data.t) {
case 'ready': break;
case 'e': console.error(e.data.d); break;
case XW.msg: cb(JSON.parse(e.data.d)); break;
}
};
var arr = rABS ? data : btoa(fixdata(data));
worker.postMessage({d:arr,b:rABS});
}
function xw_xfer(data, cb) {
var worker = new Worker(rABS ? XW.rABS : XW.norABS);
worker.onmessage = function(e) {
switch(e.data.t) {
case 'ready': break;
case 'e': console.error(e.data.d); break;
default: xx=ab2str(e.data).replace(/\n/g,"\\n").replace(/\r/g,"\\r"); console.log("done"); cb(JSON.parse(xx)); break;
}
};
if(rABS) {
var val = s2ab(data);
worker.postMessage(val[1], [val[1]]);
} else {
worker.postMessage(data, [data]);
}
}
function xw(data, cb) {
transferable = document.getElementsByName("xferable")[0].checked;
if(transferable) xw_xfer(data, cb);
else xw_noxfer(data, cb);
}
function get_radio_value( radioName ) {
var radios = document.getElementsByName( radioName );
for( var i = 0; i < radios.length; i++ ) {
if( radios[i].checked || radios.length === 1 ) {
return radios[i].value;
}
}
}
function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
if(roa.length > 0){
result[sheetName] = roa;
}
});
return result;
}
function to_csv(workbook) {
var result = [];
workbook.SheetNames.forEach(function(sheetName) {
var csv = X.utils.sheet_to_csv(workbook.Sheets[sheetName]);
if(csv.length > 0){
result.push("SHEET: " + sheetName);
result.push("");
result.push(csv);
}
});
return result.join("\n");
}
function to_formulae(workbook) {
var result = [];
workbook.SheetNames.forEach(function(sheetName) {
var formulae = X.utils.get_formulae(workbook.Sheets[sheetName]);
if(formulae.length > 0){
result.push("SHEET: " + sheetName);
result.push("");
result.push(formulae.join("\n"));
}
});
return result.join("\n");
}
var tarea = document.getElementById('b64data');
function b64it() {
if(typeof console !== 'undefined') console.log("onload", new Date());
var wb = X.read(tarea.value, {type: 'base64',WTF:wtf_mode});
process_wb(wb);
}
function process_wb(wb) {
var output = "";
switch(get_radio_value("format")) {
case "json":
output = JSON.stringify(to_json(wb), 2, 2);
break;
case "form":
output = to_formulae(wb);
break;
default:
output = to_csv(wb);
}
if(out.innerText === undefined) out.textContent = output;
else out.innerText = output;
if(typeof console !== 'undefined') console.log("output", new Date());
}
var drop = document.getElementById('drop');
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
rABS = document.getElementsByName("userabs")[0].checked;
use_worker = document.getElementsByName("useworker")[0].checked;
var files = e.dataTransfer.files;
var f = files[0];
{
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
var data = e.target.result;
if(use_worker) {
xw(data, process_wb);
} else {
var wb;
if(rABS) {
wb = X.read(data, {type: 'binary'});
} else {
var arr = fixdata(data);
wb = X.read(btoa(arr), {type: 'base64'});
}
process_wb(wb);
}
};
if(rABS) reader.readAsBinaryString(f);
else reader.readAsArrayBuffer(f);
}
}
function handleDragover(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
}
if(drop.addEventListener) {
drop.addEventListener('dragenter', handleDragover, false);
drop.addEventListener('dragover', handleDragover, false);
drop.addEventListener('drop', handleDrop, false);
}
var xlf = document.getElementById('xlf');
function handleFile(e) {
rABS = document.getElementsByName("userabs")[0].checked;
use_worker = document.getElementsByName("useworker")[0].checked;
var files = e.target.files;
var f = files[0];
{
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
var data = e.target.result;
if(use_worker) {
xw(data, process_wb);
} else {
var wb;
if(rABS) {
wb = X.read(data, {type: 'binary'});
} else {
var arr = fixdata(data);
wb = X.read(btoa(arr), {type: 'base64'});
}
process_wb(wb);
}
};
if(rABS) reader.readAsBinaryString(f);
else reader.readAsArrayBuffer(f);
}
}
if(xlf.addEventListener) xlf.addEventListener('change', handleFile, false);

3
demos/webpack/core.js Normal file
View File

@ -0,0 +1,3 @@
var XLSX = require('./xlsx.core.min');
console.log("it works!");
module.exports = XLSX;

View File

@ -0,0 +1,11 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
importScripts('core.out.js');
postMessage({t:"ready"});
onmessage = function (oEvent) {
var v;
try {
v = XLSX.read(oEvent.data.d, {type: oEvent.data.b ? 'binary' : 'base64'});
} catch(e) { postMessage({t:"e",d:e.stack||e}); }
postMessage({t:"xlsx", d:JSON.stringify(v)});
};

View File

@ -0,0 +1,26 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
importScripts('core.out.js');
postMessage({t:"ready"});
function ab2str(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
function s2ab(s) {
var b = new ArrayBuffer(s.length*2), v = new Uint16Array(b);
for (var i=0; i != s.length; ++i) v[i] = s.charCodeAt(i);
return [v, b];
}
onmessage = function (oEvent) {
var v;
try {
v = XLSX.read(ab2str(oEvent.data), {type: 'binary'});
} catch(e) { postMessage({t:"e",d:e.stack}); }
var res = {t:"xlsx", d:JSON.stringify(v)};
var r = s2ab(res.d)[1];
postMessage(r, [r]);
};

View File

@ -0,0 +1,26 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
importScripts('core.out.js');
postMessage({t:"ready"});
function ab2str(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint16Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint16Array(data.slice(l*w)));
return o;
}
function s2ab(s) {
var b = new ArrayBuffer(s.length*2), v = new Uint16Array(b);
for (var i=0; i != s.length; ++i) v[i] = s.charCodeAt(i);
return [v, b];
}
onmessage = function (oEvent) {
var v;
try {
v = XLSX.read(ab2str(oEvent.data), {type: 'binary'});
} catch(e) { postMessage({t:"e",d:e.stack}); }
var res = {t:"xlsx", d:JSON.stringify(v)};
var r = s2ab(res.d)[1];
postMessage(r, [r]);
};

3
demos/webpack/full.js Normal file
View File

@ -0,0 +1,3 @@
var XLSX = require('./xlsx.full.min');
console.log("it works!");
module.exports = XLSX;

View File

@ -0,0 +1,11 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
importScripts('full.out.js');
postMessage({t:"ready"});
onmessage = function (oEvent) {
var v;
try {
v = XLSX.read(oEvent.data.d, {type: oEvent.data.b ? 'binary' : 'base64'});
} catch(e) { postMessage({t:"e",d:e.stack||e}); }
postMessage({t:"xlsx", d:JSON.stringify(v)});
};

View File

@ -0,0 +1,26 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
importScripts('full.out.js');
postMessage({t:"ready"});
function ab2str(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
function s2ab(s) {
var b = new ArrayBuffer(s.length*2), v = new Uint16Array(b);
for (var i=0; i != s.length; ++i) v[i] = s.charCodeAt(i);
return [v, b];
}
onmessage = function (oEvent) {
var v;
try {
v = XLSX.read(ab2str(oEvent.data), {type: 'binary'});
} catch(e) { postMessage({t:"e",d:e.stack}); }
var res = {t:"xlsx", d:JSON.stringify(v)};
var r = s2ab(res.d)[1];
postMessage(r, [r]);
};

View File

@ -0,0 +1,26 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
importScripts('full.out.js');
postMessage({t:"ready"});
function ab2str(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint16Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint16Array(data.slice(l*w)));
return o;
}
function s2ab(s) {
var b = new ArrayBuffer(s.length*2), v = new Uint16Array(b);
for (var i=0; i != s.length; ++i) v[i] = s.charCodeAt(i);
return [v, b];
}
onmessage = function (oEvent) {
var v;
try {
v = XLSX.read(ab2str(oEvent.data), {type: 'binary'});
} catch(e) { postMessage({t:"e",d:e.stack}); }
var res = {t:"xlsx", d:JSON.stringify(v)};
var r = s2ab(res.d)[1];
postMessage(r, [r]);
};

View File

@ -3,6 +3,13 @@ module.exports = {
libraryTarget: 'var',
library: 'XLSX'
},
/* module.noParse needed for bower */
module: {
noParse: [
/xlsx.core.min.js/,
/xlsx.full.min.js/
]
},
/* Uncomment the next block to suppress codepage */
/*
resolve: {

View File

@ -41,9 +41,6 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
<br />
<script src="webpack.min.js"></script>
<script>
/*jshint browser:true */
/*global XLSX */
var X = XLSX;
var XW = {
/* worker message */
msg: 'xlsx',
@ -52,229 +49,7 @@ var XW = {
norABS: './xlsxworker1.js',
noxfer: './xlsxworker.js'
};
var rABS = typeof FileReader !== "undefined" && typeof FileReader.prototype !== "undefined" && typeof FileReader.prototype.readAsBinaryString !== "undefined";
if(!rABS) {
document.getElementsByName("userabs")[0].disabled = true;
document.getElementsByName("userabs")[0].checked = false;
}
var use_worker = typeof Worker !== 'undefined';
if(!use_worker) {
document.getElementsByName("useworker")[0].disabled = true;
document.getElementsByName("useworker")[0].checked = false;
}
var transferable = use_worker;
if(!transferable) {
document.getElementsByName("xferable")[0].disabled = true;
document.getElementsByName("xferable")[0].checked = false;
}
var wtf_mode = false;
function fixdata(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
return o;
}
function ab2str(data) {
var o = "", l = 0, w = 10240;
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint16Array(data.slice(l*w,l*w+w)));
o+=String.fromCharCode.apply(null, new Uint16Array(data.slice(l*w)));
return o;
}
function s2ab(s) {
var b = new ArrayBuffer(s.length*2), v = new Uint16Array(b);
for (var i=0; i != s.length; ++i) v[i] = s.charCodeAt(i);
return [v, b];
}
function xw_noxfer(data, cb) {
var worker = new Worker(XW.noxfer);
worker.onmessage = function(e) {
switch(e.data.t) {
case 'ready': break;
case 'e': console.error(e.data.d); break;
case XW.msg: cb(JSON.parse(e.data.d)); break;
}
};
var arr = rABS ? data : btoa(fixdata(data));
worker.postMessage({d:arr,b:rABS});
}
function xw_xfer(data, cb) {
var worker = new Worker(rABS ? XW.rABS : XW.norABS);
worker.onmessage = function(e) {
switch(e.data.t) {
case 'ready': break;
case 'e': console.error(e.data.d); break;
default: xx=ab2str(e.data).replace(/\n/g,"\\n").replace(/\r/g,"\\r"); console.log("done"); cb(JSON.parse(xx)); break;
}
};
if(rABS) {
var val = s2ab(data);
worker.postMessage(val[1], [val[1]]);
} else {
worker.postMessage(data, [data]);
}
}
function xw(data, cb) {
transferable = document.getElementsByName("xferable")[0].checked;
if(transferable) xw_xfer(data, cb);
else xw_noxfer(data, cb);
}
function get_radio_value( radioName ) {
var radios = document.getElementsByName( radioName );
for( var i = 0; i < radios.length; i++ ) {
if( radios[i].checked || radios.length === 1 ) {
return radios[i].value;
}
}
}
function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
if(roa.length > 0){
result[sheetName] = roa;
}
});
return result;
}
function to_csv(workbook) {
var result = [];
workbook.SheetNames.forEach(function(sheetName) {
var csv = X.utils.sheet_to_csv(workbook.Sheets[sheetName]);
if(csv.length > 0){
result.push("SHEET: " + sheetName);
result.push("");
result.push(csv);
}
});
return result.join("\n");
}
function to_formulae(workbook) {
var result = [];
workbook.SheetNames.forEach(function(sheetName) {
var formulae = X.utils.get_formulae(workbook.Sheets[sheetName]);
if(formulae.length > 0){
result.push("SHEET: " + sheetName);
result.push("");
result.push(formulae.join("\n"));
}
});
return result.join("\n");
}
var tarea = document.getElementById('b64data');
function b64it() {
if(typeof console !== 'undefined') console.log("onload", new Date());
var wb = X.read(tarea.value, {type: 'base64',WTF:wtf_mode});
process_wb(wb);
}
function process_wb(wb) {
var output = "";
switch(get_radio_value("format")) {
case "json":
output = JSON.stringify(to_json(wb), 2, 2);
break;
case "form":
output = to_formulae(wb);
break;
default:
output = to_csv(wb);
}
if(out.innerText === undefined) out.textContent = output;
else out.innerText = output;
if(typeof console !== 'undefined') console.log("output", new Date());
}
var drop = document.getElementById('drop');
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
rABS = document.getElementsByName("userabs")[0].checked;
use_worker = document.getElementsByName("useworker")[0].checked;
var files = e.dataTransfer.files;
var f = files[0];
{
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
var data = e.target.result;
if(use_worker) {
xw(data, process_wb);
} else {
var wb;
if(rABS) {
wb = X.read(data, {type: 'binary'});
} else {
var arr = fixdata(data);
wb = X.read(btoa(arr), {type: 'base64'});
}
process_wb(wb);
}
};
if(rABS) reader.readAsBinaryString(f);
else reader.readAsArrayBuffer(f);
}
}
function handleDragover(e) {
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
}
if(drop.addEventListener) {
drop.addEventListener('dragenter', handleDragover, false);
drop.addEventListener('dragover', handleDragover, false);
drop.addEventListener('drop', handleDrop, false);
}
var xlf = document.getElementById('xlf');
function handleFile(e) {
rABS = document.getElementsByName("userabs")[0].checked;
use_worker = document.getElementsByName("useworker")[0].checked;
var files = e.target.files;
var f = files[0];
{
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
var data = e.target.result;
if(use_worker) {
xw(data, process_wb);
} else {
var wb;
if(rABS) {
wb = X.read(data, {type: 'binary'});
} else {
var arr = fixdata(data);
wb = X.read(btoa(arr), {type: 'base64'});
}
process_wb(wb);
}
};
if(rABS) reader.readAsBinaryString(f);
else reader.readAsArrayBuffer(f);
}
}
if(xlf.addEventListener) xlf.addEventListener('change', handleFile, false);
</script>
<script src="app.js"></script>
</body>
</html>

1
demos/webpack/xlsx.core.min.js vendored Symbolic link
View File

@ -0,0 +1 @@
../../dist/xlsx.core.min.js

1
demos/webpack/xlsx.full.min.js vendored Symbolic link
View File

@ -0,0 +1 @@
../../dist/xlsx.full.min.js

6
dist/cpexcel.js vendored
View File

@ -1,6 +1,6 @@
/* cpexcel.js (C) 2013-present SheetJS -- http://sheetjs.com */
/*jshint -W100 */
var cptable = {version:"1.10.0"};
var cptable = {version:"1.11.0"};
cptable[437] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[620] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàąçêëèïîćÄĄĘęłôöĆûùŚÖÜ¢Ł¥śƒŹŻóÓńŃźż¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[737] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
@ -973,7 +973,7 @@ return {"enc": e, "dec": d }; })();
cptable[10029] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[10079] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ—“”÷◊ÿŸ¤ÐðÞþý·„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[10081] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ—“”÷◊ÿŸĞğİıŞş‡·„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙ<C39B>ˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d.charAt(i)] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
if (typeof module !== 'undefined' && module.exports) module.exports = cptable;
if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = cptable;
/* cputils.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* vim: set ft=javascript: */
/*jshint newcap: false */
@ -982,7 +982,7 @@ if (typeof module !== 'undefined' && module.exports) module.exports = cptable;
if(typeof cptable === "undefined") {
if(typeof require !== "undefined"){
var cpt = cptable;
if (typeof module !== 'undefined' && module.exports) module.exports = factory(cpt);
if (typeof module !== 'undefined' && module.exports && typeof DO_NOT_EXPORT_CODEPAGE === 'undefined') module.exports = factory(cpt);
else root.cptable = factory(cpt);
} else throw new Error("cptable not found");
} else cptable = factory(cptable);

2
dist/jszip.js vendored
View File

@ -10,7 +10,7 @@ JSZip uses the library pako released under the MIT license :
https://github.com/nodeca/pako/blob/master/LICENSE
*/
(function(e){
if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();
if("object"==typeof exports&&"undefined"!=typeof module&&"undefined"==typeof DO_NOT_EXPORT_JSZIP)module.exports=e();
else if("function"==typeof define&&define.amd){JSZip=e();define([],e);}
else{
var f;

28
dist/xlsx.core.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

30
dist/xlsx.full.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

115
dist/xlsx.js vendored
View File

@ -6,11 +6,11 @@
/*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.11.0';
XLSX.version = '0.11.1';
var current_codepage = 1200;
/*global cptable:true */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') global.cptable = null;
if(typeof cptable === 'undefined') global.cptable = undefined;
}
function reset_cp() { set_cp(1200); }
var set_cp = function(cp) { current_codepage = cp; };
@ -1347,7 +1347,7 @@ function read_date(blob, offset) {
var fs;
function readFileSync(filename, options) {
if(fs == null) fs = null;
if(fs == null) fs = require('fs');
return parse(fs.readFileSync(filename), options);
}
@ -1434,7 +1434,7 @@ var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
var dnthresh = basedate.getTime() + (new Date().getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
function datenum(v, date1904) {
var epoch = v.getTime();
if(date1904) epoch += 1462*24*60*60*1000;
if(date1904) epoch -= 1462*24*60*60*1000;
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
}
function numdate(v) {
@ -1583,8 +1583,8 @@ var _fs, jszip;
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(typeof jszip === 'undefined') jszip = null;
_fs = null;
if(typeof jszip === 'undefined') jszip = undefined;
try { _fs = require('fs'); } catch(e) { }
}
}
@ -1739,12 +1739,15 @@ var vtregex = (function(){ var vt_cache = {};
return (vt_cache[bt] = new RegExp("<(?:vt:)?" + bt + ">([\\s\\S]*?)</(?:vt:)?" + bt + ">", 'g') );
};})();
var vtvregex = /<\/?(?:vt:)?variant>/g, vtmregex = /<(?:vt:)([^>]*)>([\s\S]*)</;
function parseVector(data) {
function parseVector(data, opts) {
var h = parsexmltag(data);
var matches = data.match(vtregex(h.baseType))||[];
if(matches.length != h.size) throw new Error("unexpected vector length " + matches.length + " != " + h.size);
var res = [];
if(matches.length != h.size) {
if(opts.WTF) throw new Error("unexpected vector length " + matches.length + " != " + h.size);
return res;
}
matches.forEach(function(x) {
var v = x.replace(vtvregex,"").match(vtmregex);
res.push({v:utf8read(v[2]), t:v[1]});
@ -2122,7 +2125,7 @@ var make_offcrypto = function(O, _crypto) {
var crypto;
if(typeof _crypto !== 'undefined') crypto = _crypto;
else if(typeof require !== 'undefined') {
try { crypto = null; }
try { crypto = undefined; }
catch(e) { crypto = null; }
}
@ -3336,7 +3339,7 @@ var EXT_PROPS = [
XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties";
RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties';
function parse_ext_props(data, p) {
function parse_ext_props(data, p, opts) {
var q = {}; if(!p) p = {};
EXT_PROPS.forEach(function(f) {
@ -3351,10 +3354,10 @@ function parse_ext_props(data, p) {
});
if(q.HeadingPairs && q.TitlesOfParts) {
var v = parseVector(q.HeadingPairs);
var parts = parseVector(q.TitlesOfParts).map(function(x) { return x.v; });
var v = parseVector(q.HeadingPairs, opts);
var parts = parseVector(q.TitlesOfParts, opts).map(function (x) { return x.v; });
var idx = 0, len = 0;
for(var i = 0; i !== v.length; i+=2) {
if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
len = +(v[i+1].v);
switch(v[i].v) {
case "Worksheets":
@ -3612,7 +3615,7 @@ function parse_VtStringBase(blob, stringType, pad) {
}
function parse_VtString(blob, t, pad) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); }
function parse_VtUnalignedString(blob, t) { if(!t) throw new Error("dafuq?"); return parse_VtStringBase(blob, t, 0); }
function parse_VtUnalignedString(blob, t) { if(!t) throw new Error("VtUnalignedString must have positive length"); return parse_VtStringBase(blob, t, 0); }
/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
function parse_VtVecUnalignedLpstrValue(blob) {
@ -3706,7 +3709,7 @@ function parse_TypedPropertyValue(blob, type, _opts) {
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw && 4).replace(chr0,'');
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw).replace(chr0,'');
case 0x51 /*VT_USTR*/: return parse_VtUnalignedString(blob, t/*, 4*/).replace(chr0,'');
case 0x100C /*VT_VECTOR|VT_VARIANT*/: return parse_VtVecHeadingPair(blob);
case 0x101E /*VT_LPSTR*/: return parse_VtVecUnalignedLpstr(blob);
@ -6703,13 +6706,37 @@ function parse_FilePassHeader(blob, length, oo) {
return o;
}
function parse_FilePass(blob, length, opts) {
var o = { Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }; /* wEncryptionType */
var o = ({ Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }); /* wEncryptionType */
if(o.Type) parse_FilePassHeader(blob, length-2, o);
else parse_XORObfuscation(blob, length-2, opts, o);
return o;
}
var RTF = (function() {
function rtf_to_sheet(d, opts) {
switch(opts.type) {
case 'base64': return rtf_to_sheet_str(Base64.decode(d), opts);
case 'binary': return rtf_to_sheet_str(d, opts);
case 'buffer': return rtf_to_sheet_str(d.toString('binary'), opts);
case 'array': return rtf_to_sheet_str(cc2str(d), opts);
}
throw new Error("Unrecognized type " + opts.type);
}
function rtf_to_sheet_str(str, opts) {
throw new Error("Unsupported RTF");
}
function rtf_to_workbook(d, opts) { return sheet_to_workbook(rtf_to_sheet(d, opts), opts); }
function sheet_to_rtf() { throw new Error("Unsupported"); }
return {
to_workbook: rtf_to_workbook,
to_sheet: rtf_to_sheet,
from_sheet: sheet_to_rtf
};
})();
function hex2RGB(h) {
var o = h.substr(h[0]==="#"?1:0,6);
return [parseInt(o.substr(0,2),16),parseInt(o.substr(2,2),16),parseInt(o.substr(4,2),16)];
@ -6905,8 +6932,9 @@ function parse_fills(t, styles, themes, opts) {
case '<fills': case '<fills>': case '</fills>': break;
/* 18.8.20 fill CT_Fill */
case '<fill>': case '<fill': break;
case '</fill>': styles.Fills.push(fill); fill = {}; break;
case '<fill>': case '<fill': case '<fill/>':
fill = {}; styles.Fills.push(fill); break;
case '</fill>': break;
/* 18.8.24 gradientFill CT_GradientFill */
case '<gradientFill>': break;
@ -7327,6 +7355,7 @@ var XLSBFillPTNames = [
];
var rev_XLSBFillPTNames = (evert(XLSBFillPTNames));
/* TODO: gradient fill representation */
var parse_BrtFill = parsenoop;
function write_BrtFill(fill, o) {
if(!o) o = new_buf(4*3 + 8*7 + 16*1);
var fls = rev_XLSBFillPTNames[fill.patternType];
@ -7389,6 +7418,7 @@ function write_Blxf(data, o) {
return o;
}
/* [MS-XLSB] 2.4.299 BrtBorder TODO */
var parse_BrtBorder = parsenoop;
function write_BrtBorder(border, o) {
if(!o) o = new_buf(51);
o.write_shift(1, 0); /* diagonal */
@ -9025,9 +9055,17 @@ var PtgBinOp = {
PtgPower: "^",
PtgSub: "-"
};
function get_ixti(supbooks, ixti, opts) {
function formula_quote_sheet_name(sname) {
if(!sname) return "";
if(sname.indexOf(" ") > -1) return "'" + sname + "'";
return sname;
}
function get_ixti_raw(supbooks, ixti, opts) {
return supbooks.SheetNames[ixti];
}
function get_ixti(supbooks, ixti, opts) {
return formula_quote_sheet_name(get_ixti_raw(supbooks, ixti, opts));
}
function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
//console.log(formula);
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
@ -10696,7 +10734,8 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
else if(p.t === 'd') p.w = SSF.format(fmtid,datenum(p.v),_ssfopts);
else p.w = SSF.format(fmtid,p.v,_ssfopts);
} catch(e) { if(opts.WTF) throw e; }
if(fillid) try {
if(!opts.cellStyles) return;
if(fillid != null) try {
p.s = styles.Fills[fillid];
if (p.s.fgColor && p.s.fgColor.theme && !p.s.fgColor.rgb) {
p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
@ -10706,7 +10745,7 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
p.s.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.bgColor.theme].rgb, p.s.bgColor.tint || 0);
if(opts.WTF) p.s.bgColor.raw_rgb = themes.themeElements.clrScheme[p.s.bgColor.theme].rgb;
}
} catch(e) { if(opts.WTF) throw e; }
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
}
function parse_ws_xml_dim(ws, s) {
var d = safe_decode_range(s);
@ -13735,12 +13774,14 @@ Workbook.WBProps.date1904 = true;
return out;
}
function arr2str(data) { return data.map(_chr).join(""); }
function parse_xlml(data, opts) {
fix_read_opts(opts=opts||{});
switch(opts.type||"base64") {
case "base64": return parse_xlml_xml(Base64.decode(data), opts);
case "binary": case "buffer": case "file": return parse_xlml_xml(data, opts);
case "array": return parse_xlml_xml(data.map(_chr).join(""), opts);
case "array": return parse_xlml_xml(arr2str(data), opts);
}
}
@ -14900,8 +14941,8 @@ var XLSBRecordEnum = {
0x002A: { n:"BrtIndexBlock", f:parsenoop },
0x002B: { n:"BrtFont", f:parse_BrtFont },
0x002C: { n:"BrtFmt", f:parse_BrtFmt },
0x002D: { n:"BrtFill", f:parsenoop },
0x002E: { n:"BrtBorder", f:parsenoop },
0x002D: { n:"BrtFill", f:parse_BrtFill },
0x002E: { n:"BrtBorder", f:parse_BrtBorder },
0x002F: { n:"BrtXF", f:parse_BrtXF },
0x0030: { n:"BrtStyle", f:parsenoop },
0x0031: { n:"BrtCellMeta", f:parsenoop },
@ -17060,6 +17101,7 @@ var write_csv_str = write_obj_str({from_sheet:sheet_to_csv});
var write_slk_str = write_obj_str(SYLK);
var write_dif_str = write_obj_str(DIF);
var write_prn_str = write_obj_str(PRN);
var write_rtf_str = write_obj_str(RTF);
var write_txt_str = write_obj_str({from_sheet:sheet_to_txt});
function fix_opts_func(defaults) {
return function fix_opts(opts) {
@ -17192,7 +17234,7 @@ function parse_zip(zip, opts) {
if(propdata) props = parse_core_props(propdata);
if(dir.extprops.length !== 0) {
propdata = getzipstr(zip, dir.extprops[0].replace(/^\//,''), true);
if(propdata) parse_ext_props(propdata, props);
if(propdata) parse_ext_props(propdata, props, opts);
}
}
@ -17515,7 +17557,7 @@ function readSync(data, opts) {
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);
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) throw new Error("Unsupported RTF"); break;
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) return RTF.to_workbook(d, o); break;
case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
}
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
@ -17598,6 +17640,7 @@ function writeSync(wb, opts) {
case 'csv': return write_string_type(write_csv_str(wb, o), o);
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': return write_binary_type(write_biff_buf(wb, o), o);
case 'xlsx':
@ -17624,6 +17667,7 @@ function resolve_book_type(o/*?WriteFileOpts*/) {
case '.txt': o.bookType = 'txt'; break;
case '.dif': o.bookType = 'dif'; break;
case '.prn': o.bookType = 'prn'; break;
case '.rtf': o.bookType = 'rtf'; break;
case '.slk': o.bookType = 'sylk'; break;
case '.htm': o.bookType = 'html'; break;
}
@ -17727,8 +17771,9 @@ function sheet_to_json(sheet, opts){
var qreg = /"/g;
function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
var isempty = true;
var row = "", txt = "", rr = encode_row(R);
var row = [], txt = "", rr = encode_row(R);
for(var C = r.s.c; C <= r.e.c; ++C) {
if (!cols[C]) continue;
var val = o.dense ? (sheet[R]||[])[C]: sheet[cols[C] + rr];
if(val == null) txt = "";
else if(val.v != null) {
@ -17741,10 +17786,10 @@ function make_csv_row(sheet, r, R, cols, fs, rs, FS, o) {
txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
} else txt = "";
/* NOTE: Excel CSV does not support array formulae */
row += (C === r.s.c ? "" : FS) + txt;
row.push(txt);
}
if(o.blankrows === false && isempty) return null;
return row;
return row.join(FS);
}
function sheet_to_csv(sheet, opts) {
@ -17757,8 +17802,11 @@ function sheet_to_csv(sheet, opts) {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row = "", cols = [];
o.dense = Array.isArray(sheet);
for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
var colInfos = o.skipHidden && sheet["!cols"] || [];
var rowInfos = o.skipHidden && sheet["!rows"] || [];
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
for(var R = r.s.r; R <= r.e.r; ++R) {
if ((rowInfos[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
if(row == null) { continue; }
if(o.strip) row = row.replace(endregex,"");
@ -17987,13 +18035,16 @@ if(has_buf && typeof require != 'undefined') (function() {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row = "", cols = [];
o.dense = Array.isArray(sheet);
for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
var colInfos = o.skipHidden && sheet["!cols"] || [];
var rowInfos = o.skipHidden && sheet["!rows"] || [];
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
var R = r.s.r;
stream._read = function() {
if(R > r.e.r) return stream.push(null);
while(R <= r.e.r) {
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
++R;
if ((rowInfos[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
if(row != null) {
if(o.strip) row = row.replace(endregex,"");
stream.push(row + RS);

22
dist/xlsx.min.js vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.min.map vendored

File diff suppressed because one or more lines are too long

View File

@ -27,5 +27,3 @@
- ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats"
- Open Document Format for Office Applications Version 1.2 (29 September 2011)
- Worksheet File Format (From Lotus) December 1984

View File

@ -10,7 +10,7 @@ JSZip uses the library pako released under the MIT license :
https://github.com/nodeca/pako/blob/master/LICENSE
*/
(function(e){
if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();
if("object"==typeof exports&&"undefined"!=typeof module&&"undefined"==typeof DO_NOT_EXPORT_JSZIP)module.exports=e();
else if("function"==typeof define&&define.amd){JSZip=e();define([],e);}
else{
var f;

View File

@ -1559,6 +1559,7 @@ produces CSV output. The function takes an options argument:
| dateNF | fmt 14 | Use specified date format in string output |
| strip | false | Remove trailing field separators in each record ** |
| blankrows | true | Include blank lines in the CSV output |
| skipHidden | false | Skips hidden rows/columns in the CSV output |
- `strip` will remove trailing commas from each line under default `FS/RS`
- blankrows must be set to `false` to skip blank lines.
@ -2100,5 +2101,3 @@ granted by the Apache 2.0 License are reserved by the Original Author.
- ISO/IEC 29500:2012(E) "Information technology — Document description and processing languages — Office Open XML File Formats"
- Open Document Format for Office Applications Version 1.2 (29 September 2011)
- Worksheet File Format (From Lotus) December 1984

2
misc/suppress_export.js Normal file
View File

@ -0,0 +1,2 @@
var DO_NOT_EXPORT_CODEPAGE = true;
var DO_NOT_EXPORT_JSZIP = true;

View File

@ -1,6 +1,6 @@
{
"name": "xlsx",
"version": "0.11.0",
"version": "0.11.1",
"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" ],
@ -19,7 +19,7 @@
"dependencies": {
"exit-on-epipe":"~1.0.1",
"ssf":"~0.10.1",
"codepage":"~1.10.1",
"codepage":"~1.11.0",
"cfb":"~0.12.0",
"crc-32":"~1.1.0",
"adler-32":"~1.1.0",

414
test.js
View File

@ -7,21 +7,25 @@ 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 opts = {cellNF: true};
if(process.env.WTF) {
opts.WTF = true;
opts.cellStyles = true;
}
var TYPE = browser ? "binary" : "buffer";
opts.type = TYPE;
var fullex = [".xlsb", /*".xlsm",*/ ".xlsx"/*, ".xlml"*/];
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "xlml", "sylk", "dif"];
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
if(process.env.FMTS === "full") process.env.FMTS = ex.join(":");
if(process.env.FMTS) ex=process.env.FMTS.split(":").map(function(x){return x[0]==="."?x:"."+x;});
if(typeof process != 'undefined' && ((process||{}).env)) {
opts.WTF = true;
opts.cellStyles = true;
if(process.env.FMTS === "full") process.env.FMTS = ex.join(":");
if(process.env.FMTS) ex=process.env.FMTS.split(":").map(function(x){return x[0]==="."?x:"."+x;});
}
var exp = ex.map(function(x){ return x + ".pending"; });
function test_file(x){ return ex.indexOf(x.substr(-5))>=0||exp.indexOf(x.substr(-13))>=0 || ex.indexOf(x.substr(-4))>=0||exp.indexOf(x.substr(-12))>=0; }
var files = (fs.existsSync('tests.lst') ? fs.readFileSync('tests.lst', 'utf-8').split("\n").map(function(x) { return x.trim(); }) : fs.readdirSync('test_files')).filter(test_file);
var fileA = (fs.existsSync('tests/testA.lst') ? fs.readFileSync('tests/testA.lst', 'utf-8').split("\n").map(function(x) { return x.trim(); }) : []).filter(test_file);
var files = browser ? [] : (fs.existsSync('tests.lst') ? fs.readFileSync('tests.lst', 'utf-8').split("\n").map(function(x) { return x.trim(); }) : fs.readdirSync('test_files')).filter(test_file);
var fileA = browser ? [] : (fs.existsSync('tests/testA.lst') ? fs.readFileSync('tests/testA.lst', 'utf-8').split("\n").map(function(x) { return x.trim(); }) : []).filter(test_file);
/* Excel enforces 31 character sheet limit, although technical file limit is 255 */
function fixsheetname(x) { return x.substr(0,31); }
@ -241,7 +245,7 @@ function parsetest(x, wb, full, ext) {
var wbtable = {};
describe('should parse test files', function() {
(browser ? describe.skip : describe)('should parse test files', function() {
files.forEach(function(x) {
if(x.slice(-8) == ".pending" || !fs.existsSync(dir + x)) return;
it(x, function() {
@ -304,14 +308,14 @@ describe('parse options', function() {
else it('before', bef);
describe('cell', function() {
it('XLSX should generate HTML by default', function() {
var wb = X.readFile(paths.cstxlsx);
var wb = X.read(fs.readFileSync(paths.cstxlsx), {type:TYPE});
var ws = wb.Sheets.Sheet1;
each_cell(ws, function(cell) {
assert(html_cell_types.indexOf(cell.t) === -1 || cell.h);
});
});
it('XLSX should not generate HTML when requested', function() {
var wb = X.readFile(paths.cstxlsx, {cellHTML:false});
var wb = X.read(fs.readFileSync(paths.cstxlsx), {type:TYPE, cellHTML:false});
var ws = wb.Sheets.Sheet1;
each_cell(ws, function(cell) {
assert(typeof cell.h === 'undefined');
@ -319,7 +323,7 @@ describe('parse options', function() {
});
it('should generate formulae by default', function() {
FSTPaths.forEach(function(p) {
var wb = X.readFile(p);
var wb = X.read(fs.readFileSync(p), {type:TYPE});
var found = false;
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
@ -332,7 +336,7 @@ describe('parse options', function() {
});
it('should not generate formulae when requested', function() {
FSTPaths.forEach(function(p) {
var wb =X.readFile(p,{cellFormula:false});
var wb =X.read(fs.readFileSync(p),{type:TYPE,cellFormula:false});
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
each_cell(ws, function(cell) {
@ -343,7 +347,7 @@ describe('parse options', function() {
});
it('should generate formatted text by default', function() {
FSTPaths.forEach(function(p) {
var wb = X.readFile(p);
var wb = X.read(fs.readFileSync(p),{type:TYPE});
var found = false;
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
@ -356,7 +360,7 @@ describe('parse options', function() {
});
it('should not generate formatted text when requested', function() {
FSTPaths.forEach(function(p) {
var wb =X.readFile(p,{cellText:false});
var wb =X.read(fs.readFileSync(p),{type:TYPE, cellText:false});
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
each_cell(ws, function(cell) {
@ -367,7 +371,7 @@ describe('parse options', function() {
});
it('should not generate number formats by default', function() {
NFPaths.forEach(function(p) {
var wb = X.readFile(p);
var wb = X.read(fs.readFileSync(p), {type:TYPE});
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
each_cell(ws, function(cell) {
@ -378,7 +382,7 @@ describe('parse options', function() {
});
it('should generate number formats when requested', function() {
NFPaths.forEach(function(p) {
var wb = X.readFile(p, {cellNF: true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, cellNF: true});
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
each_cell(ws, function(cell) {
@ -389,7 +393,7 @@ describe('parse options', function() {
});
it('should not generate cell styles by default', function() {
[paths.cssxlsx, paths.cssxlsb, paths.cssxls, paths.cssxml].forEach(function(p) {
var wb = X.readFile(p);
var wb = X.read(fs.readFileSync(p), {type:TYPE, WTF:1});
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
each_cell(ws, function(cell) {
@ -401,7 +405,7 @@ describe('parse options', function() {
it('should generate cell styles when requested', function() {
/* TODO: XLS / XLML */
[paths.cssxlsx /*, paths.cssxlsb, paths.cssxls, paths.cssxml*/].forEach(function(p) {
var wb = X.readFile(p, {cellStyles:true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, cellStyles:true});
var found = false;
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
@ -414,7 +418,7 @@ describe('parse options', function() {
});
it('should not generate cell dates by default', function() {
DTPaths.forEach(function(p) {
var wb = X.readFile(p);
var wb = X.read(fs.readFileSync(p), {type:TYPE});
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
each_cell(ws, function(cell) {
@ -425,7 +429,7 @@ describe('parse options', function() {
});
it('should generate cell dates when requested', function() {
DTPaths.forEach(function(p) {
var wb = X.readFile(p, {cellDates: true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, cellDates: true, WTF:1});
var found = false;
wb.SheetNames.forEach(function(s) {
var ws = wb.Sheets[s];
@ -440,23 +444,23 @@ describe('parse options', function() {
describe('sheet', function() {
it('should not generate sheet stubs by default', function() {
[paths.mcxlsx, paths.mcxlsb, paths.mcods, paths.mcxls, paths.mcxml].forEach(function(p) {
var wb = X.readFile(p);
var wb = X.read(fs.readFileSync(p), {type:TYPE});
assert.throws(function() { return get_cell(wb.Sheets.Merge, "A2").v; });
});
});
it('should generate sheet stubs when requested', function() {
[paths.mcxlsx, paths.mcxlsb, paths.mcods, paths.mcxls, paths.mcxml].forEach(function(p) {
var wb = X.readFile(p, {sheetStubs:true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, sheetStubs:true});
assert(get_cell(wb.Sheets.Merge, "A2").t == 'z');
});
});
it('should handle stub cells', function() {
[paths.mcxlsx, paths.mcxlsb, paths.mcods, paths.mcxls, paths.mcxml].forEach(function(p) {
var wb = X.readFile(p, {sheetStubs:true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, sheetStubs:true});
X.utils.sheet_to_csv(wb.Sheets.Merge);
X.utils.sheet_to_json(wb.Sheets.Merge);
X.utils.sheet_to_formulae(wb.Sheets.Merge);
ofmt.forEach(function(f) { X.write(wb, {type:"binary", bookType:f}); });
ofmt.forEach(function(f) { X.write(wb, {type:TYPE, bookType:f}); });
});
});
function checkcells(wb, A46, B26, C16, D2) {
@ -467,48 +471,48 @@ describe('parse options', function() {
}
it('should read all cells by default', function() {
[paths.fstxlsx, paths.fstxlsb, paths.fstods, paths.fstxls, paths.fstxml].forEach(function(p) {
checkcells(X.readFile(p), true, true, true, true);
checkcells(X.read(fs.readFileSync(p), {type:TYPE}), true, true, true, true);
});
});
it('sheetRows n=20', function() {
[paths.fstxlsx, paths.fstxlsb, paths.fstods, paths.fstxls, paths.fstxml].forEach(function(p) {
checkcells(X.readFile(p, {sheetRows:20}), false, false, true, true);
checkcells(X.read(fs.readFileSync(p), {type:TYPE, sheetRows:20}), false, false, true, true);
});
});
it('sheetRows n=10', function() {
[paths.fstxlsx, paths.fstxlsb, paths.fstods, paths.fstxls, paths.fstxml].forEach(function(p) {
checkcells(X.readFile(p, {sheetRows:10}), false, false, false, true);
checkcells(X.read(fs.readFileSync(p), {type:TYPE, sheetRows:10}), false, false, false, true);
});
});
});
describe('book', function() {
it('bookSheets should not generate sheets', function() {
[paths.mcxlsx, paths.mcxlsb, paths.mcxls, paths.mcxml].forEach(function(p) {
var wb = X.readFile(p, {bookSheets:true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, bookSheets:true});
assert(typeof wb.Sheets === 'undefined');
});
});
it('bookProps should not generate sheets', function() {
[paths.nfxlsx, paths.nfxlsb, paths.nfxls, paths.nfxml].forEach(function(p) {
var wb = X.readFile(p, {bookProps:true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, bookProps:true});
assert(typeof wb.Sheets === 'undefined');
});
});
it('bookProps && bookSheets should not generate sheets', function() {
[paths.lonxlsx, paths.lonxls].forEach(function(p) {
var wb = X.readFile(p, {bookProps:true, bookSheets:true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, bookProps:true, bookSheets:true});
assert(typeof wb.Sheets === 'undefined');
});
});
it('should not generate deps by default', function() {
[paths.fstxlsx, paths.fstxlsb, paths.fstxls, paths.fstxml].forEach(function(p) {
var wb = X.readFile(p);
var wb = X.read(fs.readFileSync(p), {type:TYPE});
assert(typeof wb.Deps === 'undefined' || !(wb.Deps && wb.Deps.length>0));
});
});
it('bookDeps should generate deps (XLSX/XLSB)', function() {
[paths.fstxlsx, paths.fstxlsb].forEach(function(p) {
var wb = X.readFile(p, {bookDeps:true});
var wb = X.read(fs.readFileSync(p), {type:TYPE, bookDeps:true});
assert(typeof wb.Deps !== 'undefined' && wb.Deps.length > 0);
});
});
@ -517,32 +521,32 @@ describe('parse options', function() {
}); };
it('should not generate book files by default', function() {
var wb;
wb = X.readFile(paths.fstxlsx);
wb = X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE});
ckf(wb, ['files', 'keys'], false);
wb = X.readFile(paths.fstxlsb);
wb = X.read(fs.readFileSync(paths.fstxlsb), {type:TYPE});
ckf(wb, ['files', 'keys'], false);
wb = X.readFile(paths.fstxls);
wb = X.read(fs.readFileSync(paths.fstxls), {type:TYPE});
ckf(wb, ['cfb'], false);
});
it('bookFiles should generate book files', function() {
var wb;
wb = X.readFile(paths.fstxlsx, {bookFiles:true});
wb = X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE, bookFiles:true});
ckf(wb, ['files', 'keys'], true);
wb = X.readFile(paths.fstxlsb, {bookFiles:true});
wb = X.read(fs.readFileSync(paths.fstxlsb), {type:TYPE, bookFiles:true});
ckf(wb, ['files', 'keys'], true);
wb = X.readFile(paths.fstxls, {bookFiles:true});
wb = X.read(fs.readFileSync(paths.fstxls), {type:TYPE, bookFiles:true});
ckf(wb, ['cfb'], true);
});
it('should not generate VBA by default', function() {
var wb = X.readFile(paths.nfxlsx);
var wb = X.read(fs.readFileSync(paths.nfxlsx), {type:TYPE});
assert(typeof wb.vbaraw === 'undefined');
wb = X.readFile(paths.nfxlsb);
wb = X.read(fs.readFileSync(paths.nfxlsb), {type:TYPE});
assert(typeof wb.vbaraw === 'undefined');
});
it('bookVBA should generate vbaraw (XLSX/XLSB)', function() {
var wb = X.readFile(paths.nfxlsx,{bookVBA:true});
var wb = X.read(fs.readFileSync(paths.nfxlsx),{type:TYPE, bookVBA:true});
assert(wb.vbaraw);
wb = X.readFile(paths.nfxlsb,{bookVBA:true});
wb = X.read(fs.readFileSync(paths.nfxlsb),{type:TYPE, bookVBA:true});
assert(wb.vbaraw);
});
});
@ -563,19 +567,20 @@ describe('input formats', function() {
X.read(fs.readFileSync(paths.cstxlsx, 'base64'), {type: 'base64'});
X.read(fs.readFileSync(paths.cstxlsb, 'base64'), {type: 'base64'});
});
it('should read buffers', function() {
X.read(fs.readFileSync(paths.cstxls), {type: 'buffer'});
X.read(fs.readFileSync(paths.cstxml), {type: 'buffer'});
X.read(fs.readFileSync(paths.cstods), {type: 'buffer'});
X.read(fs.readFileSync(paths.cstxlsx), {type: 'buffer'});
X.read(fs.readFileSync(paths.cstxlsb), {type: 'buffer'});
var k = browser ? 'array' : 'buffer';
(typeof UInt8Array !== 'undefined' ? it : it.skip)('should read ' + k + 's', function() {
X.read(fs.readFileSync(paths.cstxls, 'buffer'), {type: k});
X.read(fs.readFileSync(paths.cstxml, 'buffer'), {type: k});
X.read(fs.readFileSync(paths.cstods, 'buffer'), {type: k});
X.read(fs.readFileSync(paths.cstxlsx, 'buffer'), {type: k});
X.read(fs.readFileSync(paths.cstxlsb, 'buffer'), {type: k});
});
it('should read array', function() {
X.read(fs.readFileSync(paths.mcxls, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
X.read(fs.readFileSync(paths.mcxml, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
X.read(fs.readFileSync(paths.mcxlsx, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
X.read(fs.readFileSync(paths.mcxlsb, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
X.read(fs.readFileSync(paths.mcods, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
(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'});
});
it('should throw if format is unknown', function() {
assert.throws(function() { X.read(fs.readFileSync(paths.cstxls), {type: 'dafuq'}); });
@ -584,6 +589,15 @@ describe('input formats', function() {
assert.throws(function() { X.read(fs.readFileSync(paths.cstxlsx), {type: 'dafuq'}); });
assert.throws(function() { X.read(fs.readFileSync(paths.cstxlsb), {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'));
});
else {
it('should infer buffer type', function() {
X.read(fs.readFileSync(paths.cstxls));
X.read(fs.readFileSync(paths.cstxml));
@ -591,25 +605,33 @@ describe('input formats', function() {
X.read(fs.readFileSync(paths.cstxlsx));
X.read(fs.readFileSync(paths.cstxlsb));
});
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);
});
}
});
describe('output formats', function() {
var wb1, wb2, wb3, wb4;
var bef = (function() {
X = require(modp);
wb1 = X.readFile(paths.cpxlsx);
wb2 = X.readFile(paths.cpxlsb);
wb3 = X.readFile(paths.cpxls);
wb4 = X.readFile(paths.cpxml);
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.readFile(paths.cpxlsx);
wb2 = X.readFile(paths.cpxlsb);
wb3 = X.readFile(paths.cpxls);
wb4 = X.readFile(paths.cpxml);
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'});
@ -630,7 +652,7 @@ describe('output formats', function() {
X.read(X.write(wb3, {type: 'base64'}), {type: 'base64'});
X.read(X.write(wb4, {type: 'base64'}), {type: 'base64'});
});
it('should write buffers', function() {
if(!browser) it('should write buffers', function() {
X.write(wb1, {type: 'buffer'});
X.write(wb2, {type: 'buffer'});
X.write(wb3, {type: 'buffer'});
@ -736,11 +758,11 @@ describe('parse features', function() {
describe('sheet visibility', function() {
var wb1, wb2, wb3, wb4, wb5;
var bef = (function() {
wb1 = X.readFile(paths.svxls);
wb2 = X.readFile(paths.svxls5);
wb3 = X.readFile(paths.svxml);
wb4 = X.readFile(paths.svxlsx);
wb5 = X.readFile(paths.svxlsb);
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});
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
@ -768,10 +790,10 @@ describe('parse features', function() {
if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){
var X = require(modp);
var sheet = 'Sheet1';
var wb1=X.readFile(paths.swcxlsx);
var wb2=X.readFile(paths.swcxlsb);
var wb3=X.readFile(paths.swcxls);
var wb4=X.readFile(paths.swcxml);
var wb1=X.read(fs.readFileSync(paths.swcxlsx), {type:TYPE});
var wb2=X.read(fs.readFileSync(paths.swcxlsb), {type:TYPE});
var wb3=X.read(fs.readFileSync(paths.swcxls), {type:TYPE});
var wb4=X.read(fs.readFileSync(paths.swcxml), {type:TYPE});
[wb1,wb2,wb3,wb4].map(function(wb) { return wb.Sheets[sheet]; }).forEach(function(ws, i) {
assert.equal(get_cell(ws, "B1").c.length, 1,"must have 1 comment");
@ -789,7 +811,7 @@ describe('parse features', function() {
['xlml', paths.cstxml],
['ods', paths.cstods]
].forEach(function(m) { it(m[0] + ' stress test', function() {
var wb = X.readFile(m[1]);
var wb = X.read(fs.readFileSync(m[1]), {type:TYPE});
check_comments(wb);
var ws0 = wb.Sheets.Sheet2;
assert.equal(get_cell(ws0,"A1").c[0].a, 'Author');
@ -802,10 +824,10 @@ describe('parse features', function() {
describe('should parse core properties and custom properties', function() {
var wb1, wb2, wb3, wb4;
var bef = (function() {
wb1 = X.readFile(paths.cpxlsx);
wb2 = X.readFile(paths.cpxlsb);
wb3 = X.readFile(paths.cpxls);
wb4 = X.readFile(paths.cpxml);
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);
@ -822,22 +844,22 @@ describe('parse features', function() {
describe('sheetRows', function() {
it('should use original range if not set', function() {
var opts = {};
var wb1 = X.readFile(paths.fstxlsx, opts);
var wb2 = X.readFile(paths.fstxlsb, opts);
var wb3 = X.readFile(paths.fstxls, opts);
var wb4 = X.readFile(paths.fstxml, opts);
var opts = {type:TYPE};
var wb1 = X.read(fs.readFileSync(paths.fstxlsx), opts);
var wb2 = X.read(fs.readFileSync(paths.fstxlsb), opts);
var wb3 = X.read(fs.readFileSync(paths.fstxls), opts);
var wb4 = X.read(fs.readFileSync(paths.fstxml), opts);
[wb1, wb2, wb3, wb4].forEach(function(wb) {
assert.equal(wb.Sheets.Text["!ref"],"A1:F49");
});
});
it('should adjust range if set', function() {
var opts = {sheetRows:10};
var wb1 = X.readFile(paths.fstxlsx, opts);
var wb2 = X.readFile(paths.fstxlsb, opts);
var wb3 = X.readFile(paths.fstxls, opts);
var wb4 = X.readFile(paths.fstxml, opts);
var wb5 = X.readFile(paths.fstods, opts);
var opts = {type:TYPE, sheetRows:10};
var wb1 = X.read(fs.readFileSync(paths.fstxlsx), opts);
var wb2 = X.read(fs.readFileSync(paths.fstxlsb), opts);
var wb3 = X.read(fs.readFileSync(paths.fstxls), opts);
var wb4 = X.read(fs.readFileSync(paths.fstxml), opts);
var wb5 = X.read(fs.readFileSync(paths.fstods), opts);
/* TODO */
[wb1, wb2 /*, wb3, wb4, wb5 */].forEach(function(wb) {
assert.equal(wb.Sheets.Text["!fullref"],"A1:F49");
@ -845,12 +867,12 @@ describe('parse features', function() {
});
});
it('should not generate comment cells', function() {
var opts = {sheetRows:10};
var wb1 = X.readFile(paths.cstxlsx, opts);
var wb2 = X.readFile(paths.cstxlsb, opts);
var wb3 = X.readFile(paths.cstxls, opts);
var wb4 = X.readFile(paths.cstxml, opts);
var wb5 = X.readFile(paths.cstods, opts);
var opts = {type:TYPE, sheetRows:10};
var wb1 = X.read(fs.readFileSync(paths.cstxlsx), opts);
var wb2 = X.read(fs.readFileSync(paths.cstxlsb), opts);
var wb3 = X.read(fs.readFileSync(paths.cstxls), opts);
var wb4 = X.read(fs.readFileSync(paths.cstxml), opts);
var wb5 = X.read(fs.readFileSync(paths.cstods), opts);
/* TODO */
[wb1, wb2 /*, wb3, wb4, wb5 */].forEach(function(wb) {
assert.equal(wb.Sheets.Sheet7["!fullref"],"A1:N34");
@ -863,12 +885,12 @@ describe('parse features', function() {
var wb1, wb2, wb3, wb4, wb5, wb6;
var bef = (function() {
X = require(modp);
wb1 = X.readFile(paths.cwxlsx, {cellStyles:true});
wb2 = X.readFile(paths.cwxlsb, {cellStyles:true});
wb3 = X.readFile(paths.cwxls, {cellStyles:true});
wb4 = X.readFile(paths.cwxls5, {cellStyles:true});
wb5 = X.readFile(paths.cwxml, {cellStyles:true});
wb6 = X.readFile(paths.cwslk, {cellStyles:true});
wb1 = X.read(fs.readFileSync(paths.cwxlsx), {type:TYPE, cellStyles:true});
wb2 = X.read(fs.readFileSync(paths.cwxlsb), {type:TYPE, cellStyles:true});
wb3 = X.read(fs.readFileSync(paths.cwxls), {type:TYPE, cellStyles:true});
wb4 = X.read(fs.readFileSync(paths.cwxls5), {type:TYPE, cellStyles:true});
wb5 = X.read(fs.readFileSync(paths.cwxml), {type:TYPE, cellStyles:true});
wb6 = X.read(fs.readFileSync(paths.cwslk), {type:TYPE, cellStyles:true});
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
@ -910,17 +932,17 @@ describe('parse features', function() {
var ol1, ol2, ol3, ol4, ol5;
var bef = (function() {
X = require(modp);
wb1 = X.readFile(paths.rhxlsx, {cellStyles:true});
wb2 = X.readFile(paths.rhxlsb, {cellStyles:true});
wb3 = X.readFile(paths.rhxls, {cellStyles:true});
wb4 = X.readFile(paths.rhxls5, {cellStyles:true});
wb5 = X.readFile(paths.rhxml, {cellStyles:true});
wb6 = X.readFile(paths.rhslk, {cellStyles:true});
ol1 = X.readFile(paths.olxlsx, {cellStyles:true});
ol2 = X.readFile(paths.olxlsb, {cellStyles:true});
ol3 = X.readFile(paths.olxls, {cellStyles:true});
ol4 = X.readFile(paths.olxls5, {cellStyles:true});
ol5 = X.readFile(paths.olods, {cellStyles:true});
wb1 = X.read(fs.readFileSync(paths.rhxlsx), {type:TYPE, cellStyles:true});
wb2 = X.read(fs.readFileSync(paths.rhxlsb), {type:TYPE, cellStyles:true});
wb3 = X.read(fs.readFileSync(paths.rhxls), {type:TYPE, cellStyles:true});
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});
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});
ol4 = X.read(fs.readFileSync(paths.olxls5), {type:TYPE, cellStyles:true});
ol5 = X.read(fs.readFileSync(paths.olods), {type:TYPE, cellStyles:true});
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
@ -964,11 +986,11 @@ describe('parse features', function() {
var wb1, wb2, wb3, wb4, wb5;
var bef = (function() {
X = require(modp);
wb1 = X.readFile(paths.mcxlsx);
wb2 = X.readFile(paths.mcxlsb);
wb3 = X.readFile(paths.mcods);
wb4 = X.readFile(paths.mcxls);
wb5 = X.readFile(paths.mcxml);
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});
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
@ -990,10 +1012,10 @@ describe('parse features', function() {
var wb1, wb2, wb3, wb4;
var bef = (function() {
X = require(modp);
wb1 = X.readFile(paths.hlxlsx);
wb2 = X.readFile(paths.hlxlsb);
wb3 = X.readFile(paths.hlxls);
wb4 = X.readFile(paths.hlxml);
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});
});
if(typeof before != 'undefined') before(bef);
else it('before', bef);
@ -1008,7 +1030,7 @@ describe('parse features', function() {
it('Must have read the date', function() {
var wb, ws;
var sheetName = 'Sheet1';
wb = X.readFile(paths.dtxlsx);
wb = X.read(fs.readFileSync(paths.dtxlsx), {type:TYPE});
ws = wb.Sheets[sheetName];
var sheet = X.utils.sheet_to_json(ws);
assert.equal(sheet[3]['てすと'], '2/14/14');
@ -1016,9 +1038,9 @@ describe('parse features', function() {
it('cellDates should not affect formatted text', function() {
var wb1, ws1, wb2, ws2;
var sheetName = 'Sheet1';
wb1 = X.readFile(paths.dtxlsx);
wb1 = X.read(fs.readFileSync(paths.dtxlsx), {type:TYPE});
ws1 = wb1.Sheets[sheetName];
wb2 = X.readFile(paths.dtxlsb);
wb2 = X.read(fs.readFileSync(paths.dtxlsb), {type:TYPE});
ws2 = wb2.Sheets[sheetName];
assert.equal(X.utils.sheet_to_csv(ws1),X.utils.sheet_to_csv(ws2));
});
@ -1035,14 +1057,14 @@ describe('parse features', function() {
];
it('should not generate date cells by default', function() { fmts.forEach(function(f) {
var wb, ws;
wb = X.readFile(f[1]);
wb = X.read(fs.readFileSync(f[1]), {type:TYPE});
ws = wb.Sheets[f[2]];
assert.equal(get_cell(ws, f[3]).w, f[4]);
assert.equal(get_cell(ws, f[3]).t, 'n');
}); });
it('should generate date cells if cellDates is true', function() { fmts.forEach(function(f) {
var wb, ws;
wb = X.readFile(f[1], {cellDates:true});
wb = X.read(fs.readFileSync(f[1]), {type:TYPE, cellDates:true});
ws = wb.Sheets[f[2]];
assert.equal(get_cell(ws, f[3]).w, f[4]);
assert.equal(get_cell(ws, f[3]).t, 'd');
@ -1057,7 +1079,7 @@ describe('parse features', function() {
['xls', paths.dnsxls, true],
['xlml', paths.dnsxml, false],
].forEach(function(m) { it(m[0], function() {
var wb = X.readFile(m[1]);
var wb = X.read(fs.readFileSync(m[1]), {type:TYPE});
var names = wb.Workbook.Names;
for(var i = 0; i < names.length; ++i) if(names[i].Name == "SheetJS") break;
assert(i < names.length, "Missing name");
@ -1080,7 +1102,7 @@ describe('parse features', function() {
['xlml', paths.afxml],
['ods', paths.afods]
].forEach(function(m) { it(m[0], function() {
var wb = X.readFile(m[1]);
var wb = X.read(fs.readFileSync(m[1]), {type:TYPE});
assert(wb.Sheets[wb.SheetNames[0]]['!autofilter'] == null);
for(var i = 1; i < wb.SheetNames.length; ++i) {
assert(wb.Sheets[wb.SheetNames[i]]['!autofilter'] != null);
@ -1101,7 +1123,7 @@ describe('parse features', function() {
if(typeof before != 'undefined') before(bef);
else it('before', bef);
['xlsx'].forEach(function(m) { it(m, function() {
var wb2 = X.read(X.write(wb, {bookType:m, type:"binary"}),{type:"binary", cellHTML:true});
var wb2 = X.read(X.write(wb, {bookType:m, type:TYPE}),{type:TYPE, cellHTML:true});
assert.equal(get_cell(wb2.Sheets.Sheet1, "A2").h, "&amp;");
assert.equal(get_cell(wb2.Sheets.Sheet1, "B2").h, "&lt;");
assert.equal(get_cell(wb2.Sheets.Sheet1, "C2").h, "&gt;");
@ -1113,11 +1135,11 @@ describe('parse features', function() {
var wb1, wb2, wb3, wb4, wb5, wbs;
var bef = (function() {
if(!fs.existsSync(paths.pmxls)) return wbs=[];
wb1 = X.readFile(paths.pmxls);
wb2 = X.readFile(paths.pmxls5);
wb3 = X.readFile(paths.pmxml);
wb4 = X.readFile(paths.pmxlsx);
wb5 = X.readFile(paths.pmxlsb);
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(typeof before != 'undefined') before(bef);
@ -1148,8 +1170,8 @@ describe('parse features', function() {
describe('should correctly handle styles', function() {
var wsxls, wsxlsx, rn, rn2;
var bef = (function() {
wsxls=X.readFile(paths.cssxls, {cellStyles:true,WTF:1}).Sheets.Sheet1;
wsxlsx=X.readFile(paths.cssxlsx, {cellStyles:true,WTF:1}).Sheets.Sheet1;
wsxls=X.read(fs.readFileSync(paths.cssxls), {type:TYPE,cellStyles:true,WTF:1}).Sheets.Sheet1;
wsxlsx=X.read(fs.readFileSync(paths.cssxlsx), {type:TYPE,cellStyles:true,WTF:1}).Sheets.Sheet1;
rn = function(range) {
var r = X.utils.decode_range(range);
var out = [];
@ -1255,9 +1277,9 @@ describe('write features', function() {
Sheets: {Sheet1: ws}
};
Object.keys(baseprops).forEach(function(k) { wb.Props[k] = baseprops[k]; });
var wb2 = X.read(X.write(wb, {bookType:w, type:"buffer"}), {type:"buffer"});
var wb2 = X.read(X.write(wb, {bookType:w, type:TYPE}), {type:TYPE});
Object.keys(baseprops).forEach(function(k) { assert.equal(baseprops[k], wb2.Props[k]); });
var wb3 = X.read(X.write(wb2, {bookType:w, type:"buffer", Props: {Author:"SheetJS"}}), {type:"buffer"});
var wb3 = X.read(X.write(wb2, {bookType:w, type:TYPE, Props: {Author:"SheetJS"}}), {type:TYPE});
assert.equal("SheetJS", wb3.Props.Author);
}); });
});
@ -1280,6 +1302,31 @@ function seq(end, start) {
return o;
}
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
var dnthresh = basedate.getTime() + (new Date().getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
var epoch = v.getTime();
if(date1904) epoch += 1462*24*60*60*1000;
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
}
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
var good_pd = good_pd_date.getFullYear() == 2017;
function parseDate(str/*:string|Date*/)/*:Date*/ {
var d = new Date(str);
if(good_pd) return d;
if(str instanceof Date) return str;
if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
var s = d.getFullYear();
if(str.indexOf("" + s) > -1) return d;
d.setFullYear(d.getFullYear() + 100); return d;
}
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
return new Date(Date.UTC(+n[0], +n[1] - 1, +n[2], +n[3], +n[4], +n[5]));
}
var fixdate = browser ? parseDate("2014-02-19T14:30:00.000Z") : new Date("2014-02-19T14:30Z");
describe('roundtrip features', function() {
var bef = (function() { X = require(modp); });
if(typeof before != 'undefined') before(bef);
@ -1290,8 +1337,8 @@ describe('roundtrip features', function() {
['xlsb', paths.cpxlsb]
].forEach(function(w) {
it(w[0], function() {
var wb1 = X.readFile(w[1]);
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"});
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:TYPE}), {type:TYPE});
coreprop(wb1);
coreprop(wb2);
});
@ -1303,8 +1350,8 @@ describe('roundtrip features', function() {
['xlsb', paths.cpxlsb]
].forEach(function(w) {
it(w[0], function() {
var wb1 = X.readFile(w[1]);
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"});
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:TYPE}), {type:TYPE});
custprop(wb1);
custprop(wb2);
});
@ -1312,7 +1359,7 @@ describe('roundtrip features', function() {
describe('should preserve merge cells', function() {
["xlsx", "xlsb", "xlml", "ods"].forEach(function(f) { it(f, function() {
var wb1 = X.readFile(paths.mcxlsx);
var wb1 = X.read(fs.readFileSync(paths.mcxlsx), {type:TYPE});
var wb2 = X.read(X.write(wb1,{bookType:f,type:'binary'}),{type:'binary'});
var m1 = wb1.Sheets.Merge['!merges'].map(X.utils.encode_range);
var m2 = wb2.Sheets.Merge['!merges'].map(X.utils.encode_range);
@ -1331,7 +1378,7 @@ describe('roundtrip features', function() {
if(dh) { f = paths.dtxlsx; sheet = 'Sheet1'; addr = 'B5'; }
else { f = paths.nfxlsx; sheet = '2011'; addr = 'J36'; }
it('[' + a + '] -> (' + b + ') -> [' + c + '] -> (' + d + ')', function() {
var wb1 = X.readFile(f, {cellNF: true, cellDates: di, WTF: opts.WTF});
var wb1 = X.read(fs.readFileSync(f), {type:TYPE, cellNF: true, cellDates: di, WTF: opts.WTF});
var _f = X.write(wb1, {type:'binary', cellDates:dj, WTF:opts.WTF});
var wb2 = X.read(_f, {type:'binary', cellDates: dk, WTF: opts.WTF});
var m = [wb1,wb2].map(function(x) { return get_cell(x.Sheets[sheet], addr); });
@ -1353,8 +1400,8 @@ describe('roundtrip features', function() {
['ods', paths.fstods]
].forEach(function(w) {
it(w[0], function() {
var wb1 = X.readFile(w[1], {cellFormula:true});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {cellFormula:true, type:"buffer"});
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE, cellFormula:true});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:TYPE}), {cellFormula:true, type:TYPE});
wb1.SheetNames.forEach(function(n) {
assert.equal( X.utils.sheet_to_formulae(wb1.Sheets[n]).sort().join("\n"), X.utils.sheet_to_formulae(wb2.Sheets[n]).sort().join("\n") );
});
@ -1368,8 +1415,8 @@ describe('roundtrip features', function() {
['xlsb', paths.hlxlsb]
].forEach(function(w) {
it(w[0], function() {
var wb1 = X.readFile(w[1]);
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"});
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:TYPE}), {type:TYPE});
hlink(wb1);
hlink(wb2);
});
@ -1381,7 +1428,7 @@ describe('roundtrip features', function() {
['xlsx', paths.pmxlsx],
['xlsb', paths.pmxlsb]
].forEach(function(w) { it(w[0], function() {
var wb1 = X.readFile(w[1]);
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"binary"}), {type:"binary"});
check_margin(wb2.Sheets["Normal"]["!margins"], [0.7, 0.7, 0.75, 0.75, 0.3, 0.3]);
check_margin(wb2.Sheets["Wide"]["!margins"], [1, 1, 1, 1, 0.5, 0.5]);
@ -1397,8 +1444,8 @@ describe('roundtrip features', function() {
['xlsb', paths.svxlsb]
].forEach(function(w) {
it(w[0], function() {
var wb1 = X.readFile(w[1]);
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"});
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:TYPE}), {type:TYPE});
var wbs1 = wb1.Workbook.Sheets;
var wbs2 = wb2.Workbook.Sheets;
assert.equal(wbs1.length, wbs2.length);
@ -1416,7 +1463,7 @@ describe('roundtrip features', function() {
var ws1 = X.utils.aoa_to_sheet([["hpx12", "hpt24", "hpx48", "hidden"]]);
ws1['!cols'] = [{wch:9},{wpx:100},{width:80},{hidden:true}];
var wb1 = {SheetNames:["Sheet1"], Sheets:{Sheet1:ws1}};
var wb2 = X.read(X.write(wb1, {bookType:w, type:"buffer"}), {type:"buffer", cellStyles:true});
var wb2 = X.read(X.write(wb1, {bookType:w, type:TYPE}), {type:TYPE, cellStyles:true});
var ws2 = wb2.Sheets.Sheet1;
assert.equal(ws2['!cols'][3].hidden, true);
assert.equal(ws2['!cols'][0].wch, 9);
@ -1436,7 +1483,7 @@ describe('roundtrip features', function() {
ws1['!rows'] = [{hpx:12},{hpt:24},{hpx:48},{hidden:true}];
for(var i = 0; i <= 7; ++i) ws1['!rows'].push({level:i});
var wb1 = {SheetNames:["Sheet1"], Sheets:{Sheet1:ws1}};
var wb2 = X.read(X.write(wb1, {bookType:w, type:"buffer", cellStyles:true}), {type:"buffer", cellStyles:true});
var wb2 = X.read(X.write(wb1, {bookType:w, type:TYPE, cellStyles:true}), {type:TYPE, cellStyles:true});
var ws2 = wb2.Sheets.Sheet1;
assert.equal(ws2['!rows'][0].hpx, 12);
assert.equal(ws2['!rows'][1].hpt, 24);
@ -1454,8 +1501,8 @@ describe('roundtrip features', function() {
//['ods', paths.cstods]
].forEach(function(w) {
it(w[0], function() {
var wb1 = X.readFile(w[1]);
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"});
var wb1 = X.read(fs.readFileSync(w[1]), {type:TYPE});
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:TYPE}), {type:TYPE});
check_comments(wb1);
check_comments(wb2);
});
@ -1468,7 +1515,7 @@ describe('roundtrip features', function() {
{b:2,c:3},
{b:"a",d:"b"},
{a:true, c:false},
{c:new Date("2017-02-19T14:30Z")}
{c:fixdate}
];
var wb = X.utils.json_to_sheet(data, {cellDates:true});
var out = X.utils.sheet_to_json(wb, {raw:true});
@ -1490,24 +1537,24 @@ describe('invalid files', function() {
['passwords', 'apachepoi_xor-encryption-abc.xls'],
['DOC files', 'word_doc.doc']
].forEach(function(w) { it('should fail on ' + w[0], function() {
assert.throws(function() { X.readFile(dir + w[1]); });
assert.throws(function() { X.read(fs.readFileSync(dir + w[1], {type:TYPE}), {type:TYPE}); });
assert.throws(function() { X.read(fs.readFileSync(dir+w[1], 'base64'), {type:'base64'}); });
}); });
});
describe('write', function() {
it('should pass -> XLSX', function() {
X.write(X.readFile(paths.fstxlsb), {type:'binary'});
X.write(X.readFile(paths.fstxlsx), {type:'binary'});
X.write(X.readFile(paths.fstxls), {type:'binary'});
X.write(X.readFile(paths.fstxml), {type:'binary'});
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});
});
it('should pass if a sheet is missing', function() {
var wb = X.readFile(paths.fstxlsx); delete wb.Sheets[wb.SheetNames[0]];
var wb = X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE}); delete wb.Sheets[wb.SheetNames[0]];
X.read(X.write(wb, {type:'binary'}), {type:'binary'});
});
['Props', 'Custprops', 'SSF'].forEach(function(t) {
it('should pass if ' + t + ' is missing', function() {
var wb = X.readFile(paths.fstxlsx);
var wb = X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE});
assert.doesNotThrow(function() {
delete wb[t];
X.write(wb, {type:'binary'});
@ -1516,7 +1563,7 @@ describe('invalid files', function() {
});
['SheetNames', 'Sheets'].forEach(function(t) {
it('should fail if ' + t + ' is missing', function() {
var wb = X.readFile(paths.fstxlsx);
var wb = X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE});
assert.throws(function() {
delete wb[t];
X.write(wb, {type:'binary'});
@ -1524,7 +1571,7 @@ describe('invalid files', function() {
});
});
it('should fail if SheetNames has duplicate entries', function() {
var wb = X.readFile(paths.fstxlsx);
var wb = X.read(fs.readFileSync(paths.fstxlsx), {type:TYPE});
wb.SheetNames.push(wb.SheetNames[0]);
assert.throws(function() {
X.write(wb, {type:'binary'});
@ -1533,13 +1580,6 @@ describe('invalid files', function() {
});
});
var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
var dnthresh = basedate.getTime() + (new Date().getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
var epoch = v.getTime();
if(date1904) epoch += 1462*24*60*60*1000;
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
}
describe('json output', function() {
function seeker(json, keys, val) {
@ -1554,7 +1594,7 @@ describe('json output', function() {
data = [
[1,2,3],
[true, false, null, "sheetjs"],
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
["foo", "bar", fixdate, "0.3"],
["baz", undefined, "qux"]
];
ws = X.utils.aoa_to_sheet(data);
@ -1646,7 +1686,7 @@ describe('json output', function() {
assert.equal(json[1][0], true);
assert.equal(json[1][2], null);
assert.equal(json[2][1], "bar");
assert.equal(json[2][2].getTime(), new Date("2014-02-19T14:30Z").getTime());
assert.equal(json[2][2].getTime(), fixdate.getTime());
assert.equal(json[3][2], "qux");
});
it('should include __rowNum__', function() {
@ -1736,7 +1776,7 @@ describe('csv', function() {
data = [
[1,2,3,null],
[true, false, null, "sheetjs"],
["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"],
["foo", "bar", fixdate, "0.3"],
[null, null, null],
["baz", undefined, "qux"]
];
@ -1782,7 +1822,9 @@ describe('csv', function() {
});
it('should handle skipHidden for rows if requested', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
delete ws["!rows"];
assert.equal(X.utils.sheet_to_csv(ws), baseline);
assert.equal(X.utils.sheet_to_csv(ws, {skipHidden:true}), baseline);
ws["!rows"] = [null,{hidden:true},null,null];
assert.equal(X.utils.sheet_to_csv(ws), baseline);
assert.equal(X.utils.sheet_to_csv(ws, {skipHidden:true}), "1,2,3,\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n");
@ -1790,7 +1832,9 @@ describe('csv', function() {
});
it('should handle skipHidden for columns if requested', function() {
var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n";
delete ws["!cols"];
assert.equal(X.utils.sheet_to_csv(ws), baseline);
assert.equal(X.utils.sheet_to_csv(ws, {skipHidden:true}), baseline);
ws["!cols"] = [null,{hidden:true},null,null];
assert.equal(X.utils.sheet_to_csv(ws), baseline);
assert.equal(X.utils.sheet_to_csv(ws, {skipHidden:true}), "1,3,\nTRUE,,sheetjs\nfoo,2/19/14,0.3\n,,\nbaz,qux,\n");
@ -1807,7 +1851,7 @@ describe('js -> file -> js', function() {
data = [
[1,2,3],
[true, false, null, "sheetjs"],
["foo","bar",new Date("2014-02-19T14:30Z"), "0.3"],
["foo", "bar", fixdate, "0.3"],
["baz", 6.9, "qux"]
];
ws = X.utils.aoa_to_sheet(data);
@ -1850,7 +1894,7 @@ describe('corner cases', function() {
var data = [
[1,2,3],
[true, false, null, "sheetjs"],
["foo","bar",new Date("2014-02-19T14:30Z"), "0.3"],
["foo", "bar", fixdate, "0.3"],
["baz", null, "q\"ux"]
];
var ws = X.utils.aoa_to_sheet(data);
@ -1864,7 +1908,7 @@ describe('corner cases', function() {
var wb = {SheetNames:['sheetjs'], Sheets:{sheetjs:ws}};
X.write(wb, {type: "binary", bookType: 'xlsx'});
X.write(wb, {type: "buffer", bookType: 'xlsm'});
X.write(wb, {type: TYPE, bookType: 'xlsm'});
X.write(wb, {type: "base64", bookType: 'xlsb'});
X.write(wb, {type: "binary", bookType: 'ods'});
X.write(wb, {type: "binary", bookType: 'biff2'});
@ -1895,17 +1939,17 @@ describe('corner cases', function() {
});
});
it('codepage', function() {
X.readFile(dir + "biff5/number_format_greek.xls");
X.read(fs.readFileSync(dir + "biff5/number_format_greek.xls"), {type:TYPE});
});
});
describe('encryption', function() {
password_files.forEach(function(x) {
describe(x, function() {
it('should throw with no password', function() {assert.throws(function() { X.readFile(dir + x); }); });
it('should throw with no password', function() {assert.throws(function() { X.read(fs.readFileSync(dir + x), {type:TYPE}); }); });
it('should throw with wrong password', function() {
try {
X.readFile(dir + x, {password:'passwor',WTF:opts.WTF});
X.read(fs.readFileSync(dir + x), {type:TYPE,password:'passwor',WTF:opts.WTF});
throw new Error("incorrect password was accepted");
} catch(e) {
if(e.message != "Password is incorrect") throw e;
@ -1913,18 +1957,19 @@ describe('encryption', function() {
});
it('should recognize correct password', function() {
try {
X.readFile(dir + x, {password:'password',WTF:opts.WTF});
X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
} catch(e) {
if(e.message == "Password is incorrect") throw e;
}
});
it.skip('should decrypt file', function() {
var wb = X.readFile(dir + x, {password:'password',WTF:opts.WTF});
var wb = X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF});
});
});
});
});
if(!browser || typeof cptable !== 'undefined')
describe('multiformat tests', function() {
var mfopts = opts;
var mft = fs.readFileSync('multiformat.lst','utf-8').split("\n").map(function(x) { return x.trim(); });
@ -1933,8 +1978,9 @@ mft.forEach(function(x) {
if(x.charAt(0)!="#") describe('MFT ' + x, function() {
var fil = {}, f = [], r = x.split(/\s+/);
if(r.length < 3) return;
if(!fs.existsSync(dir + r[0] + r[1])) return;
it('should parse all', function() {
for(var j = 1; j < r.length; ++j) f[j-1] = X.readFile(dir + r[0] + r[j], mfopts);
for(var j = 1; j < r.length; ++j) f[j-1] = X.read(fs.readFileSync(dir + r[0] + r[j]), mfopts);
});
it('should have the same sheetnames', function() {
cmparr(f.map(function(x) { return x.SheetNames; }));

File diff suppressed because it is too large Load Diff

11
types/index.d.ts vendored
View File

@ -550,13 +550,24 @@ export interface Sheet2CSVOpts {
/** Use specified date format */
dateNF?: NumberFormat;
/** Remove trailing field separators in each record */
strip?: boolean;
/** Include blank lines in the CSV output */
blankrows?: boolean;
/** Skip hidden rows and columns in the CSV output */
skipHidden?: boolean;
}
export interface Sheet2HTMLOpts {
/** Add contenteditable to every cell */
editable?: boolean;
/** Header HTML */
header?: string;
/** Footer HTML */
footer?: string;
}

View File

@ -6,7 +6,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.11.0';
XLSX.version = '0.11.1';
var current_codepage = 1200;
/*:: declare var cptable:any; */
/*global cptable:true */
@ -1496,7 +1496,7 @@ var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
var dnthresh = basedate.getTime() + (new Date().getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
var epoch = v.getTime();
if(date1904) epoch += 1462*24*60*60*1000;
if(date1904) epoch -= 1462*24*60*60*1000;
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
}
function numdate(v/*:number*/)/*:Date*/ {
@ -1648,7 +1648,7 @@ if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(typeof jszip === 'undefined') jszip = require('./jszip.js');
_fs = require('fs');
try { _fs = require('fs'); } catch(e) { }
}
}
@ -3688,8 +3688,8 @@ function parse_VtStringBase(blob, stringType, pad) {
return parse_lpstr(blob, stringType, pad);
}
function parse_VtString(blob, t/*:number*/, pad/*:number*/) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); }
function parse_VtUnalignedString(blob, t/*:number*/) { if(!t) throw new Error("dafuq?"); return parse_VtStringBase(blob, t, 0); }
function parse_VtString(blob, t/*:number*/, pad/*:?boolean*/) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); }
function parse_VtUnalignedString(blob, t/*:number*/) { if(!t) throw new Error("VtUnalignedString must have positive length"); return parse_VtStringBase(blob, t, 0); }
/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
function parse_VtVecUnalignedLpstrValue(blob) {
@ -3783,7 +3783,7 @@ function parse_TypedPropertyValue(blob, type/*:number*/, _opts) {
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw && 4).replace(chr0,'');
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw).replace(chr0,'');
case 0x51 /*VT_USTR*/: return parse_VtUnalignedString(blob, t/*, 4*/).replace(chr0,'');
case 0x100C /*VT_VECTOR|VT_VARIANT*/: return parse_VtVecHeadingPair(blob);
case 0x101E /*VT_LPSTR*/: return parse_VtVecUnalignedLpstr(blob);
@ -6781,13 +6781,37 @@ function parse_FilePassHeader(blob, length/*:number*/, oo) {
return o;
}
function parse_FilePass(blob, length/*:number*/, opts) {
var o = { Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }; /* wEncryptionType */
var o = ({ Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }/*:any*/); /* wEncryptionType */
if(o.Type) parse_FilePassHeader(blob, length-2, o);
else parse_XORObfuscation(blob, length-2, opts, o);
return o;
}
var RTF = (function() {
function rtf_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
switch(opts.type) {
case 'base64': return rtf_to_sheet_str(Base64.decode(d), opts);
case 'binary': return rtf_to_sheet_str(d, opts);
case 'buffer': return rtf_to_sheet_str(d.toString('binary'), opts);
case 'array': return rtf_to_sheet_str(cc2str(d), opts);
}
throw new Error("Unrecognized type " + opts.type);
}
function rtf_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
throw new Error("Unsupported RTF");
}
function rtf_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(rtf_to_sheet(d, opts), opts); }
function sheet_to_rtf() { throw new Error("Unsupported"); }
return {
to_workbook: rtf_to_workbook,
to_sheet: rtf_to_sheet,
from_sheet: sheet_to_rtf
};
})();
function hex2RGB(h) {
var o = h.substr(h[0]==="#"?1:0,6);
return [parseInt(o.substr(0,2),16),parseInt(o.substr(2,2),16),parseInt(o.substr(4,2),16)];
@ -6983,8 +7007,9 @@ function parse_fills(t, styles, themes, opts) {
case '<fills': case '<fills>': case '</fills>': break;
/* 18.8.20 fill CT_Fill */
case '<fill>': case '<fill': break;
case '</fill>': styles.Fills.push(fill); fill = {}; break;
case '<fill>': case '<fill': case '<fill/>':
fill = {}; styles.Fills.push(fill); break;
case '</fill>': break;
/* 18.8.24 gradientFill CT_GradientFill */
case '<gradientFill>': break;
@ -7405,6 +7430,7 @@ var XLSBFillPTNames = [
];
var rev_XLSBFillPTNames/*:EvertNumType*/ = (evert(XLSBFillPTNames)/*:any*/);
/* TODO: gradient fill representation */
var parse_BrtFill = parsenoop;
function write_BrtFill(fill, o) {
if(!o) o = new_buf(4*3 + 8*7 + 16*1);
var fls/*:number*/ = rev_XLSBFillPTNames[fill.patternType];
@ -7467,6 +7493,7 @@ function write_Blxf(data, o) {
return o;
}
/* [MS-XLSB] 2.4.299 BrtBorder TODO */
var parse_BrtBorder = parsenoop;
function write_BrtBorder(border, o) {
if(!o) o = new_buf(51);
o.write_shift(1, 0); /* diagonal */
@ -9106,9 +9133,17 @@ var PtgBinOp = {
PtgPower: "^",
PtgSub: "-"
};
function get_ixti(supbooks, ixti/*:number*/, opts)/*:string*/ {
function formula_quote_sheet_name(sname/*:string*/)/*:string*/ {
if(!sname) return "";
if(sname.indexOf(" ") > -1) return "'" + sname + "'";
return sname;
}
function get_ixti_raw(supbooks, ixti/*:number*/, opts)/*:string*/ {
return supbooks.SheetNames[ixti];
}
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) {
//console.log(formula);
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
@ -10753,7 +10788,7 @@ function get_cell_style(styles, cell, opts) {
return len;
}
function safe_format(p, fmtid/*:number*/, fillid/*:number*/, opts, themes, styles) {
function safe_format(p, fmtid/*:number*/, fillid/*:?number*/, opts, themes, styles) {
if(p.t === 'z') return;
if(p.t === 'd' && typeof p.v === 'string') p.v = parseDate(p.v);
try {
@ -10777,7 +10812,8 @@ function safe_format(p, fmtid/*:number*/, fillid/*:number*/, opts, themes, style
else if(p.t === 'd') p.w = SSF.format(fmtid,datenum(p.v),_ssfopts);
else p.w = SSF.format(fmtid,p.v,_ssfopts);
} catch(e) { if(opts.WTF) throw e; }
if(fillid) try {
if(!opts.cellStyles) return;
if(fillid != null) try {
p.s = styles.Fills[fillid];
if (p.s.fgColor && p.s.fgColor.theme && !p.s.fgColor.rgb) {
p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
@ -10787,7 +10823,7 @@ function safe_format(p, fmtid/*:number*/, fillid/*:number*/, opts, themes, style
p.s.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.bgColor.theme].rgb, p.s.bgColor.tint || 0);
if(opts.WTF) p.s.bgColor.raw_rgb = themes.themeElements.clrScheme[p.s.bgColor.theme].rgb;
}
} catch(e) { if(opts.WTF) throw e; }
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
}
function parse_ws_xml_dim(ws, s) {
var d = safe_decode_range(s);
@ -13822,12 +13858,14 @@ function parse_xlml_xml(d, _opts)/*:Workbook*/ {
return out;
}
function parse_xlml(data/*:RawBytes*/, opts)/*:Workbook*/ {
function arr2str(data/*:any*/)/*:string*/ { return data.map(_chr).join(""); }
function parse_xlml(data/*:RawBytes|string*/, opts)/*:Workbook*/ {
fix_read_opts(opts=opts||{});
switch(opts.type||"base64") {
case "base64": return parse_xlml_xml(Base64.decode(data), opts);
case "binary": case "buffer": case "file": return parse_xlml_xml(data, opts);
case "array": return parse_xlml_xml(data.map(_chr).join(""), opts);
case "array": return parse_xlml_xml(arr2str(data), opts);
}
/*:: throw new Error("unsupported type " + opts.type); */
}
@ -14989,8 +15027,8 @@ var XLSBRecordEnum = {
/*::[*/0x002A/*::]*/: { n:"BrtIndexBlock", f:parsenoop },
/*::[*/0x002B/*::]*/: { n:"BrtFont", f:parse_BrtFont },
/*::[*/0x002C/*::]*/: { n:"BrtFmt", f:parse_BrtFmt },
/*::[*/0x002D/*::]*/: { n:"BrtFill", f:parsenoop },
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parsenoop },
/*::[*/0x002D/*::]*/: { n:"BrtFill", f:parse_BrtFill },
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parse_BrtBorder },
/*::[*/0x002F/*::]*/: { n:"BrtXF", f:parse_BrtXF },
/*::[*/0x0030/*::]*/: { n:"BrtStyle", f:parsenoop },
/*::[*/0x0031/*::]*/: { n:"BrtCellMeta", f:parsenoop },
@ -16315,10 +16353,10 @@ var HTML_ = (function() {
var opts = _opts || {};
if(DENSE != null && opts.dense == null) opts.dense = DENSE;
var ws/*:Worksheet*/ = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
var mtch = str.match(/<table/i);
var mtch/*:any*/ = str.match(/<table/i);
if(!mtch) throw new Error("Invalid HTML: could not find <table>");
var mtch2 = str.match(/<\/table/i);
var i = mtch.index, j = mtch2 && mtch2.index || str.length;
var mtch2/*:any*/ = str.match(/<\/table/i);
var i/*:number*/ = mtch.index, j/*:number*/ = mtch2 && mtch2.index || str.length;
var rows = str.slice(i, j).split(/(:?<tr[^>]*>)/i);
var R = -1, C = 0, RS = 0, CS = 0;
var range = {s:{r:10000000, c:10000000},e:{r:0,c:0}};
@ -17150,6 +17188,7 @@ var write_csv_str = write_obj_str({from_sheet:sheet_to_csv});
var write_slk_str = write_obj_str(SYLK);
var write_dif_str = write_obj_str(DIF);
var write_prn_str = write_obj_str(PRN);
var write_rtf_str = write_obj_str(RTF);
var write_txt_str = write_obj_str({from_sheet:sheet_to_txt});
function fix_opts_func(defaults/*:Array<Array<any> >*/)/*:{(o:any):void}*/ {
return function fix_opts(opts) {
@ -17608,7 +17647,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
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);
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) throw new Error("Unsupported RTF"); break;
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) return RTF.to_workbook(d, o); break;
case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
}
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
@ -17691,6 +17730,7 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
case 'csv': return write_string_type(write_csv_str(wb, o), o);
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': return write_binary_type(write_biff_buf(wb, o), o);
case 'xlsx':
@ -17717,6 +17757,7 @@ function resolve_book_type(o/*?WriteFileOpts*/) {
case '.txt': o.bookType = 'txt'; break;
case '.dif': o.bookType = 'dif'; break;
case '.prn': o.bookType = 'prn'; break;
case '.rtf': o.bookType = 'rtf'; break;
case '.slk': o.bookType = 'sylk'; break;
case '.htm': o.bookType = 'html'; break;
}
@ -17851,11 +17892,11 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row = "", cols = [];
o.dense = Array.isArray(sheet);
var colInfos = o.skipHidden ? sheet["!cols"] : undefined;
var rowInfos = o.skipHidden ? sheet["!rows"] : undefined;
for(var C = r.s.c; C <= r.e.c; ++C) if (!colInfos || !colInfos[C] || !colInfos[C].hidden) cols[C] = encode_col(C);
var colInfos = o.skipHidden && sheet["!cols"] || [];
var rowInfos = o.skipHidden && sheet["!rows"] || [];
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
for(var R = r.s.r; R <= r.e.r; ++R) {
if (rowInfos && rowInfos[R] && rowInfos[R].hidden) continue;
if ((rowInfos[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
if(row == null) { continue; }
if(o.strip) row = row.replace(endregex,"");
@ -18084,13 +18125,16 @@ if(has_buf && typeof require != 'undefined') (function() {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row/*:?string*/ = "", cols = [];
o.dense = Array.isArray(sheet);
for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
var colInfos = o.skipHidden && sheet["!cols"] || [];
var rowInfos = o.skipHidden && sheet["!rows"] || [];
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
var R = r.s.r;
stream._read = function() {
if(R > r.e.r) return stream.push(null);
while(R <= r.e.r) {
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
++R;
if ((rowInfos[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
if(row != null) {
if(o.strip) row = row.replace(endregex,"");
stream.push(row + RS);

86
xlsx.js
View File

@ -6,7 +6,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.11.0';
XLSX.version = '0.11.1';
var current_codepage = 1200;
/*global cptable:true */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
@ -1434,7 +1434,7 @@ var basedate = new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
var dnthresh = basedate.getTime() + (new Date().getTimezoneOffset() - basedate.getTimezoneOffset()) * 60000;
function datenum(v, date1904) {
var epoch = v.getTime();
if(date1904) epoch += 1462*24*60*60*1000;
if(date1904) epoch -= 1462*24*60*60*1000;
return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
}
function numdate(v) {
@ -1584,7 +1584,7 @@ if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(typeof jszip === 'undefined') jszip = require('./jszip.js');
_fs = require('fs');
try { _fs = require('fs'); } catch(e) { }
}
}
@ -3615,7 +3615,7 @@ function parse_VtStringBase(blob, stringType, pad) {
}
function parse_VtString(blob, t, pad) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); }
function parse_VtUnalignedString(blob, t) { if(!t) throw new Error("dafuq?"); return parse_VtStringBase(blob, t, 0); }
function parse_VtUnalignedString(blob, t) { if(!t) throw new Error("VtUnalignedString must have positive length"); return parse_VtStringBase(blob, t, 0); }
/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
function parse_VtVecUnalignedLpstrValue(blob) {
@ -3709,7 +3709,7 @@ function parse_TypedPropertyValue(blob, type, _opts) {
case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw && 4).replace(chr0,'');
case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw).replace(chr0,'');
case 0x51 /*VT_USTR*/: return parse_VtUnalignedString(blob, t/*, 4*/).replace(chr0,'');
case 0x100C /*VT_VECTOR|VT_VARIANT*/: return parse_VtVecHeadingPair(blob);
case 0x101E /*VT_LPSTR*/: return parse_VtVecUnalignedLpstr(blob);
@ -6706,13 +6706,37 @@ function parse_FilePassHeader(blob, length, oo) {
return o;
}
function parse_FilePass(blob, length, opts) {
var o = { Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }; /* wEncryptionType */
var o = ({ Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }); /* wEncryptionType */
if(o.Type) parse_FilePassHeader(blob, length-2, o);
else parse_XORObfuscation(blob, length-2, opts, o);
return o;
}
var RTF = (function() {
function rtf_to_sheet(d, opts) {
switch(opts.type) {
case 'base64': return rtf_to_sheet_str(Base64.decode(d), opts);
case 'binary': return rtf_to_sheet_str(d, opts);
case 'buffer': return rtf_to_sheet_str(d.toString('binary'), opts);
case 'array': return rtf_to_sheet_str(cc2str(d), opts);
}
throw new Error("Unrecognized type " + opts.type);
}
function rtf_to_sheet_str(str, opts) {
throw new Error("Unsupported RTF");
}
function rtf_to_workbook(d, opts) { return sheet_to_workbook(rtf_to_sheet(d, opts), opts); }
function sheet_to_rtf() { throw new Error("Unsupported"); }
return {
to_workbook: rtf_to_workbook,
to_sheet: rtf_to_sheet,
from_sheet: sheet_to_rtf
};
})();
function hex2RGB(h) {
var o = h.substr(h[0]==="#"?1:0,6);
return [parseInt(o.substr(0,2),16),parseInt(o.substr(2,2),16),parseInt(o.substr(4,2),16)];
@ -6908,8 +6932,9 @@ function parse_fills(t, styles, themes, opts) {
case '<fills': case '<fills>': case '</fills>': break;
/* 18.8.20 fill CT_Fill */
case '<fill>': case '<fill': break;
case '</fill>': styles.Fills.push(fill); fill = {}; break;
case '<fill>': case '<fill': case '<fill/>':
fill = {}; styles.Fills.push(fill); break;
case '</fill>': break;
/* 18.8.24 gradientFill CT_GradientFill */
case '<gradientFill>': break;
@ -7330,6 +7355,7 @@ var XLSBFillPTNames = [
];
var rev_XLSBFillPTNames = (evert(XLSBFillPTNames));
/* TODO: gradient fill representation */
var parse_BrtFill = parsenoop;
function write_BrtFill(fill, o) {
if(!o) o = new_buf(4*3 + 8*7 + 16*1);
var fls = rev_XLSBFillPTNames[fill.patternType];
@ -7392,6 +7418,7 @@ function write_Blxf(data, o) {
return o;
}
/* [MS-XLSB] 2.4.299 BrtBorder TODO */
var parse_BrtBorder = parsenoop;
function write_BrtBorder(border, o) {
if(!o) o = new_buf(51);
o.write_shift(1, 0); /* diagonal */
@ -9028,9 +9055,17 @@ var PtgBinOp = {
PtgPower: "^",
PtgSub: "-"
};
function get_ixti(supbooks, ixti, opts) {
function formula_quote_sheet_name(sname) {
if(!sname) return "";
if(sname.indexOf(" ") > -1) return "'" + sname + "'";
return sname;
}
function get_ixti_raw(supbooks, ixti, opts) {
return supbooks.SheetNames[ixti];
}
function get_ixti(supbooks, ixti, opts) {
return formula_quote_sheet_name(get_ixti_raw(supbooks, ixti, opts));
}
function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
//console.log(formula);
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
@ -10699,7 +10734,8 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
else if(p.t === 'd') p.w = SSF.format(fmtid,datenum(p.v),_ssfopts);
else p.w = SSF.format(fmtid,p.v,_ssfopts);
} catch(e) { if(opts.WTF) throw e; }
if(fillid) try {
if(!opts.cellStyles) return;
if(fillid != null) try {
p.s = styles.Fills[fillid];
if (p.s.fgColor && p.s.fgColor.theme && !p.s.fgColor.rgb) {
p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
@ -10709,7 +10745,7 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
p.s.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.bgColor.theme].rgb, p.s.bgColor.tint || 0);
if(opts.WTF) p.s.bgColor.raw_rgb = themes.themeElements.clrScheme[p.s.bgColor.theme].rgb;
}
} catch(e) { if(opts.WTF) throw e; }
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
}
function parse_ws_xml_dim(ws, s) {
var d = safe_decode_range(s);
@ -13738,12 +13774,14 @@ Workbook.WBProps.date1904 = true;
return out;
}
function arr2str(data) { return data.map(_chr).join(""); }
function parse_xlml(data, opts) {
fix_read_opts(opts=opts||{});
switch(opts.type||"base64") {
case "base64": return parse_xlml_xml(Base64.decode(data), opts);
case "binary": case "buffer": case "file": return parse_xlml_xml(data, opts);
case "array": return parse_xlml_xml(data.map(_chr).join(""), opts);
case "array": return parse_xlml_xml(arr2str(data), opts);
}
}
@ -14903,8 +14941,8 @@ var XLSBRecordEnum = {
0x002A: { n:"BrtIndexBlock", f:parsenoop },
0x002B: { n:"BrtFont", f:parse_BrtFont },
0x002C: { n:"BrtFmt", f:parse_BrtFmt },
0x002D: { n:"BrtFill", f:parsenoop },
0x002E: { n:"BrtBorder", f:parsenoop },
0x002D: { n:"BrtFill", f:parse_BrtFill },
0x002E: { n:"BrtBorder", f:parse_BrtBorder },
0x002F: { n:"BrtXF", f:parse_BrtXF },
0x0030: { n:"BrtStyle", f:parsenoop },
0x0031: { n:"BrtCellMeta", f:parsenoop },
@ -17063,6 +17101,7 @@ var write_csv_str = write_obj_str({from_sheet:sheet_to_csv});
var write_slk_str = write_obj_str(SYLK);
var write_dif_str = write_obj_str(DIF);
var write_prn_str = write_obj_str(PRN);
var write_rtf_str = write_obj_str(RTF);
var write_txt_str = write_obj_str({from_sheet:sheet_to_txt});
function fix_opts_func(defaults) {
return function fix_opts(opts) {
@ -17518,7 +17557,7 @@ function readSync(data, opts) {
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);
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) throw new Error("Unsupported RTF"); break;
case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) return RTF.to_workbook(d, o); break;
case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
}
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
@ -17601,6 +17640,7 @@ function writeSync(wb, opts) {
case 'csv': return write_string_type(write_csv_str(wb, o), o);
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': return write_binary_type(write_biff_buf(wb, o), o);
case 'xlsx':
@ -17627,6 +17667,7 @@ function resolve_book_type(o/*?WriteFileOpts*/) {
case '.txt': o.bookType = 'txt'; break;
case '.dif': o.bookType = 'dif'; break;
case '.prn': o.bookType = 'prn'; break;
case '.rtf': o.bookType = 'rtf'; break;
case '.slk': o.bookType = 'sylk'; break;
case '.htm': o.bookType = 'html'; break;
}
@ -17761,11 +17802,11 @@ function sheet_to_csv(sheet, opts) {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row = "", cols = [];
o.dense = Array.isArray(sheet);
var colInfos = o.skipHidden ? sheet["!cols"] : undefined;
var rowInfos = o.skipHidden ? sheet["!rows"] : undefined;
for(var C = r.s.c; C <= r.e.c; ++C) if (!colInfos || !colInfos[C] || !colInfos[C].hidden) cols[C] = encode_col(C);
var colInfos = o.skipHidden && sheet["!cols"] || [];
var rowInfos = o.skipHidden && sheet["!rows"] || [];
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
for(var R = r.s.r; R <= r.e.r; ++R) {
if (rowInfos && rowInfos[R] && rowInfos[R].hidden) continue;
if ((rowInfos[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
if(row == null) { continue; }
if(o.strip) row = row.replace(endregex,"");
@ -17994,13 +18035,16 @@ if(has_buf && typeof require != 'undefined') (function() {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row = "", cols = [];
o.dense = Array.isArray(sheet);
for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
var colInfos = o.skipHidden && sheet["!cols"] || [];
var rowInfos = o.skipHidden && sheet["!rows"] || [];
for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
var R = r.s.r;
stream._read = function() {
if(R > r.e.r) return stream.push(null);
while(R <= r.e.r) {
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
++R;
if ((rowInfos[R-1]||{}).hidden) continue;
row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
if(row != null) {
if(o.strip) row = row.replace(endregex,"");
stream.push(row + RS);