version bump 0.7.8: docs, defaults, details

- browser shim updated (h/t @wintersm for discovering this)
- smart tag ignores (h/t @lostinplace)
- sheet_to_row_object_array bugfix (fixes #80, h/t @ChrisBurkeBSD)
- README improved
- baltic and vietnamese codepages: updated codepage to 1.3.4
- iOS Numbers can handle inline strings -> disabling SST by default
- avoid Buffer accessors (see https://github.com/joyent/node/issues/7809)
- caching certain hot regexes
This commit is contained in:
SheetJS 2014-07-28 09:22:32 -04:00
parent 19c22fa34a
commit d4999ac421
39 changed files with 990 additions and 418 deletions

4
.gitignore vendored
View File

@ -1,4 +1,8 @@
node_modules
misc/coverage.html
misc/prof.js
v8.log
tmp
*.xlsx
*.xlsm
*.xlsb

View File

@ -4,4 +4,20 @@ index.html
misc/
node_modules
tmp
*.xls
*.xlsb
*.xlsm
*.xlsx
*.xml
.gitignore
.jshintrc
CONTRIBUTING.md
Makefile
tests.lst
.npmignore
xlsworker.js
shim.js
test.js
.jscs.json
.gitmodules
.travis.yml

160
README.md
View File

@ -90,7 +90,7 @@ oReq.onload = function(e) {
oReq.send();
```
- html5 drag-and-drop using readAsBinaryString:
- HTML5 drag-and-drop using readAsBinaryString:
```
/* set up drag-and-drop event */
@ -106,7 +106,7 @@ function handleDrop(e) {
var data = e.target.result;
/* if binary string, read with type 'binary' */
var wb = XLSX.read(data, {type: 'binary'});
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
@ -116,6 +116,28 @@ function handleDrop(e) {
drop_dom_element.addEventListener('drop', handleDrop, false);
```
- HTML5 input file element using readAsBinaryString:
```
function handleFile(e) {
var files = e.target.files;
var i,f;
for (i = 0, f = files[i]; i != files.length; ++i) {
var reader = new FileReader();
var name = f.name;
reader.onload = function(e) {
var data = e.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
/* DO SOMETHING WITH workbook HERE */
};
reader.readAsBinaryString(f);
}
}
input_dom_element.addEventListener('change', handleFile, false);
```
This example walks through every cell of every sheet and dumps the values:
```
@ -150,7 +172,7 @@ Some helper functions in `XLSX.utils` generate different views of the sheets:
- `XLSX.utils.sheet_to_csv` generates CSV
- `XLSX.utils.sheet_to_json` generates an array of objects
- `XLSX.utils.get_formulae` generates a list of formulae
- `XLSX.utils.sheet_to_formulae` generates a list of formulae
## Writing Workbooks
@ -167,7 +189,7 @@ XLSX.writeFile(workbook, 'out.xlsx');
```
/* bookType can be 'xlsx' or 'xlsm' or 'xlsb' */
var wopts = { bookType:'xlsx', bookSST:true, type:'binary' };
var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
var wbout = XLSX.write(workbook,wopts);
@ -185,44 +207,127 @@ Complete examples:
- <http://sheetjs.com/demos/writexlsx.html> generates a simple file
- <http://git.io/WEK88Q> writing an array of arrays in nodejs
- <http://sheetjs.com/demos/table.html> exporting an HTML table
## Interface
`XLSX` is the exposed variable in the browser and the exported nodejs variable
`XLSX.version` is the version of the library (added by the build script).
`XLSX.SSF` is an embedded version of the [format library](http://git.io/ssf).
### Parsing functions
`XLSX.read(data, read_opts)` attempts to parse `data`.
`XLSX.readFile(filename, read_opts)` attempts to read `filename` and parse.
### Writing functions
`XLSX.write(wb, write_opts)` attempts to write the workbook `wb`
`XLSX.writeFile(wb, filename, write_opts)` attempts to write `wb` to `filename`
## Cell Object Description
### Utilities
Utilities are available in the `XLSX.utils` object:
Exporting:
- `sheet_to_json` converts a workbook object to an array of JSON objects.
- `sheet_to_csv` generates delimiter-separated-values output
- `sheet_to_formulae` generates a list of the formulae (with value fallbacks)
Cell and cell address manipulation:
- `format_cell` generates the text value for a cell (using number formats)
- `{en,de}code_{row,col}` convert between 0-indexed rows/cols and A1 forms.
- `{en,de}code_cell` converts cell addresses
- `{en,de}code_range` converts cell ranges
## Workbook / Worksheet / Cell Object Description
js-xlsx conforms to the Common Spreadsheet Format (CSF):
`.SheetNames` is an ordered list of the sheets in the workbook
### General Structures
`.Sheets[sheetname]` returns a data structure representing the sheet. Each key
that does not start with `!` corresponds to a cell (using `A-1` notation).
Cell address objects are stored as `{c:C, r:R}` where `C` and `R` are 0-indexed
column and row numbers, respectively. For example, the cell address `B5` is
represented by the object `{c:1, r:4}`.
`.Sheets[sheetname][address]` returns the specified cell:
Cell range objects are stored as `{s:S, e:E}` where `S` is the first cell and
`E` is the last cell in the range. The ranges are inclusive. For example, the
range `A3:B7` is represented by the object `{s:{c:0, r:2}, e:{c:1, r:6}}`. Utils
use the following pattern to walk each of the cells in a range:
- `.v` : the raw value of the cell
- `.w` : the formatted text of the cell (if applicable)
- `.t` : the type of the cell (constrained to the enumeration `ST_CellType` as
documented in page 4215 of ISO/IEC 29500-1:2012(E) )
- `.f` : the formula of the cell (if applicable)
- `.r` : the rich text encoding of a cell text (if applicable)
- `.h` : an HTML rendering of the rich text (if applicable)
- `.c` : comments associated with the cell
- `.z` : the number format string associated with the cell (if requested)
- `.l` : the hyperlink of the cell (.Target holds link, .tooltip is tooltip)
- `.s` : the style/theme of the cell (if applicable)
```
for(var R = range.s.r; R <= range.e.r; ++R) {
for(var C = range.s.c; C <= range.e.c; ++C) {
var cell_address = {c:C, r:R};
}
}
```
### Cell Object
| Key | Description |
| --- | ----------- |
| `v` | raw value ** |
| `w` | formatted text (if applicable) |
| `t` | cell type: `b` Boolean, `n` Number, `e` error, `s/str` String |
| `f` | cell formula (if applicable) |
| `r` | rich text encoding (if applicable) |
| `h` | HTML rendering of the rich text (if applicable) |
| `c` | comments associated with the cell ** |
| `z` | number format string associated with the cell (if requested) |
| `l` | cell hyperlink object (.Target holds link, .tooltip is tooltip) |
| `s` | the style/theme of the cell (if applicable) |
- For dates, `.v` holds the raw date code from the sheet and `.w` holds the text
Built-in export utilities (such as the CSV exporter) will use the `w` text if it
is available. To change a value, be sure to delete `cell.w` (or set it to
`undefined`) before attempting to export. The utilities will regenerate the `w`
text from the number format (`cell.z`) and the raw value if possible.
### Worksheet Object
Each key that does not start with `!` maps to a cell (using `A-1` notation)
`worksheet[address]` returns the cell object for the specified address.
Special worksheet keys (accessible as `worksheet[key]`, each starting with `!`):
- `ws['!ref']`: A-1 based range representing the worksheet range. Functions that
work with sheets should use this parameter to determine the range. Cells that
are assigned outside of the range are not processed. In particular, when
writing a worksheet by hand, be sure to update the range. For a longer
discussion, see <http://git.io/KIaNKQ>
When reading a worksheet with the `sheetRows` property set, the ref parameter
will use the restricted range. The original range is set at `ws['!fullref']`
- `ws['!cols']`: array of column properties objects. Column widths are actually
stored in files in a normalized manner, measured in terms of the "Maximum
Digit Width" (the largest width of the rendered digits 0-9, in pixels). When
parsed, the column objects store the pixel width in the `wpx` field, character
width in the `wch` field, and the maximum digit width in the `MDW` field.
- `ws['!merges']`: array of range objects corresponding to the merged cells in
the worksheet. Plaintext utilities are unaware of merge cells. CSV export
will write all cells in the merge range if they exist, so be sure that only
the first cell (upper-left) in the range is set.
### Workbook Object
`workbook.SheetNames` is an ordered list of the sheets in the workbook
`wb.Sheets[sheetname]` returns an object representing the worksheet.
`wb.Props` is an object storing the standard properties. `wb.Custprops` stores
custom properties.
For dates, `.v` holds the raw date code from the sheet and `.w` holds the text
## Parsing Options
@ -264,7 +369,7 @@ The exported `write` and `writeFile` functions accept an options argument:
| bookType | 'xlsx' | Type of Workbook ("xlsx" or "xlsm" or "xlsb") |
- `bookSST` is slower and more memory intensive, but has better compatibility
with iOS Numbers
with older versions of iOS Numbers
- `bookType = 'xlsb'` is stubbed and far from complete
- The raw data is the only thing guaranteed to be saved. Formulae, formatting,
and other niceties may not be serialized (pending CSF standardization)
@ -308,6 +413,17 @@ For a much smaller test, run `make test_misc`.
Due to the precarious nature of the Open Specifications Promise, it is very
important to ensure code is cleanroom. Consult CONTRIBUTING.md
The xlsx.js file is constructed from the files in the `bits` subdirectory. The
build script (run `make`) will concatenate the individual bits to produce the
script. Before submitting a contribution, ensure that running make will produce
the xlsx.js file exactly. The simplest way to test is to move the script:
```
$ mv xlsx.js xlsx.new.js
$ make
$ diff xlsx.js xlsx.new.js
```
## XLS Support
XLS is available in [js-xls](http://git.io/xls).

View File

@ -20,7 +20,7 @@ program
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
.option('-n, --sheet-rows <num>', 'Number of rows to process (0=all rows)')
.option('--no-sst', 'do not generate sst')
.option('--sst', 'generate sst')
.option('--perf', 'do not generate output')
.option('--all', 'parse everything; XLS[XMB] write as much as possible')
.option('--dev', 'development mode')
@ -109,7 +109,7 @@ try {
if(program.perf) return;
var oo = "";
var oo = "";
if(!program.quiet) console.error(target_sheet);
if(program.formulae) oo = X.utils.get_formulae(ws).join("\n");
else if(program.json) oo = JSON.stringify(X.utils.sheet_to_row_object_array(ws));

View File

@ -1 +1 @@
XLSX.version = '0.7.7';
XLSX.version = '0.7.8';

View File

@ -4,12 +4,15 @@ if(typeof module !== "undefined" && typeof require !== 'undefined') {
current_cptable = cptable[current_codepage];
}
function reset_cp() { set_cp(1252); }
function set_cp(cp) { current_codepage = cp; if(typeof cptable !== 'undefined') current_cptable = cptable[cp]; }
var set_cp = function(cp) { current_codepage = cp; };
function char_codes(data) { var o = []; for(var i = 0; i != data.length; ++i) o[i] = data.charCodeAt(i); return o; }
function debom_xml(data) {
if(typeof cptable !== 'undefined') {
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
var debom_xml = function(data) { return data; };
if(typeof cptable !== 'undefined') {
set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
debom_xml = function(data) {
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
}
return data;
return data;
};
}

View File

@ -41,3 +41,5 @@ function cc2str(arr) {
for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]);
return o;
}
var has_buf = (typeof Buffer !== 'undefined');

View File

@ -2,11 +2,11 @@ function getdata(data) {
if(!data) return null;
if(data.name.substr(-4) === ".bin") {
if(data.data) return char_codes(data.data);
if(data.asNodeBuffer && typeof Buffer !== 'undefined') return data.asNodeBuffer();
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
} else {
if(data.data) return data.name.substr(-4) !== ".bin" ? debom_xml(data.data) : char_codes(data.data);
if(data.asNodeBuffer && typeof Buffer !== 'undefined') return debom_xml(data.asNodeBuffer().toString('binary'));
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
if(data.asBinary) return debom_xml(data.asBinary());
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
}
@ -30,8 +30,8 @@ var _fs, jszip;
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(typeof Buffer !== 'undefined' && typeof jszip === 'undefined') jszip = require('jszip');
if(typeof jszip === 'undefined') jszip = require('./jszip').JSZip;
_fs = require('fs');
if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
_fs = require('f'+'s');
}
}

View File

@ -1,4 +1,3 @@
var _chr = function(c) { return String.fromCharCode(c); };
var attregexg=/\b[\w:]+=["'][^"]*['"]/g;
var tagregex=/<[^>]*>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
@ -32,10 +31,10 @@ var rencoding = evert(encodings);
var rencstr = "&<>'\"".split("");
// TODO: CP remap (need to read file version to determine OS)
var encregex = /&[a-z]*;/g, coderegex = /_x([0-9a-fA-F]+)_/g;
var encregex = /&[a-z]*;/g, coderegex = /_x([\da-fA-F]+)_/g;
function unescapexml(text){
var s = text + '';
return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return _chr(parseInt(c,16));});
return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
}
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
function escapexml(text){
@ -69,7 +68,7 @@ var utf8read = function utf8reada(orig) {
};
if(typeof Buffer !== "undefined") {
if(has_buf) {
var utf8readb = function utf8readb(data) {
var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
for(i = 0; i < data.length; i+=j) {

View File

@ -17,38 +17,37 @@ function readIEEE754(buf, idx, isLE, nl, ml) {
}
var __toBuffer, ___toBuffer;
__toBuffer = ___toBuffer = function(bufs) {
var x = [];
for(var i = 0; i != bufs[0].length; ++i) { x = x.concat(bufs[0][i]); }
return x;
};
if(typeof Buffer !== "undefined") {
__toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
var __double, ___double;
__double = ___double = function(b, idx) { return readIEEE754(b, idx);};
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
if(has_buf) {
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
__double = function double_(b,i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
}
var ___readUInt32LE = function(b, idx) { return b.readUInt32LE ? b.readUInt32LE(idx) : b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var ___readInt32LE = function(b, idx) { return (b[idx+3]<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var __readUInt8 = function(b, idx) { return b.readUInt8 ? b.readUInt8(idx) : b[idx]; };
var __readUInt16LE = function(b, idx) { return b.readUInt16LE ? b.readUInt16LE(idx) : b[idx+1]*(1<<8)+b[idx]; };
var __readInt16LE = function(b, idx) { var u = __readUInt16LE(b,idx); if(!(u & 0x8000)) return u; return (0xffff - u + 1) * -1; };
var __readUInt32LE = typeof Buffer !== "undefined" ? function(b, i) { return Buffer.isBuffer(b) ? b.readUInt32LE(i) : ___readUInt32LE(b,i); } : ___readUInt32LE;
var __readInt32LE = typeof Buffer !== "undefined" ? function(b, i) { return Buffer.isBuffer(b) ? b.readInt32LE(i) : ___readInt32LE(b,i); } : ___readInt32LE;
var __readDoubleLE = function(b, idx) { return b.readDoubleLE ? b.readDoubleLE(idx) : readIEEE754(b, idx||0);};
var __readUInt8 = function(b, idx) { return b[idx]; };
var __readUInt16LE = function(b, idx) { return b[idx+1]*(1<<8)+b[idx]; };
var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
function ReadShift(size, t) {
var o="", oo=[], w, vv, i, loc;
if(t === 'dbcs') {
loc = this.l;
if(typeof Buffer !== 'undefined' && this instanceof Buffer) o = this.slice(this.l, this.l+2*size).toString("utf16le");
if(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString("utf16le");
else for(i = 0; i != size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; }
size *= 2;
} else switch(size) {
case 1: o = __readUInt8(this, this.l); break;
case 2: o = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); break;
case 4: o = __readUInt32LE(this, this.l); break;
case 8: if(t === 'f') { o = __readDoubleLE(this, this.l); break; }
case 8: if(t === 'f') { o = __double(this, this.l); break; }
}
this.l+=size; return o;
}
@ -59,7 +58,8 @@ function WriteShift(t, val, f) {
for(i = 0; i != val.length; ++i) this.writeUInt16LE(val.charCodeAt(i), this.l + 2 * i);
size = 2 * val.length;
} else switch(t) {
case 1: size = 1; this.writeUInt8(val, this.l); break;
case 1: size = 1; this[this.l] = val&255; break;
case 3: size = 3; this[this.l+2] = val & 255; val >>>= 8; this[this.l+1] = val&255; val >>>= 8; this[this.l] = val&255; break;
case 4: size = 4; this.writeUInt32LE(val, this.l); break;
case 8: size = 8; if(f === 'f') { this.writeDoubleLE(val, this.l); break; }
/* falls through */
@ -70,7 +70,7 @@ function WriteShift(t, val, f) {
}
function prep_blob(blob, pos) {
blob.l = pos || 0;
blob.l = pos;
blob.read_shift = ReadShift;
blob.write_shift = WriteShift;
}
@ -80,9 +80,8 @@ function parsenoop(blob, length) { blob.l += length; }
function writenoop(blob, length) { blob.l += length; }
function new_buf(sz) {
var o = typeof Buffer !== 'undefined' ? new Buffer(sz) : new Array(sz);
var o = has_buf ? new Buffer(sz) : new Array(sz);
prep_blob(o, 0);
return o;
}
function is_buf(a) { return (typeof Buffer !== 'undefined' && a instanceof Buffer) || Array.isArray(a); }

View File

@ -24,6 +24,13 @@ function parse_RichStr(data, length) {
data.l = start + length;
return z;
}
function write_RichStr(str, o) {
/* TODO: formatted string */
if(o == null) o = new_buf(5+2*str.t.length);
o.write_shift(1,0);
write_XLWideString(str.t, o);
return o;
}
/* [MS-XLSB] 2.5.9 */
function parse_Cell(data) {
@ -33,6 +40,14 @@ function parse_Cell(data) {
var fPhShow = data.read_shift(1);
return { c:col, iStyleRef: iStyleRef };
}
function write_Cell(cell, o) {
if(o == null) o = new_buf(8);
o.write_shift(-4, cell.c);
o.write_shift(3, cell.iStyleRef === undefined ? cell.iStyleRef : cell.s);
o.write_shift(1, 0); /* fPhShow */
return o;
}
/* [MS-XLSB] 2.5.21 */
function parse_CodeName (data, length) { return parse_XLWideString(data, length); }
@ -55,7 +70,7 @@ function parse_XLWideString(data) {
return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
}
function write_XLWideString(data, o) {
if(o == null) o = new_buf(127);
if(o == null) o = new_buf(4+2*data.length);
o.write_shift(4, data.length);
if(data.length > 0) o.write_shift(0, data, 'dbcs');
return o;
@ -72,7 +87,7 @@ function parse_RkNumber(data) {
var fX100 = b[0] & 1, fInt = b[0] & 2;
data.l+=4;
b[0] &= 0xFC;
var RK = fInt === 0 ? __readDoubleLE([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
var RK = fInt === 0 ? __double([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
return fX100 ? RK/100 : RK;
}

View File

@ -21,14 +21,21 @@ var CORE_PROPS = [
XMLNS.CORE_PROPS = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
RELS.CORE_PROPS = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties';
var CORE_PROPS_REGEX = (function() {
var r = new Array(CORE_PROPS.length);
for(var i = 0; i < CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i];
var g = "(?:"+ f[0].substr(0,f[0].indexOf(":")) +":)"+ f[0].substr(f[0].indexOf(":")+1);
r[i] = new RegExp("<" + g + "[^>]*>(.*)<\/" + g + ">");
}
return r;
})();
function parse_core_props(data) {
var p = {};
for(var i = 0; i != CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i];
var g = "(?:"+ f[0].substr(0,f[0].indexOf(":")) +":)"+ f[0].substr(f[0].indexOf(":")+1);
var cur = data.match(new RegExp("<" + g + "[^>]*>(.*)<\/" + g + ">"));
for(var i = 0; i < CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i], cur = data.match(CORE_PROPS_REGEX[i]);
if(cur != null && cur.length > 0) p[f[1]] = cur[1];
if(f[2] === 'date' && p[f[1]]) p[f[1]] = new Date(p[f[1]]);
}
@ -47,7 +54,6 @@ var CORE_PROPS_XML_ROOT = writextag('cp:coreProperties', null, {
function cp_doit(f, g, h, o, p) {
if(p[f] != null || g == null || g === "") return;
if(typeof g !== 'string') g = String(g); /* TODO: remove */
p[f] = g;
o[o.length] = (h ? writextag(f,g,h) : writetag(f,g));
}

View File

@ -59,13 +59,13 @@ function write_ext_props(cp, opts) {
o[o.length] = (EXT_PROPS_XML_ROOT);
EXT_PROPS.forEach(function(f) {
if(typeof cp[f[1]] === 'undefined') return;
if(cp[f[1]] === undefined) return;
var v;
switch(f[2]) {
case 'string': v = cp[f[1]]; break;
case 'bool': v = cp[f[1]] ? 'true' : 'false'; break;
}
if(typeof v !== 'undefined') o[o.length] = (W(f[0], v));
if(v !== undefined) o[o.length] = (W(f[0], v));
});
/* TODO: HeadingPairs, TitlesOfParts */

View File

@ -178,7 +178,7 @@ function parse_sst_xml(data, opts) {
}
RELS.SST = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
var straywsregex = /^\s|\s$|[\t\n\r]/;
function write_sst_xml(sst, opts) {
if(!opts.bookSST) return "";
var o = [XML_HEADER];
@ -193,7 +193,7 @@ function write_sst_xml(sst, opts) {
if(s.r) sitag += s.r;
else {
sitag += "<t";
if(s.t.match(/^\s|\s$|[\t\n\r]/)) sitag += ' xml:space="preserve"';
if(s.t.match(straywsregex)) sitag += ' xml:space="preserve"';
sitag += ">" + escapexml(s.t) + "</t>";
}
sitag += "</si>";

View File

@ -21,4 +21,19 @@ function parse_sst_bin(data, opts) {
return s;
}
function write_sst_bin(sst, opts) { }
function write_BrtBeginSst(sst, o) {
if(!o) o = new_buf(8);
o.write_shift(4, sst.Count);
o.write_shift(4, sst.Unique);
return o;
}
var write_BrtSSTItem = write_RichStr;
function write_sst_bin(sst, opts) {
var ba = buf_array();
write_record(ba, "BrtBeginSst", write_BrtBeginSst(sst));
for(var i = 0; i < sst.length; ++i) write_record(ba, "BrtSSTItem", write_BrtSSTItem(sst[i]));
write_record(ba, "BrtEndSst");
return ba.end();
}

View File

@ -47,14 +47,14 @@ function parse_fills(t, opts) {
function parse_numFmts(t, opts) {
styles.NumberFmt = [];
var k = keys(SSF._table);
for(var i=0; i != k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for(i=0; i != m.length; ++i) {
for(i=0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': case '<numFmts>': break;
case '<numFmt': {
var f=unescapexml(y.formatCode), j=parseInt(y.numFmtId,10);
var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
styles.NumberFmt[j] = f; if(j>0) SSF.load(f,j);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
@ -67,8 +67,8 @@ function write_numFmts(NF, opts) {
[[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) {
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
});
if(o.length === 1) return "";
o[o.length] = ("</numFmts>");
if(o.length === 2) return "";
o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">");
return o.join("");
}
@ -112,23 +112,29 @@ function write_cellXfs(cellXfs) {
}
/* 18.8 Styles CT_Stylesheet*/
function parse_sty_xml(data, opts) {
var parse_sty_xml= (function make_pstyx() {
var numFmtRegex = /<numFmts([^>]*)>.*<\/numFmts>/;
var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
return function parse_sty_xml(data, opts) {
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
/* numFmts CT_NumFmts ? */
if((t=data.match(/<numFmts([^>]*)>.*<\/numFmts>/))) parse_numFmts(t, opts);
if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
/* fonts CT_Fonts ? */
// if((t=data.match(/<fonts([^>]*)>.*<\/fonts>/))) parse_fonts(t, opts);
/* fills CT_Fills */
if((t=data.match(/<fills([^>]*)>.*<\/fills>/))) parse_fills(t, opts);
if((t=data.match(fillsRegex))) parse_fills(t, opts);
/* borders CT_Borders ? */
/* cellStyleXfs CT_CellStyleXfs ? */
/* cellXfs CT_CellXfs ? */
if((t=data.match(/<cellXfs([^>]*)>.*<\/cellXfs>/))) parse_cellXfs(t, opts);
if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
/* dxfs CT_Dxfs ? */
/* tableStyles CT_TableStyles ? */
@ -136,7 +142,8 @@ function parse_sty_xml(data, opts) {
/* extLst CT_ExtensionList ? */
return styles;
}
};
})();
var STYLES_XML_ROOT = writextag('styleSheet', null, {
'xmlns': XMLNS.main[0],
@ -146,10 +153,8 @@ var STYLES_XML_ROOT = writextag('styleSheet', null, {
RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
function write_sty_xml(wb, opts) {
var o = [], p = {}, w;
o[o.length] = (XML_HEADER);
o[o.length] = (STYLES_XML_ROOT);
if((w = write_numFmts(wb.SSF))) o[o.length] = (w);
var o = [XML_HEADER, STYLES_XML_ROOT], w;
if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');

View File

@ -113,4 +113,21 @@ function parse_sty_bin(data, opts) {
return styles;
}
function write_sty_bin(data, opts) { }
/* [MS-XLSB] 2.1.7.50 Styles */
function write_sty_bin(data, opts) {
var ba = buf_array();
write_record(ba, "BrtBeginStyleSheet");
/* [FMTS] */
/* [FONTS] */
/* [FILLS] */
/* [BORDERS] */
/* CELLSTYLEXFS */
/* CELLXFS*/
/* STYLES */
/* DXFS */
/* TABLESTYLES */
/* [COLORPALETTE] */
/* FRTSTYLESHEET*/
write_record(ba, "BrtEndStyleSheet");
return ba.end();
}

View File

@ -4,14 +4,14 @@ var _ssfopts = {}; // spreadsheet formatting options
RELS.WS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
function get_sst_id(sst, str) {
for(var i = 0; i != sst.length; ++i) if(sst[i].t === str) { sst.Count ++; return i; }
sst[sst.length] = {t:str}; sst.Count ++; sst.Unique ++; return sst.length-1;
for(var i = 0, len = sst.length; i < len; ++i) if(sst[i].t === str) { sst.Count ++; return i; }
sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len;
}
function get_cell_style(styles, cell, opts) {
var z = opts.revssf[cell.z != null ? cell.z : "General"];
for(var i = 0; i != styles.length; ++i) if(styles[i].numFmtId === z) return i;
styles[styles.length] = {
for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i;
styles[len] = {
numFmtId:z,
fontId:0,
fillId:0,
@ -19,7 +19,7 @@ function get_cell_style(styles, cell, opts) {
xfId:0,
applyNumberFormat:1
};
return styles.length-1;
return len;
}
function safe_format(p, fmtid, fillid, opts) {

View File

@ -1,10 +1,12 @@
function parse_ws_xml_dim(ws, s) {
var d = safe_decode_range(s);
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.e.r>=0) ws["!ref"] = encode_range(d);
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
}
var mergecregex = /<mergeCell ref="[A-Z0-9:]+"\s*\/>/g;
var sheetdataregex = /<(?:\w+:)?sheetData>([^\u2603]*)<\/(?:\w+:)?sheetData>/;
var hlinkregex = /<hyperlink[^>]*\/>/g;
var dimregex = /"(\w*:\w*)"/;
var colregex = /<col[^>]*\/>/g;
/* 18.3 Worksheets */
function parse_ws_xml(data, opts, rels) {
if(!data) return data;
@ -14,7 +16,7 @@ function parse_ws_xml(data, opts, rels) {
/* 18.3.1.35 dimension CT_SheetDimension ? */
var ridx = data.indexOf("<dimension");
if(ridx > 0) {
var ref = data.substr(ridx,50).match(/"(\w*:\w*)"/);
var ref = data.substr(ridx,50).match(dimregex);
if(ref != null) parse_ws_xml_dim(s, ref[1]);
}
@ -30,7 +32,7 @@ function parse_ws_xml(data, opts, rels) {
var columns = [];
if(opts.cellStyles && data.indexOf("</cols>")!==-1) {
/* 18.3.1.13 col CT_Col */
var cols = data.match(/<col[^>]*\/>/g);
var cols = data.match(colregex);
parse_ws_xml_cols(columns, cols);
}
@ -126,15 +128,15 @@ function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) {
var os = get_cell_style(opts.cellXfs, cell, opts);
if(os !== 0) o.s = os;
switch(cell.t) {
case 's': case 'str':
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
default:
if(opts.bookSST) {
v = writetag('v', ''+get_sst_id(opts.Strings, cell.v));
o.t = "s"; break;
}
o.t = "str"; break;
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
}
return writextag('c', v, o);
}
@ -149,20 +151,22 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
var tag;
var sstr;
var fmtid = 0, fillid = 0, do_format = Array.isArray(styles.CellXf), cf;
for(var marr = sdata.split(rowregex), mt = 0; mt != marr.length; ++mt) {
for(var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) {
x = marr[mt].trim();
if(x.length === 0) continue;
var xlen = x.length;
if(xlen === 0) continue;
/* 18.3.1.73 row CT_Row */
for(ri = 0; ri != x.length; ++ri) if(x.charCodeAt(ri) === 62) break; ++ri;
for(ri = 0; ri < xlen; ++ri) if(x.charCodeAt(ri) === 62) break; ++ri;
tag = parsexmltag(x.substr(0,ri), true);
if(opts.sheetRows && opts.sheetRows < +tag.r) continue;
if(guess.s.r > tag.r - 1) guess.s.r = tag.r - 1;
if(guess.e.r < tag.r - 1) guess.e.r = tag.r - 1;
var tagr = parseInt(tag.r, 10);
if(opts.sheetRows && opts.sheetRows < tagr) continue;
if(guess.s.r > tagr - 1) guess.s.r = tagr - 1;
if(guess.e.r < tagr - 1) guess.e.r = tagr - 1;
/* 18.3.1.4 c CT_Cell */
cells = x.substr(ri).split(cellregex);
for(ri = 0; ri != cells.length; ++ri) {
for(ri = 1, cellen = cells.length; ri != cellen; ++ri) {
x = cells[ri].trim();
if(x.length === 0) continue;
cref = x.match(rregex); idx = ri; i=0; cc=0;
@ -221,7 +225,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
cf = styles.CellXf[tag.s];
if(cf != null) {
if(cf.numFmtId != null) fmtid = cf.numFmtId;
if(opts.cellStyles && cf.fillId != undefined) fillid = cf.fillId;
if(opts.cellStyles && cf.fillId != null) fillid = cf.fillId;
}
}
safe_format(p, fmtid, fillid, opts);
@ -231,17 +235,17 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
}; })();
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [];
for(var R = range.s.r; R <= range.e.r; ++R) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R, C;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
for(var C = range.s.c; C <= range.e.c; ++C) {
if(R === range.s.r) cols[C] = encode_col(C);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
if(!ws[ref]) continue;
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb))) r.push(cell);
if(ws[ref] === undefined) continue;
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
}
if(r.length) o[o.length] = (writextag('row', r.join(""), {r:rr}));
if(r.length > 0) o[o.length] = (writextag('row', r.join(""), {r:rr}));
}
return o.join("");
}
@ -253,13 +257,18 @@ var WS_XML_ROOT = writextag('worksheet', null, {
function write_ws_xml(idx, opts, wb) {
var o = [XML_HEADER, WS_XML_ROOT];
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {}, sidx = 0, rdata = "";
o[o.length] = (writextag('dimension', null, {'ref': ws['!ref'] || 'A1'}));
if((ws['!cols']||[]).length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
sidx = o.length;
o[o.length] = (writextag('sheetData', null));
if(ws['!ref']) rdata = write_ws_xml_data(ws, opts, idx, wb);
if(rdata.length) o[o.length] = (rdata);
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
var ws = wb.Sheets[s];
if(ws === undefined) ws = {};
var ref = ws['!ref']; if(ref === undefined) ref = 'A1';
o[o.length] = (writextag('dimension', null, {'ref': ref}));
if(ws['!cols'] !== undefined && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
o[sidx = o.length] = '<sheetData/>';
if(ws['!ref'] !== undefined) {
rdata = write_ws_xml_data(ws, opts, idx, wb);
if(rdata.length > 0) o[o.length] = (rdata);
}
if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); }
if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }

View File

@ -25,6 +25,11 @@ function parse_BrtCellBlank(data, length) {
var cell = parse_Cell(data);
return [cell];
}
function write_BrtCellBlank(cell, val, o) {
if(o == null) o = new_buf(8);
return write_Cell(val, o);
}
/* [MS-XLSB] 2.4.304 BrtCellBool */
function parse_BrtCellBool(data, length) {
@ -299,6 +304,15 @@ function parse_ws_bin(data, opts, rels) {
case 'BrtCustomFilter': break;
case 'BrtEndCustomFilters': break;
/* Smart Tags */
case 'BrtBeginSmartTags': break;
case 'BrtBeginCellSmartTags': break;
case 'BrtBeginCellSmartTag': break;
case 'BrtCellSmartTagProperty': break;
case 'BrtEndCellSmartTag': break;
case 'BrtEndCellSmartTags': break;
case 'BrtEndSmartTags': break;
/* Cell Watch */
case 'BrtBeginCellWatches': break;
case 'BrtCellWatch': break;
@ -332,14 +346,47 @@ function parse_ws_bin(data, opts, rels) {
return s;
}
/* TODO: something useful -- this is a stub */
function write_ws_bin_cell(ba, cell, R, C, opts) {
if(cell.v === undefined) return "";
var vv = "";
switch(cell.t) {
case 'b': vv = cell.v ? "1" : "0"; break;
case 'n': case 'e': vv = ''+cell.v; break;
default: vv = cell.v; break;
}
var o = {r:R, c:C};
/* TODO: cell style */
o.s = get_cell_style(opts.cellXfs, cell, opts);
switch(cell.t) {
case 's': case 'str':
if(opts.bookSST) {
vv = get_sst_id(opts.Strings, cell.v);
o.t = "s"; break;
}
o.t = "str"; break;
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
}
write_record(ba, "BrtCellBlank", write_BrtCellBlank(cell, o));
}
function write_CELLTABLE(ba, ws, idx, opts, wb) {
var r = safe_decode_range(ws['!ref'] || "A1");
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
write_record(ba, 'BrtBeginSheetData');
for(var i = r.s.r; i <= r.e.r; ++i) {
for(var R = range.s.r; R <= range.e.r; ++R) {
rr = encode_row(R);
/* [ACCELLTABLE] */
/* BrtRowHdr */
/* *16384CELL */
for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
if(!ws[ref]) continue;
/* write cell */
write_ws_bin_cell(ba, ws[ref], R, C, opts);
}
}
write_record(ba, 'BrtEndSheetData');
}

View File

@ -1,4 +1,5 @@
/* 18.2 Workbook */
var wbnsregex = /<\w+:workbook/;
function parse_wb_xml(data, opts) {
var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
var pass = false, xmlns = "xmlns";
@ -9,7 +10,7 @@ function parse_wb_xml(data, opts) {
/* 18.2.27 workbook CT_Workbook 1 */
case '<workbook':
if(x.match(/<\w+:workbook/)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
if(x.match(wbnsregex)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
wb.xmlns = y[xmlns];
break;
case '</workbook>': break;

View File

@ -82,11 +82,18 @@ function parse_wb_bin(data, opts) {
case 'BrtBeginWebPubItem': break;
case 'BrtEndWebPubItem': break;
case 'BrtEndWebPubItems': break;*/
/* Smart Tags */
case 'BrtBeginSmartTagTypes': break;
case 'BrtSmartTagType': break;
case 'BrtEndSmartTagTypes': break;
case 'BrtFRTBegin': pass = true; break;
case 'BrtFRTArchID$': break;
case 'BrtWorkBookPr15': break;
case 'BrtFRTEnd': pass = false; break;
case 'BrtEndBook': break;
default: if(!pass) throw new Error("Unexpected record " + R.n);
default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n);
}
});

View File

@ -2,7 +2,7 @@ function fix_opts_func(defaults) {
return function fix_opts(opts) {
for(var i = 0; i != defaults.length; ++i) {
var d = defaults[i];
if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1];
if(opts[d[0]] === undefined) opts[d[0]] = d[1];
if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
}
};

View File

@ -1,7 +1,7 @@
function readSync(data, opts) {
var zip, d = data;
var o = opts||{};
if(!o.type) o.type = (typeof Buffer !== 'undefined' && data instanceof Buffer) ? "buffer" : "base64";
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
switch(o.type) {
case "base64": zip = new jszip(d, { base64:true }); break;
case "binary": zip = new jszip(d, { base64:false }); break;

View File

@ -23,27 +23,28 @@ function encode_range(cs,ce) {
function safe_decode_range(range) {
var o = {s:{c:0,r:0},e:{c:0,r:0}};
var idx = 0, i = 0, cc = 0;
for(idx = 0; i != range.length; ++i) {
var len = range.length;
for(idx = 0; i < len; ++i) {
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
idx = 26*idx + cc;
}
o.s.c = --idx;
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i < len; ++i) {
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
idx = 10*idx + cc;
}
o.s.r = --idx;
if(i === range.length || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
if(i === len || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i != len; ++i) {
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
idx = 26*idx + cc;
}
o.e.c = --idx;
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i != len; ++i) {
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
idx = 10*idx + cc;
}
@ -66,9 +67,9 @@ function format_cell(cell, v) {
function sheet_to_json(sheet, opts){
var val, row, range, header = 0, offset = 1, r, hdr = [], isempty, R, C, v;
var out = [];
var o = opts != null ? opts : {};
if(!sheet || !sheet["!ref"]) return out;
var raw = o.raw;
if(sheet == null || sheet["!ref"] == null) return [];
range = o.range !== undefined ? o.range : sheet["!ref"];
if(o.header === 1) header = 1;
else if(o.header === "A") header = 2;
@ -80,7 +81,9 @@ function sheet_to_json(sheet, opts){
}
if(header > 0) offset = 0;
var rr = encode_row(r.s.r);
var cols = [];
var cols = new Array(r.e.c-r.s.c+1);
var out = new Array(r.e.r-r.s.r-offset+1);
var outi = 0;
for(C = r.s.c; C <= r.e.c; ++C) {
cols[C] = encode_col(C);
val = sheet[cols[C] + rr];
@ -89,7 +92,7 @@ function sheet_to_json(sheet, opts){
case 2: hdr[C] = cols[C]; break;
case 3: hdr[C] = o.header[C - r.s.c]; break;
default:
if(!val) continue;
if(val === undefined) continue;
hdr[C] = format_cell(val);
}
}
@ -100,7 +103,7 @@ function sheet_to_json(sheet, opts){
row = header === 1 ? [] : Object.create({ __rowNum__ : R });
for (C = r.s.c; C <= r.e.c; ++C) {
val = sheet[cols[C] + rr];
if(!val || !val.t) continue;
if(val === undefined || val.t === undefined) continue;
v = val.v;
switch(val.t){
case 'e': continue;
@ -109,16 +112,17 @@ function sheet_to_json(sheet, opts){
default: throw 'unrecognized type ' + val.t;
}
if(v !== undefined) {
row[hdr[C]] = o.raw ? v : format_cell(val,v);
row[hdr[C]] = raw ? v : format_cell(val,v);
isempty = false;
}
}
if(!isempty) out.push(row);
if(isempty === false) out[outi++] = row;
}
out.length = outi;
return out;
}
function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts == null ? opts : {}); }
function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts != null ? opts : {}); }
function sheet_to_csv(sheet, opts) {
var out = "", txt = "", qreg = /"/g;
@ -130,11 +134,11 @@ function sheet_to_csv(sheet, opts) {
var row = "", rr = "", cols = [];
var i = 0, cc = 0, val;
var R = 0, C = 0;
for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
for(R = r.s.r; R <= r.e.r; ++R) {
row = "";
rr = encode_row(R);
for(C = r.s.c; C <= r.e.c; ++C) {
if(R === r.s.r) cols[C] = encode_col(C);
val = sheet[cols[C] + rr];
txt = val !== undefined ? ''+format_cell(val) : "";
for(i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34) {
@ -150,13 +154,13 @@ var make_csv = sheet_to_csv;
function sheet_to_formulae(sheet) {
var cmds, y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return "";
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C;
cmds = new Array((r.e.r-r.s.r+1)*(r.e.c-r.s.c+1));
var i = 0;
for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
for(var R = r.s.r; R <= r.e.r; ++R) {
rr = encode_row(R);
for(var C = r.s.c; C <= r.e.c; ++C) {
if(R === r.s.r) cols[C] = encode_col(C);
for(C = r.s.c; C <= r.e.c; ++C) {
y = cols[C] + rr;
x = sheet[y];
val = "";

35
dist/cpexcel.js vendored
View File

@ -1,6 +1,6 @@
/* cpexcel.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
/*jshint -W100 */
var cptable = {};
var cptable = {version:"1.3.4"};
cptable[874] = (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{|}~<7F><E282AC><EFBFBD><EFBFBD><EFBFBD><E280A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>“”•<E28093><E28094><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู<E0B8B9><E0B8BA><EFBFBD><EFBFBD>฿เแโใไๅๆ็่้๊๋์ํ๎๏๑๒๓๔๕๖๗๘๙๚๛<E0B99A><E0B99B><EFBFBD><EFBFBD>", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[932] = (function(){ var d = [], e = {}, D = [], j;
D[0] = "\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{|}~<><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚<EFBE9E><EFBE9F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>".split("");
@ -789,6 +789,8 @@ cptable[1253] = (function(){ var d = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006
cptable[1254] = (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{|}~<7F>ƒ„…†‡ˆ‰ŠŒ<E280B9><C592><EFBFBD><EFBFBD>“”•˜™šœ<E280BA><C593>Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖ×ØÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[1255] = (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{|}~<7F>ƒ„…†‡ˆ<CB86><EFBFBD><E280B9><EFBFBD><EFBFBD><EFBFBD>“”•˜<CB9C><EFBFBD><E280BA><EFBFBD><EFBFBD> ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹ<D6B8>ֻּֽ־ֿ׀ׁׂ׃װױײ׳״<D7B3><D7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>אבגדהוזחטיךכלםמןנסעףפץצקרשת<D7A9><D7AA><E2808E>", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[1256] = (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[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[1257] = (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{|}~<7F><EFBFBD>„…†‡<E280A0><EFBFBD><EFBFBD>¨ˇ¸<CB87>“”•<E28093><EFBFBD><EFBFBD>¯˛<C2AF> <EFBFBD>¢£¤<C2A3>¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[1258] = (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{|}~<7F>ƒ„…†‡ˆ<CB86>Œ<E280B9><C592><EFBFBD><EFBFBD>“”•˜<CB9C>œ<E280BA><C593>Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖ×ØÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[10000] = (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{|}~ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ—“”÷◊ÿŸ¤fifl‡·„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[10006] = (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{|}~Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡΤ«»… ΥΧΆΈœ―“”÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ<CE90>", D = [], e = {}; for(var i=0;i!=d.length;++i) { if(d.charCodeAt(i) !== 0xFFFD) e[d[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
cptable[10007] = (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[i]] = i; D[i] = d.charAt(i); } return {"enc": e, "dec": D }; })();
@ -987,7 +989,9 @@ if (typeof module !== 'undefined' && module.exports) module.exports = cptable;
var len = data.length, w = 0, ww = 0;
if(4 * len > mdl) { mdl = 4 * len; mdb = new Buffer(mdl); }
mdb.length = 0;
for(var i = 0, j = 1, k = 0, D = 0; i < len; i+=j) {
var i = 0;
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
for(var j = 1, k = 0, D = 0; i < len; i+=j) {
j = 1; D = data[i];
if(D < 128) w = D;
else if(D < 224) { w=(D&31)*64+(data[i+1]&63); j=2; }
@ -1202,7 +1206,9 @@ if (typeof module !== 'undefined' && module.exports) module.exports = cptable;
}
else if((M=magic[cp])) switch(M) {
case "utf8":
for(i = 0; i < len; i+=j) {
i = 0;
if(len >= 3 && data[0] == 0xEF) if(data[1] == 0xBB && data[2] == 0xBF) i = 3;
for(; i < len; i+=j) {
j = 1;
if(data[i] < 128) w = data[i];
else if(data[i] < 224) { w=(data[i]&31)*64+(data[i+1]&63); j=2; }
@ -1220,21 +1226,27 @@ if (typeof module !== 'undefined' && module.exports) module.exports = cptable;
for(i = 0; i < len; i++) out[i] = String.fromCharCode(data[i]);
k = len; break;
case "utf16le":
i = 0;
if(len >= 2 && data[0] == 0xFF) if(data[1] == 0xFE) i = 2;
if(typeof Buffer !== 'undefined' && Buffer.isBuffer(data)) return data.toString(M);
j = 2;
for(i = 0; i < len; i+=j) {
for(; i < len; i+=j) {
out[k++] = String.fromCharCode((data[i+1]<<8) + data[i]);
}
break;
case "utf16be":
i = 0;
if(len >= 2 && data[0] == 0xFE) if(data[1] == 0xFF) i = 2;
j = 2;
for(i = 0; i < len; i+=j) {
for(; i < len; i+=j) {
out[k++] = String.fromCharCode((data[i]<<8) + data[i+1]);
}
break;
case "utf32le":
i = 0;
if(len >= 4 && data[0] == 0xFF) if(data[1] == 0xFE && data[2] == 0 && data[3] == 0) i = 4;
j = 4;
for(i = 0; i < len; i+=j) {
for(; i < len; i+=j) {
w = (data[i+3]<<24) + (data[i+2]<<16) + (data[i+1]<<8) + (data[i]);
if(w > 0xFFFF) {
w -= 0x10000;
@ -1245,8 +1257,10 @@ if (typeof module !== 'undefined' && module.exports) module.exports = cptable;
}
break;
case "utf32be":
i = 0;
if(len >= 4 && data[3] == 0xFF) if(data[2] == 0xFE && data[1] == 0 && data[0] == 0) i = 4;
j = 4;
for(i = 0; i < len; i+=j) {
for(; i < len; i+=j) {
w = (data[i]<<24) + (data[i+1]<<16) + (data[i+2]<<8) + (data[i+3]);
if(w > 0xFFFF) {
w -= 0x10000;
@ -1257,7 +1271,12 @@ if (typeof module !== 'undefined' && module.exports) module.exports = cptable;
}
break;
case "utf7":
for(i = 0; i < len; i+=j) {
i = 0;
if(len >= 4 && data[0] == 0x2B && data[1] == 0x2F && data[2] == 0x76) {
if(len >= 5 && data[3] == 0x38 && data[4] == 0x2D) i = 5;
else if(data[3] == 0x38 || data[3] == 0x39 || data[3] == 0x2B || data[3] == 0x2F) i = 4;
}
for(; i < len; i+=j) {
if(data[i] !== 0x2b) { j=1; out[k++] = String.fromCharCode(data[i]); continue; }
j=1;
if(data[i+1] === 0x2d) { j = 2; out[k++] = "+"; continue; }

10
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

12
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

372
dist/xlsx.js vendored
View File

@ -3,21 +3,24 @@
/*jshint -W041 */
var XLSX = {};
(function(XLSX){
XLSX.version = '0.7.7';
XLSX.version = '0.7.8';
var current_codepage = 1252, current_cptable;
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
current_cptable = cptable[current_codepage];
}
function reset_cp() { set_cp(1252); }
function set_cp(cp) { current_codepage = cp; if(typeof cptable !== 'undefined') current_cptable = cptable[cp]; }
var set_cp = function(cp) { current_codepage = cp; };
function char_codes(data) { var o = []; for(var i = 0; i != data.length; ++i) o[i] = data.charCodeAt(i); return o; }
function debom_xml(data) {
if(typeof cptable !== 'undefined') {
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
var debom_xml = function(data) { return data; };
if(typeof cptable !== 'undefined') {
set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
debom_xml = function(data) {
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
}
return data;
return data;
};
}
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
/*jshint -W041 */
@ -827,15 +830,17 @@ function cc2str(arr) {
for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]);
return o;
}
var has_buf = (typeof Buffer !== 'undefined');
function getdata(data) {
if(!data) return null;
if(data.name.substr(-4) === ".bin") {
if(data.data) return char_codes(data.data);
if(data.asNodeBuffer && typeof Buffer !== 'undefined') return data.asNodeBuffer();
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
} else {
if(data.data) return data.name.substr(-4) !== ".bin" ? debom_xml(data.data) : char_codes(data.data);
if(data.asNodeBuffer && typeof Buffer !== 'undefined') return debom_xml(data.asNodeBuffer().toString('binary'));
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
if(data.asBinary) return debom_xml(data.asBinary());
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
}
@ -859,12 +864,11 @@ var _fs, jszip;
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(typeof Buffer !== 'undefined' && typeof jszip === 'undefined') jszip = require('jszip');
if(typeof jszip === 'undefined') jszip = require('./jszip').JSZip;
_fs = require('fs');
if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
_fs = require('f'+'s');
}
}
var _chr = function(c) { return String.fromCharCode(c); };
var attregexg=/\b[\w:]+=["'][^"]*['"]/g;
var tagregex=/<[^>]*>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
@ -898,10 +902,10 @@ var rencoding = evert(encodings);
var rencstr = "&<>'\"".split("");
// TODO: CP remap (need to read file version to determine OS)
var encregex = /&[a-z]*;/g, coderegex = /_x([0-9a-fA-F]+)_/g;
var encregex = /&[a-z]*;/g, coderegex = /_x([\da-fA-F]+)_/g;
function unescapexml(text){
var s = text + '';
return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return _chr(parseInt(c,16));});
return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
}
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
function escapexml(text){
@ -935,7 +939,7 @@ var utf8read = function utf8reada(orig) {
};
if(typeof Buffer !== "undefined") {
if(has_buf) {
var utf8readb = function utf8readb(data) {
var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
for(i = 0; i < data.length; i+=j) {
@ -1044,38 +1048,37 @@ function readIEEE754(buf, idx, isLE, nl, ml) {
}
var __toBuffer, ___toBuffer;
__toBuffer = ___toBuffer = function(bufs) {
var x = [];
for(var i = 0; i != bufs[0].length; ++i) { x = x.concat(bufs[0][i]); }
return x;
};
if(typeof Buffer !== "undefined") {
__toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
var __double, ___double;
__double = ___double = function(b, idx) { return readIEEE754(b, idx);};
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
if(has_buf) {
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
__double = function double_(b,i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
}
var ___readUInt32LE = function(b, idx) { return b.readUInt32LE ? b.readUInt32LE(idx) : b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var ___readInt32LE = function(b, idx) { return (b[idx+3]<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var __readUInt8 = function(b, idx) { return b.readUInt8 ? b.readUInt8(idx) : b[idx]; };
var __readUInt16LE = function(b, idx) { return b.readUInt16LE ? b.readUInt16LE(idx) : b[idx+1]*(1<<8)+b[idx]; };
var __readInt16LE = function(b, idx) { var u = __readUInt16LE(b,idx); if(!(u & 0x8000)) return u; return (0xffff - u + 1) * -1; };
var __readUInt32LE = typeof Buffer !== "undefined" ? function(b, i) { return Buffer.isBuffer(b) ? b.readUInt32LE(i) : ___readUInt32LE(b,i); } : ___readUInt32LE;
var __readInt32LE = typeof Buffer !== "undefined" ? function(b, i) { return Buffer.isBuffer(b) ? b.readInt32LE(i) : ___readInt32LE(b,i); } : ___readInt32LE;
var __readDoubleLE = function(b, idx) { return b.readDoubleLE ? b.readDoubleLE(idx) : readIEEE754(b, idx||0);};
var __readUInt8 = function(b, idx) { return b[idx]; };
var __readUInt16LE = function(b, idx) { return b[idx+1]*(1<<8)+b[idx]; };
var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
function ReadShift(size, t) {
var o="", oo=[], w, vv, i, loc;
if(t === 'dbcs') {
loc = this.l;
if(typeof Buffer !== 'undefined' && this instanceof Buffer) o = this.slice(this.l, this.l+2*size).toString("utf16le");
if(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString("utf16le");
else for(i = 0; i != size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; }
size *= 2;
} else switch(size) {
case 1: o = __readUInt8(this, this.l); break;
case 2: o = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); break;
case 4: o = __readUInt32LE(this, this.l); break;
case 8: if(t === 'f') { o = __readDoubleLE(this, this.l); break; }
case 8: if(t === 'f') { o = __double(this, this.l); break; }
}
this.l+=size; return o;
}
@ -1086,7 +1089,8 @@ function WriteShift(t, val, f) {
for(i = 0; i != val.length; ++i) this.writeUInt16LE(val.charCodeAt(i), this.l + 2 * i);
size = 2 * val.length;
} else switch(t) {
case 1: size = 1; this.writeUInt8(val, this.l); break;
case 1: size = 1; this[this.l] = val&255; break;
case 3: size = 3; this[this.l+2] = val & 255; val >>>= 8; this[this.l+1] = val&255; val >>>= 8; this[this.l] = val&255; break;
case 4: size = 4; this.writeUInt32LE(val, this.l); break;
case 8: size = 8; if(f === 'f') { this.writeDoubleLE(val, this.l); break; }
/* falls through */
@ -1097,7 +1101,7 @@ function WriteShift(t, val, f) {
}
function prep_blob(blob, pos) {
blob.l = pos || 0;
blob.l = pos;
blob.read_shift = ReadShift;
blob.write_shift = WriteShift;
}
@ -1107,12 +1111,11 @@ function parsenoop(blob, length) { blob.l += length; }
function writenoop(blob, length) { blob.l += length; }
function new_buf(sz) {
var o = typeof Buffer !== 'undefined' ? new Buffer(sz) : new Array(sz);
var o = has_buf ? new Buffer(sz) : new Array(sz);
prep_blob(o, 0);
return o;
}
function is_buf(a) { return (typeof Buffer !== 'undefined' && a instanceof Buffer) || Array.isArray(a); }
/* [MS-XLSB] 2.1.4 Record */
function recordhopper(data, cb, opts) {
var tmpbyte, cntbyte, length;
@ -1205,6 +1208,13 @@ function parse_RichStr(data, length) {
data.l = start + length;
return z;
}
function write_RichStr(str, o) {
/* TODO: formatted string */
if(o == null) o = new_buf(5+2*str.t.length);
o.write_shift(1,0);
write_XLWideString(str.t, o);
return o;
}
/* [MS-XLSB] 2.5.9 */
function parse_Cell(data) {
@ -1214,6 +1224,14 @@ function parse_Cell(data) {
var fPhShow = data.read_shift(1);
return { c:col, iStyleRef: iStyleRef };
}
function write_Cell(cell, o) {
if(o == null) o = new_buf(8);
o.write_shift(-4, cell.c);
o.write_shift(3, cell.iStyleRef === undefined ? cell.iStyleRef : cell.s);
o.write_shift(1, 0); /* fPhShow */
return o;
}
/* [MS-XLSB] 2.5.21 */
function parse_CodeName (data, length) { return parse_XLWideString(data, length); }
@ -1236,7 +1254,7 @@ function parse_XLWideString(data) {
return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
}
function write_XLWideString(data, o) {
if(o == null) o = new_buf(127);
if(o == null) o = new_buf(4+2*data.length);
o.write_shift(4, data.length);
if(data.length > 0) o.write_shift(0, data, 'dbcs');
return o;
@ -1253,7 +1271,7 @@ function parse_RkNumber(data) {
var fX100 = b[0] & 1, fInt = b[0] & 2;
data.l+=4;
b[0] &= 0xFC;
var RK = fInt === 0 ? __readDoubleLE([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
var RK = fInt === 0 ? __double([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
return fX100 ? RK/100 : RK;
}
@ -1660,14 +1678,21 @@ var CORE_PROPS = [
XMLNS.CORE_PROPS = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
RELS.CORE_PROPS = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties';
var CORE_PROPS_REGEX = (function() {
var r = new Array(CORE_PROPS.length);
for(var i = 0; i < CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i];
var g = "(?:"+ f[0].substr(0,f[0].indexOf(":")) +":)"+ f[0].substr(f[0].indexOf(":")+1);
r[i] = new RegExp("<" + g + "[^>]*>(.*)<\/" + g + ">");
}
return r;
})();
function parse_core_props(data) {
var p = {};
for(var i = 0; i != CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i];
var g = "(?:"+ f[0].substr(0,f[0].indexOf(":")) +":)"+ f[0].substr(f[0].indexOf(":")+1);
var cur = data.match(new RegExp("<" + g + "[^>]*>(.*)<\/" + g + ">"));
for(var i = 0; i < CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i], cur = data.match(CORE_PROPS_REGEX[i]);
if(cur != null && cur.length > 0) p[f[1]] = cur[1];
if(f[2] === 'date' && p[f[1]]) p[f[1]] = new Date(p[f[1]]);
}
@ -1686,7 +1711,6 @@ var CORE_PROPS_XML_ROOT = writextag('cp:coreProperties', null, {
function cp_doit(f, g, h, o, p) {
if(p[f] != null || g == null || g === "") return;
if(typeof g !== 'string') g = String(g); /* TODO: remove */
p[f] = g;
o[o.length] = (h ? writextag(f,g,h) : writetag(f,g));
}
@ -1764,13 +1788,13 @@ function write_ext_props(cp, opts) {
o[o.length] = (EXT_PROPS_XML_ROOT);
EXT_PROPS.forEach(function(f) {
if(typeof cp[f[1]] === 'undefined') return;
if(cp[f[1]] === undefined) return;
var v;
switch(f[2]) {
case 'string': v = cp[f[1]]; break;
case 'bool': v = cp[f[1]] ? 'true' : 'false'; break;
}
if(typeof v !== 'undefined') o[o.length] = (W(f[0], v));
if(v !== undefined) o[o.length] = (W(f[0], v));
});
/* TODO: HeadingPairs, TitlesOfParts */
@ -2029,7 +2053,7 @@ function parse_sst_xml(data, opts) {
}
RELS.SST = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
var straywsregex = /^\s|\s$|[\t\n\r]/;
function write_sst_xml(sst, opts) {
if(!opts.bookSST) return "";
var o = [XML_HEADER];
@ -2044,7 +2068,7 @@ function write_sst_xml(sst, opts) {
if(s.r) sitag += s.r;
else {
sitag += "<t";
if(s.t.match(/^\s|\s$|[\t\n\r]/)) sitag += ' xml:space="preserve"';
if(s.t.match(straywsregex)) sitag += ' xml:space="preserve"';
sitag += ">" + escapexml(s.t) + "</t>";
}
sitag += "</si>";
@ -2076,7 +2100,22 @@ function parse_sst_bin(data, opts) {
return s;
}
function write_sst_bin(sst, opts) { }
function write_BrtBeginSst(sst, o) {
if(!o) o = new_buf(8);
o.write_shift(4, sst.Count);
o.write_shift(4, sst.Unique);
return o;
}
var write_BrtSSTItem = write_RichStr;
function write_sst_bin(sst, opts) {
var ba = buf_array();
write_record(ba, "BrtBeginSst", write_BrtBeginSst(sst));
for(var i = 0; i < sst.length; ++i) write_record(ba, "BrtSSTItem", write_BrtSSTItem(sst[i]));
write_record(ba, "BrtEndSst");
return ba.end();
}
function hex2RGB(h) {
var o = h.substr(h[0]==="#"?1:0,6);
return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)];
@ -2194,14 +2233,14 @@ function parse_fills(t, opts) {
function parse_numFmts(t, opts) {
styles.NumberFmt = [];
var k = keys(SSF._table);
for(var i=0; i != k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for(i=0; i != m.length; ++i) {
for(i=0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': case '<numFmts>': break;
case '<numFmt': {
var f=unescapexml(y.formatCode), j=parseInt(y.numFmtId,10);
var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
styles.NumberFmt[j] = f; if(j>0) SSF.load(f,j);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
@ -2214,8 +2253,8 @@ function write_numFmts(NF, opts) {
[[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) {
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
});
if(o.length === 1) return "";
o[o.length] = ("</numFmts>");
if(o.length === 2) return "";
o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">");
return o.join("");
}
@ -2259,23 +2298,29 @@ function write_cellXfs(cellXfs) {
}
/* 18.8 Styles CT_Stylesheet*/
function parse_sty_xml(data, opts) {
var parse_sty_xml= (function make_pstyx() {
var numFmtRegex = /<numFmts([^>]*)>.*<\/numFmts>/;
var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
return function parse_sty_xml(data, opts) {
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
/* numFmts CT_NumFmts ? */
if((t=data.match(/<numFmts([^>]*)>.*<\/numFmts>/))) parse_numFmts(t, opts);
if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
/* fonts CT_Fonts ? */
// if((t=data.match(/<fonts([^>]*)>.*<\/fonts>/))) parse_fonts(t, opts);
/* fills CT_Fills */
if((t=data.match(/<fills([^>]*)>.*<\/fills>/))) parse_fills(t, opts);
if((t=data.match(fillsRegex))) parse_fills(t, opts);
/* borders CT_Borders ? */
/* cellStyleXfs CT_CellStyleXfs ? */
/* cellXfs CT_CellXfs ? */
if((t=data.match(/<cellXfs([^>]*)>.*<\/cellXfs>/))) parse_cellXfs(t, opts);
if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
/* dxfs CT_Dxfs ? */
/* tableStyles CT_TableStyles ? */
@ -2283,7 +2328,8 @@ function parse_sty_xml(data, opts) {
/* extLst CT_ExtensionList ? */
return styles;
}
};
})();
var STYLES_XML_ROOT = writextag('styleSheet', null, {
'xmlns': XMLNS.main[0],
@ -2293,10 +2339,8 @@ var STYLES_XML_ROOT = writextag('styleSheet', null, {
RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
function write_sty_xml(wb, opts) {
var o = [], p = {}, w;
o[o.length] = (XML_HEADER);
o[o.length] = (STYLES_XML_ROOT);
if((w = write_numFmts(wb.SSF))) o[o.length] = (w);
var o = [XML_HEADER, STYLES_XML_ROOT], w;
if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
@ -2424,7 +2468,24 @@ function parse_sty_bin(data, opts) {
return styles;
}
function write_sty_bin(data, opts) { }
/* [MS-XLSB] 2.1.7.50 Styles */
function write_sty_bin(data, opts) {
var ba = buf_array();
write_record(ba, "BrtBeginStyleSheet");
/* [FMTS] */
/* [FONTS] */
/* [FILLS] */
/* [BORDERS] */
/* CELLSTYLEXFS */
/* CELLXFS*/
/* STYLES */
/* DXFS */
/* TABLESTYLES */
/* [COLORPALETTE] */
/* FRTSTYLESHEET*/
write_record(ba, "BrtEndStyleSheet");
return ba.end();
}
RELS.THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
/* 20.1.6.2 clrScheme CT_ColorScheme */
@ -2680,14 +2741,14 @@ var _ssfopts = {}; // spreadsheet formatting options
RELS.WS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
function get_sst_id(sst, str) {
for(var i = 0; i != sst.length; ++i) if(sst[i].t === str) { sst.Count ++; return i; }
sst[sst.length] = {t:str}; sst.Count ++; sst.Unique ++; return sst.length-1;
for(var i = 0, len = sst.length; i < len; ++i) if(sst[i].t === str) { sst.Count ++; return i; }
sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len;
}
function get_cell_style(styles, cell, opts) {
var z = opts.revssf[cell.z != null ? cell.z : "General"];
for(var i = 0; i != styles.length; ++i) if(styles[i].numFmtId === z) return i;
styles[styles.length] = {
for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i;
styles[len] = {
numFmtId:z,
fontId:0,
fillId:0,
@ -2695,7 +2756,7 @@ function get_cell_style(styles, cell, opts) {
xfId:0,
applyNumberFormat:1
};
return styles.length-1;
return len;
}
function safe_format(p, fmtid, fillid, opts) {
@ -2725,11 +2786,13 @@ function safe_format(p, fmtid, fillid, opts) {
}
function parse_ws_xml_dim(ws, s) {
var d = safe_decode_range(s);
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.e.r>=0) ws["!ref"] = encode_range(d);
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
}
var mergecregex = /<mergeCell ref="[A-Z0-9:]+"\s*\/>/g;
var sheetdataregex = /<(?:\w+:)?sheetData>([^\u2603]*)<\/(?:\w+:)?sheetData>/;
var hlinkregex = /<hyperlink[^>]*\/>/g;
var dimregex = /"(\w*:\w*)"/;
var colregex = /<col[^>]*\/>/g;
/* 18.3 Worksheets */
function parse_ws_xml(data, opts, rels) {
if(!data) return data;
@ -2739,7 +2802,7 @@ function parse_ws_xml(data, opts, rels) {
/* 18.3.1.35 dimension CT_SheetDimension ? */
var ridx = data.indexOf("<dimension");
if(ridx > 0) {
var ref = data.substr(ridx,50).match(/"(\w*:\w*)"/);
var ref = data.substr(ridx,50).match(dimregex);
if(ref != null) parse_ws_xml_dim(s, ref[1]);
}
@ -2755,7 +2818,7 @@ function parse_ws_xml(data, opts, rels) {
var columns = [];
if(opts.cellStyles && data.indexOf("</cols>")!==-1) {
/* 18.3.1.13 col CT_Col */
var cols = data.match(/<col[^>]*\/>/g);
var cols = data.match(colregex);
parse_ws_xml_cols(columns, cols);
}
@ -2851,15 +2914,15 @@ function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) {
var os = get_cell_style(opts.cellXfs, cell, opts);
if(os !== 0) o.s = os;
switch(cell.t) {
case 's': case 'str':
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
default:
if(opts.bookSST) {
v = writetag('v', ''+get_sst_id(opts.Strings, cell.v));
o.t = "s"; break;
}
o.t = "str"; break;
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
}
return writextag('c', v, o);
}
@ -2874,20 +2937,22 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
var tag;
var sstr;
var fmtid = 0, fillid = 0, do_format = Array.isArray(styles.CellXf), cf;
for(var marr = sdata.split(rowregex), mt = 0; mt != marr.length; ++mt) {
for(var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) {
x = marr[mt].trim();
if(x.length === 0) continue;
var xlen = x.length;
if(xlen === 0) continue;
/* 18.3.1.73 row CT_Row */
for(ri = 0; ri != x.length; ++ri) if(x.charCodeAt(ri) === 62) break; ++ri;
for(ri = 0; ri < xlen; ++ri) if(x.charCodeAt(ri) === 62) break; ++ri;
tag = parsexmltag(x.substr(0,ri), true);
if(opts.sheetRows && opts.sheetRows < +tag.r) continue;
if(guess.s.r > tag.r - 1) guess.s.r = tag.r - 1;
if(guess.e.r < tag.r - 1) guess.e.r = tag.r - 1;
var tagr = parseInt(tag.r, 10);
if(opts.sheetRows && opts.sheetRows < tagr) continue;
if(guess.s.r > tagr - 1) guess.s.r = tagr - 1;
if(guess.e.r < tagr - 1) guess.e.r = tagr - 1;
/* 18.3.1.4 c CT_Cell */
cells = x.substr(ri).split(cellregex);
for(ri = 0; ri != cells.length; ++ri) {
for(ri = 1, cellen = cells.length; ri != cellen; ++ri) {
x = cells[ri].trim();
if(x.length === 0) continue;
cref = x.match(rregex); idx = ri; i=0; cc=0;
@ -2946,7 +3011,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
cf = styles.CellXf[tag.s];
if(cf != null) {
if(cf.numFmtId != null) fmtid = cf.numFmtId;
if(opts.cellStyles && cf.fillId != undefined) fillid = cf.fillId;
if(opts.cellStyles && cf.fillId != null) fillid = cf.fillId;
}
}
safe_format(p, fmtid, fillid, opts);
@ -2956,17 +3021,17 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
}; })();
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [];
for(var R = range.s.r; R <= range.e.r; ++R) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R, C;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
for(var C = range.s.c; C <= range.e.c; ++C) {
if(R === range.s.r) cols[C] = encode_col(C);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
if(!ws[ref]) continue;
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb))) r.push(cell);
if(ws[ref] === undefined) continue;
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
}
if(r.length) o[o.length] = (writextag('row', r.join(""), {r:rr}));
if(r.length > 0) o[o.length] = (writextag('row', r.join(""), {r:rr}));
}
return o.join("");
}
@ -2978,13 +3043,18 @@ var WS_XML_ROOT = writextag('worksheet', null, {
function write_ws_xml(idx, opts, wb) {
var o = [XML_HEADER, WS_XML_ROOT];
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {}, sidx = 0, rdata = "";
o[o.length] = (writextag('dimension', null, {'ref': ws['!ref'] || 'A1'}));
if((ws['!cols']||[]).length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
sidx = o.length;
o[o.length] = (writextag('sheetData', null));
if(ws['!ref']) rdata = write_ws_xml_data(ws, opts, idx, wb);
if(rdata.length) o[o.length] = (rdata);
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
var ws = wb.Sheets[s];
if(ws === undefined) ws = {};
var ref = ws['!ref']; if(ref === undefined) ref = 'A1';
o[o.length] = (writextag('dimension', null, {'ref': ref}));
if(ws['!cols'] !== undefined && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
o[sidx = o.length] = '<sheetData/>';
if(ws['!ref'] !== undefined) {
rdata = write_ws_xml_data(ws, opts, idx, wb);
if(rdata.length > 0) o[o.length] = (rdata);
}
if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); }
if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }
@ -3017,6 +3087,11 @@ function parse_BrtCellBlank(data, length) {
var cell = parse_Cell(data);
return [cell];
}
function write_BrtCellBlank(cell, val, o) {
if(o == null) o = new_buf(8);
return write_Cell(val, o);
}
/* [MS-XLSB] 2.4.304 BrtCellBool */
function parse_BrtCellBool(data, length) {
@ -3291,6 +3366,15 @@ function parse_ws_bin(data, opts, rels) {
case 'BrtCustomFilter': break;
case 'BrtEndCustomFilters': break;
/* Smart Tags */
case 'BrtBeginSmartTags': break;
case 'BrtBeginCellSmartTags': break;
case 'BrtBeginCellSmartTag': break;
case 'BrtCellSmartTagProperty': break;
case 'BrtEndCellSmartTag': break;
case 'BrtEndCellSmartTags': break;
case 'BrtEndSmartTags': break;
/* Cell Watch */
case 'BrtBeginCellWatches': break;
case 'BrtCellWatch': break;
@ -3324,14 +3408,47 @@ function parse_ws_bin(data, opts, rels) {
return s;
}
/* TODO: something useful -- this is a stub */
function write_ws_bin_cell(ba, cell, R, C, opts) {
if(cell.v === undefined) return "";
var vv = "";
switch(cell.t) {
case 'b': vv = cell.v ? "1" : "0"; break;
case 'n': case 'e': vv = ''+cell.v; break;
default: vv = cell.v; break;
}
var o = {r:R, c:C};
/* TODO: cell style */
o.s = get_cell_style(opts.cellXfs, cell, opts);
switch(cell.t) {
case 's': case 'str':
if(opts.bookSST) {
vv = get_sst_id(opts.Strings, cell.v);
o.t = "s"; break;
}
o.t = "str"; break;
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
}
write_record(ba, "BrtCellBlank", write_BrtCellBlank(cell, o));
}
function write_CELLTABLE(ba, ws, idx, opts, wb) {
var r = safe_decode_range(ws['!ref'] || "A1");
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
write_record(ba, 'BrtBeginSheetData');
for(var i = r.s.r; i <= r.e.r; ++i) {
for(var R = range.s.r; R <= range.e.r; ++R) {
rr = encode_row(R);
/* [ACCELLTABLE] */
/* BrtRowHdr */
/* *16384CELL */
for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
if(!ws[ref]) continue;
/* write cell */
write_ws_bin_cell(ba, ws[ref], R, C, opts);
}
}
write_record(ba, 'BrtEndSheetData');
}
@ -3483,6 +3600,7 @@ function parse_wb_defaults(wb) {
_ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904, 'date1904');
}
/* 18.2 Workbook */
var wbnsregex = /<\w+:workbook/;
function parse_wb_xml(data, opts) {
var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
var pass = false, xmlns = "xmlns";
@ -3493,7 +3611,7 @@ function parse_wb_xml(data, opts) {
/* 18.2.27 workbook CT_Workbook 1 */
case '<workbook':
if(x.match(/<\w+:workbook/)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
if(x.match(wbnsregex)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
wb.xmlns = y[xmlns];
break;
case '</workbook>': break;
@ -3675,6 +3793,7 @@ function parse_wb_bin(data, opts) {
case 'BrtACBegin': break;
case 'BrtAbsPath15': break;
case 'BrtACEnd': break;
case 'BrtWbFactoid': break;
/*case 'BrtBookProtectionIso': break;*/
case 'BrtBookProtection': break;
case 'BrtBeginBookViews': break;
@ -3703,11 +3822,18 @@ function parse_wb_bin(data, opts) {
case 'BrtBeginWebPubItem': break;
case 'BrtEndWebPubItem': break;
case 'BrtEndWebPubItems': break;*/
/* Smart Tags */
case 'BrtBeginSmartTagTypes': break;
case 'BrtSmartTagType': break;
case 'BrtEndSmartTagTypes': break;
case 'BrtFRTBegin': pass = true; break;
case 'BrtFRTArchID$': break;
case 'BrtWorkBookPr15': break;
case 'BrtFRTEnd': pass = false; break;
case 'BrtEndBook': break;
default: if(!pass) throw new Error("Unexpected record " + R.n);
default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n);
}
});
@ -4674,7 +4800,7 @@ function fix_opts_func(defaults) {
return function fix_opts(opts) {
for(var i = 0; i != defaults.length; ++i) {
var d = defaults[i];
if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1];
if(opts[d[0]] === undefined) opts[d[0]] = d[1];
if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
}
};
@ -4935,7 +5061,7 @@ function write_zip(wb, opts) {
function readSync(data, opts) {
var zip, d = data;
var o = opts||{};
if(!o.type) o.type = (typeof Buffer !== 'undefined' && data instanceof Buffer) ? "buffer" : "base64";
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
switch(o.type) {
case "base64": zip = new jszip(d, { base64:true }); break;
case "binary": zip = new jszip(d, { base64:false }); break;
@ -4998,27 +5124,28 @@ function encode_range(cs,ce) {
function safe_decode_range(range) {
var o = {s:{c:0,r:0},e:{c:0,r:0}};
var idx = 0, i = 0, cc = 0;
for(idx = 0; i != range.length; ++i) {
var len = range.length;
for(idx = 0; i < len; ++i) {
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
idx = 26*idx + cc;
}
o.s.c = --idx;
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i < len; ++i) {
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
idx = 10*idx + cc;
}
o.s.r = --idx;
if(i === range.length || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
if(i === len || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i != len; ++i) {
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
idx = 26*idx + cc;
}
o.e.c = --idx;
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i != len; ++i) {
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
idx = 10*idx + cc;
}
@ -5041,9 +5168,9 @@ function format_cell(cell, v) {
function sheet_to_json(sheet, opts){
var val, row, range, header = 0, offset = 1, r, hdr = [], isempty, R, C, v;
var out = [];
var o = opts != null ? opts : {};
if(!sheet || !sheet["!ref"]) return out;
var raw = o.raw;
if(sheet == null || sheet["!ref"] == null) return [];
range = o.range !== undefined ? o.range : sheet["!ref"];
if(o.header === 1) header = 1;
else if(o.header === "A") header = 2;
@ -5055,7 +5182,9 @@ function sheet_to_json(sheet, opts){
}
if(header > 0) offset = 0;
var rr = encode_row(r.s.r);
var cols = [];
var cols = new Array(r.e.c-r.s.c+1);
var out = new Array(r.e.r-r.s.r-offset+1);
var outi = 0;
for(C = r.s.c; C <= r.e.c; ++C) {
cols[C] = encode_col(C);
val = sheet[cols[C] + rr];
@ -5064,7 +5193,7 @@ function sheet_to_json(sheet, opts){
case 2: hdr[C] = cols[C]; break;
case 3: hdr[C] = o.header[C - r.s.c]; break;
default:
if(!val) continue;
if(val === undefined) continue;
hdr[C] = format_cell(val);
}
}
@ -5075,7 +5204,7 @@ function sheet_to_json(sheet, opts){
row = header === 1 ? [] : Object.create({ __rowNum__ : R });
for (C = r.s.c; C <= r.e.c; ++C) {
val = sheet[cols[C] + rr];
if(!val || !val.t) continue;
if(val === undefined || val.t === undefined) continue;
v = val.v;
switch(val.t){
case 'e': continue;
@ -5084,16 +5213,17 @@ function sheet_to_json(sheet, opts){
default: throw 'unrecognized type ' + val.t;
}
if(v !== undefined) {
row[hdr[C]] = o.raw ? v : format_cell(val,v);
row[hdr[C]] = raw ? v : format_cell(val,v);
isempty = false;
}
}
if(!isempty) out.push(row);
if(isempty === false) out[outi++] = row;
}
out.length = outi;
return out;
}
function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts == null ? opts : {}); }
function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts != null ? opts : {}); }
function sheet_to_csv(sheet, opts) {
var out = "", txt = "", qreg = /"/g;
@ -5105,11 +5235,11 @@ function sheet_to_csv(sheet, opts) {
var row = "", rr = "", cols = [];
var i = 0, cc = 0, val;
var R = 0, C = 0;
for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
for(R = r.s.r; R <= r.e.r; ++R) {
row = "";
rr = encode_row(R);
for(C = r.s.c; C <= r.e.c; ++C) {
if(R === r.s.r) cols[C] = encode_col(C);
val = sheet[cols[C] + rr];
txt = val !== undefined ? ''+format_cell(val) : "";
for(i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34) {
@ -5125,13 +5255,13 @@ var make_csv = sheet_to_csv;
function sheet_to_formulae(sheet) {
var cmds, y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return "";
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C;
cmds = new Array((r.e.r-r.s.r+1)*(r.e.c-r.s.c+1));
var i = 0;
for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
for(var R = r.s.r; R <= r.e.r; ++R) {
rr = encode_row(R);
for(var C = r.s.c; C <= r.e.c; ++C) {
if(R === r.s.r) cols[C] = encode_col(C);
for(C = r.s.c; C <= r.e.c; ++C) {
y = cols[C] + rr;
x = sheet[y];
val = "";

10
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

@ -1,6 +1,6 @@
{
"name": "xlsx",
"version": "0.7.7",
"version": "0.7.8",
"author": "sheetjs",
"description": "Excel 2007+ spreadsheet (XLSB/XLSX/XLSM) parser and writer",
"keywords": [ "excel", "xlsx", "xlsb", "xlsm", "office", "spreadsheet" ],
@ -10,7 +10,7 @@
"main": "./xlsx",
"dependencies": {
"ssf":"~0.8.1",
"codepage":"~1.3.1",
"codepage":"~1.3.4",
"cfb":">=0.10.0",
"jszip":"2.3.0",
"crc-32":"",

View File

@ -200,7 +200,13 @@ if (!Array.prototype.indexOf) {
return -1;
};
}
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
if (! Array.isArray) {
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
};
}
// https://github.com/ttaubert/node-arraybuffer-slice
// (c) 2013 Tim Taubert <tim@timtaubert.de>

View File

@ -149,7 +149,7 @@ describe('should parse test files', function() {
it(x + ' [' + ext + ']', function(){
var wb = wbtable[dir + x];
if(!wb) wb = X.readFile(dir + x, opts);
parsetest(x, X.read(X.write(wb, {type:"buffer", bookType:ext.replace(/\./,""), bookSST: idx != 1}), {WTF:opts.WTF}), ext.replace(/\./,"") !== "xlsb", ext);
parsetest(x, X.read(X.write(wb, {type:"buffer", bookType:ext.replace(/\./,"")}), {WTF:opts.WTF}), ext.replace(/\./,"") !== "xlsb", ext);
});
});
});

@ -1 +1 @@
Subproject commit 43f12e4c2d2f040eef1828126a329ea915b3faa5
Subproject commit a4ce64aaca4f8750ba9f249ba24f6ebd502dbd15

View File

@ -6,15 +6,19 @@ calendar_stress_test.xlsb.pending
cell_style_simple.xlsb
comments_stress_test.xlsb
custom_properties.xlsb
defined_names_simple.xlsb
formula_stress_test.xlsb
formulae_test_simple.xlsb
hyperlink_stress_test_2011.xlsb
merge_cells.xlsb
named_ranges_2011.xlsb
number_format.xlsb
number_format_russian.xlsb
pivot_table_named_range.xlsb
pivot_table_test.xlsb
rich_text_stress.xlsb
smart_tags_2007.xlsb
sushi.xlsb
text_and_numbers.xlsb
xlsx-stream-d-date-cell.xlsb
2013/apachepoi_29982.xls.xlsb
@ -96,6 +100,7 @@ apachepoi_54607.xlsx
apachepoi_55640.xlsx
apachepoi_55745.xlsx
apachepoi_55850.xlsx
apachepoi_55906-MultiSheetRefs.xlsx
apachepoi_55923.xlsx
apachepoi_55924.xlsx
apachepoi_55926.xlsx
@ -107,7 +112,14 @@ apachepoi_56170.xlsx
apachepoi_56274.xlsx
apachepoi_56278.xlsx
apachepoi_56315.xlsx
apachepoi_56420.xlsx
apachepoi_56514.xlsx
apachepoi_56688_1.xlsx
apachepoi_56688_2.xlsx
apachepoi_56688_3.xlsx
apachepoi_56688_4.xlsx
apachepoi_56702.xlsx
apachepoi_56737.xlsx
apachepoi_AverageTaxRates.xlsx
apachepoi_Booleans.xlsx
apachepoi_BrNotClosed.xlsx
@ -123,6 +135,7 @@ apachepoi_FormatChoiceTests.xlsx
apachepoi_FormatConditionTests.xlsx
apachepoi_Formatting.xlsx
apachepoi_FormulaEvalTestData_Copy.xlsx
apachepoi_FormulaSheetRange.xlsx
apachepoi_GeneralFormatTests.xlsx
apachepoi_GroupTest.xlsx
apachepoi_InlineStrings.xlsx
@ -152,9 +165,12 @@ apachepoi_WithTwoCharts.xlsx
apachepoi_WithVariousData.xlsx
apachepoi_atp.xlsx
apachepoi_chart_sheet.xlsx.pending
apachepoi_commentTest.xlsx
apachepoi_comments.xlsx
apachepoi_headerFooterTest.xlsx
apachepoi_picture.xlsx
apachepoi_ref-56737.xlsx
apachepoi_ref2-56737.xlsx
apachepoi_reordered_sheets.xlsx
apachepoi_sample-beta.xlsx
apachepoi_sample.xlsx
@ -172,6 +188,7 @@ calendar_stress_test.xlsx.pending
cell_style_simple.xlsx
comments_stress_test.xlsx
custom_properties.xlsx
defined_names_simple.xlsx
excel-reader-xlsx_data01.xlsx
excel-reader-xlsx_data02.xlsx
excel-reader-xlsx_error02.xlsx.pending
@ -267,6 +284,7 @@ roo_time-test.xlsx
roo_type_excel.xlsx.pending
roo_type_openoffice.xlsx.pending
roo_whitespace.xlsx
smart_tags_2007.xlsx
spreadsheet-parsexlsx_Test.xlsx
spreadsheet-parsexlsx_bug-10.xlsx
spreadsheet-parsexlsx_bug-11.xlsx
@ -282,6 +300,10 @@ spreadsheet-parsexlsx_bug-6-2.xlsx
spreadsheet-parsexlsx_bug-6.xlsx
spreadsheet-parsexlsx_bug-7.xlsx
spreadsheet-parsexlsx_bug-8.xlsx
spreadsheet-parsexlsx_bug-lock.xlsx
spreadsheet-parsexlsx_column-formats.xlsx
spreadsheet-parsexlsx_tab-color.xlsx
sushi.xlsx
text_and_numbers.xlsx
xlrd_merged_cells.xlsx
xlrd_reveng1.xlsx
@ -297,5 +319,6 @@ apachepoi_47026.xlsm
apachepoi_47089.xlsm
apachepoi_ExcelWithAttachments.xlsm
number_format.xlsm
number_format_russian.xlsm
openpyxl_r_vba-test.xlsm
pivot_table_test.xlsm

371
xlsx.js
View File

@ -3,21 +3,24 @@
/*jshint -W041 */
var XLSX = {};
(function(XLSX){
XLSX.version = '0.7.7';
XLSX.version = '0.7.8';
var current_codepage = 1252, current_cptable;
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
current_cptable = cptable[current_codepage];
}
function reset_cp() { set_cp(1252); }
function set_cp(cp) { current_codepage = cp; if(typeof cptable !== 'undefined') current_cptable = cptable[cp]; }
var set_cp = function(cp) { current_codepage = cp; };
function char_codes(data) { var o = []; for(var i = 0; i != data.length; ++i) o[i] = data.charCodeAt(i); return o; }
function debom_xml(data) {
if(typeof cptable !== 'undefined') {
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
var debom_xml = function(data) { return data; };
if(typeof cptable !== 'undefined') {
set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
debom_xml = function(data) {
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
}
return data;
return data;
};
}
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
/*jshint -W041 */
@ -827,15 +830,17 @@ function cc2str(arr) {
for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]);
return o;
}
var has_buf = (typeof Buffer !== 'undefined');
function getdata(data) {
if(!data) return null;
if(data.name.substr(-4) === ".bin") {
if(data.data) return char_codes(data.data);
if(data.asNodeBuffer && typeof Buffer !== 'undefined') return data.asNodeBuffer();
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
} else {
if(data.data) return data.name.substr(-4) !== ".bin" ? debom_xml(data.data) : char_codes(data.data);
if(data.asNodeBuffer && typeof Buffer !== 'undefined') return debom_xml(data.asNodeBuffer().toString('binary'));
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
if(data.asBinary) return debom_xml(data.asBinary());
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
}
@ -859,12 +864,11 @@ var _fs, jszip;
if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
if(typeof Buffer !== 'undefined' && typeof jszip === 'undefined') jszip = require('jszip');
if(typeof jszip === 'undefined') jszip = require('./jszip').JSZip;
_fs = require('fs');
if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');
if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;
_fs = require('f'+'s');
}
}
var _chr = function(c) { return String.fromCharCode(c); };
var attregexg=/\b[\w:]+=["'][^"]*['"]/g;
var tagregex=/<[^>]*>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
@ -898,10 +902,10 @@ var rencoding = evert(encodings);
var rencstr = "&<>'\"".split("");
// TODO: CP remap (need to read file version to determine OS)
var encregex = /&[a-z]*;/g, coderegex = /_x([0-9a-fA-F]+)_/g;
var encregex = /&[a-z]*;/g, coderegex = /_x([\da-fA-F]+)_/g;
function unescapexml(text){
var s = text + '';
return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return _chr(parseInt(c,16));});
return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
}
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
function escapexml(text){
@ -935,7 +939,7 @@ var utf8read = function utf8reada(orig) {
};
if(typeof Buffer !== "undefined") {
if(has_buf) {
var utf8readb = function utf8readb(data) {
var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c;
for(i = 0; i < data.length; i+=j) {
@ -1044,38 +1048,37 @@ function readIEEE754(buf, idx, isLE, nl, ml) {
}
var __toBuffer, ___toBuffer;
__toBuffer = ___toBuffer = function(bufs) {
var x = [];
for(var i = 0; i != bufs[0].length; ++i) { x = x.concat(bufs[0][i]); }
return x;
};
if(typeof Buffer !== "undefined") {
__toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; };
var __double, ___double;
__double = ___double = function(b, idx) { return readIEEE754(b, idx);};
var is_buf = function is_buf_a(a) { return Array.isArray(a); };
if(has_buf) {
__toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);};
__double = function double_(b,i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); };
is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); };
}
var ___readUInt32LE = function(b, idx) { return b.readUInt32LE ? b.readUInt32LE(idx) : b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var ___readInt32LE = function(b, idx) { return (b[idx+3]<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var __readUInt8 = function(b, idx) { return b.readUInt8 ? b.readUInt8(idx) : b[idx]; };
var __readUInt16LE = function(b, idx) { return b.readUInt16LE ? b.readUInt16LE(idx) : b[idx+1]*(1<<8)+b[idx]; };
var __readInt16LE = function(b, idx) { var u = __readUInt16LE(b,idx); if(!(u & 0x8000)) return u; return (0xffff - u + 1) * -1; };
var __readUInt32LE = typeof Buffer !== "undefined" ? function(b, i) { return Buffer.isBuffer(b) ? b.readUInt32LE(i) : ___readUInt32LE(b,i); } : ___readUInt32LE;
var __readInt32LE = typeof Buffer !== "undefined" ? function(b, i) { return Buffer.isBuffer(b) ? b.readInt32LE(i) : ___readInt32LE(b,i); } : ___readInt32LE;
var __readDoubleLE = function(b, idx) { return b.readDoubleLE ? b.readDoubleLE(idx) : readIEEE754(b, idx||0);};
var __readUInt8 = function(b, idx) { return b[idx]; };
var __readUInt16LE = function(b, idx) { return b[idx+1]*(1<<8)+b[idx]; };
var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; };
var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
function ReadShift(size, t) {
var o="", oo=[], w, vv, i, loc;
if(t === 'dbcs') {
loc = this.l;
if(typeof Buffer !== 'undefined' && this instanceof Buffer) o = this.slice(this.l, this.l+2*size).toString("utf16le");
if(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString("utf16le");
else for(i = 0; i != size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; }
size *= 2;
} else switch(size) {
case 1: o = __readUInt8(this, this.l); break;
case 2: o = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); break;
case 4: o = __readUInt32LE(this, this.l); break;
case 8: if(t === 'f') { o = __readDoubleLE(this, this.l); break; }
case 8: if(t === 'f') { o = __double(this, this.l); break; }
}
this.l+=size; return o;
}
@ -1086,7 +1089,8 @@ function WriteShift(t, val, f) {
for(i = 0; i != val.length; ++i) this.writeUInt16LE(val.charCodeAt(i), this.l + 2 * i);
size = 2 * val.length;
} else switch(t) {
case 1: size = 1; this.writeUInt8(val, this.l); break;
case 1: size = 1; this[this.l] = val&255; break;
case 3: size = 3; this[this.l+2] = val & 255; val >>>= 8; this[this.l+1] = val&255; val >>>= 8; this[this.l] = val&255; break;
case 4: size = 4; this.writeUInt32LE(val, this.l); break;
case 8: size = 8; if(f === 'f') { this.writeDoubleLE(val, this.l); break; }
/* falls through */
@ -1097,7 +1101,7 @@ function WriteShift(t, val, f) {
}
function prep_blob(blob, pos) {
blob.l = pos || 0;
blob.l = pos;
blob.read_shift = ReadShift;
blob.write_shift = WriteShift;
}
@ -1107,12 +1111,11 @@ function parsenoop(blob, length) { blob.l += length; }
function writenoop(blob, length) { blob.l += length; }
function new_buf(sz) {
var o = typeof Buffer !== 'undefined' ? new Buffer(sz) : new Array(sz);
var o = has_buf ? new Buffer(sz) : new Array(sz);
prep_blob(o, 0);
return o;
}
function is_buf(a) { return (typeof Buffer !== 'undefined' && a instanceof Buffer) || Array.isArray(a); }
/* [MS-XLSB] 2.1.4 Record */
function recordhopper(data, cb, opts) {
var tmpbyte, cntbyte, length;
@ -1205,6 +1208,13 @@ function parse_RichStr(data, length) {
data.l = start + length;
return z;
}
function write_RichStr(str, o) {
/* TODO: formatted string */
if(o == null) o = new_buf(5+2*str.t.length);
o.write_shift(1,0);
write_XLWideString(str.t, o);
return o;
}
/* [MS-XLSB] 2.5.9 */
function parse_Cell(data) {
@ -1214,6 +1224,14 @@ function parse_Cell(data) {
var fPhShow = data.read_shift(1);
return { c:col, iStyleRef: iStyleRef };
}
function write_Cell(cell, o) {
if(o == null) o = new_buf(8);
o.write_shift(-4, cell.c);
o.write_shift(3, cell.iStyleRef === undefined ? cell.iStyleRef : cell.s);
o.write_shift(1, 0); /* fPhShow */
return o;
}
/* [MS-XLSB] 2.5.21 */
function parse_CodeName (data, length) { return parse_XLWideString(data, length); }
@ -1236,7 +1254,7 @@ function parse_XLWideString(data) {
return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
}
function write_XLWideString(data, o) {
if(o == null) o = new_buf(127);
if(o == null) o = new_buf(4+2*data.length);
o.write_shift(4, data.length);
if(data.length > 0) o.write_shift(0, data, 'dbcs');
return o;
@ -1253,7 +1271,7 @@ function parse_RkNumber(data) {
var fX100 = b[0] & 1, fInt = b[0] & 2;
data.l+=4;
b[0] &= 0xFC;
var RK = fInt === 0 ? __readDoubleLE([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
var RK = fInt === 0 ? __double([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2;
return fX100 ? RK/100 : RK;
}
@ -1660,14 +1678,21 @@ var CORE_PROPS = [
XMLNS.CORE_PROPS = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";
RELS.CORE_PROPS = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties';
var CORE_PROPS_REGEX = (function() {
var r = new Array(CORE_PROPS.length);
for(var i = 0; i < CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i];
var g = "(?:"+ f[0].substr(0,f[0].indexOf(":")) +":)"+ f[0].substr(f[0].indexOf(":")+1);
r[i] = new RegExp("<" + g + "[^>]*>(.*)<\/" + g + ">");
}
return r;
})();
function parse_core_props(data) {
var p = {};
for(var i = 0; i != CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i];
var g = "(?:"+ f[0].substr(0,f[0].indexOf(":")) +":)"+ f[0].substr(f[0].indexOf(":")+1);
var cur = data.match(new RegExp("<" + g + "[^>]*>(.*)<\/" + g + ">"));
for(var i = 0; i < CORE_PROPS.length; ++i) {
var f = CORE_PROPS[i], cur = data.match(CORE_PROPS_REGEX[i]);
if(cur != null && cur.length > 0) p[f[1]] = cur[1];
if(f[2] === 'date' && p[f[1]]) p[f[1]] = new Date(p[f[1]]);
}
@ -1686,7 +1711,6 @@ var CORE_PROPS_XML_ROOT = writextag('cp:coreProperties', null, {
function cp_doit(f, g, h, o, p) {
if(p[f] != null || g == null || g === "") return;
if(typeof g !== 'string') g = String(g); /* TODO: remove */
p[f] = g;
o[o.length] = (h ? writextag(f,g,h) : writetag(f,g));
}
@ -1764,13 +1788,13 @@ function write_ext_props(cp, opts) {
o[o.length] = (EXT_PROPS_XML_ROOT);
EXT_PROPS.forEach(function(f) {
if(typeof cp[f[1]] === 'undefined') return;
if(cp[f[1]] === undefined) return;
var v;
switch(f[2]) {
case 'string': v = cp[f[1]]; break;
case 'bool': v = cp[f[1]] ? 'true' : 'false'; break;
}
if(typeof v !== 'undefined') o[o.length] = (W(f[0], v));
if(v !== undefined) o[o.length] = (W(f[0], v));
});
/* TODO: HeadingPairs, TitlesOfParts */
@ -2029,7 +2053,7 @@ function parse_sst_xml(data, opts) {
}
RELS.SST = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
var straywsregex = /^\s|\s$|[\t\n\r]/;
function write_sst_xml(sst, opts) {
if(!opts.bookSST) return "";
var o = [XML_HEADER];
@ -2044,7 +2068,7 @@ function write_sst_xml(sst, opts) {
if(s.r) sitag += s.r;
else {
sitag += "<t";
if(s.t.match(/^\s|\s$|[\t\n\r]/)) sitag += ' xml:space="preserve"';
if(s.t.match(straywsregex)) sitag += ' xml:space="preserve"';
sitag += ">" + escapexml(s.t) + "</t>";
}
sitag += "</si>";
@ -2076,7 +2100,22 @@ function parse_sst_bin(data, opts) {
return s;
}
function write_sst_bin(sst, opts) { }
function write_BrtBeginSst(sst, o) {
if(!o) o = new_buf(8);
o.write_shift(4, sst.Count);
o.write_shift(4, sst.Unique);
return o;
}
var write_BrtSSTItem = write_RichStr;
function write_sst_bin(sst, opts) {
var ba = buf_array();
write_record(ba, "BrtBeginSst", write_BrtBeginSst(sst));
for(var i = 0; i < sst.length; ++i) write_record(ba, "BrtSSTItem", write_BrtSSTItem(sst[i]));
write_record(ba, "BrtEndSst");
return ba.end();
}
function hex2RGB(h) {
var o = h.substr(h[0]==="#"?1:0,6);
return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)];
@ -2194,14 +2233,14 @@ function parse_fills(t, opts) {
function parse_numFmts(t, opts) {
styles.NumberFmt = [];
var k = keys(SSF._table);
for(var i=0; i != k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]];
var m = t[0].match(tagregex);
for(i=0; i != m.length; ++i) {
for(i=0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': case '<numFmts>': break;
case '<numFmt': {
var f=unescapexml(y.formatCode), j=parseInt(y.numFmtId,10);
var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
styles.NumberFmt[j] = f; if(j>0) SSF.load(f,j);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';
@ -2214,8 +2253,8 @@ function write_numFmts(NF, opts) {
[[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) {
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
});
if(o.length === 1) return "";
o[o.length] = ("</numFmts>");
if(o.length === 2) return "";
o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">");
return o.join("");
}
@ -2259,23 +2298,29 @@ function write_cellXfs(cellXfs) {
}
/* 18.8 Styles CT_Stylesheet*/
function parse_sty_xml(data, opts) {
var parse_sty_xml= (function make_pstyx() {
var numFmtRegex = /<numFmts([^>]*)>.*<\/numFmts>/;
var cellXfRegex = /<cellXfs([^>]*)>.*<\/cellXfs>/;
var fillsRegex = /<fills([^>]*)>.*<\/fills>/;
return function parse_sty_xml(data, opts) {
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
/* numFmts CT_NumFmts ? */
if((t=data.match(/<numFmts([^>]*)>.*<\/numFmts>/))) parse_numFmts(t, opts);
if((t=data.match(numFmtRegex))) parse_numFmts(t, opts);
/* fonts CT_Fonts ? */
// if((t=data.match(/<fonts([^>]*)>.*<\/fonts>/))) parse_fonts(t, opts);
/* fills CT_Fills */
if((t=data.match(/<fills([^>]*)>.*<\/fills>/))) parse_fills(t, opts);
if((t=data.match(fillsRegex))) parse_fills(t, opts);
/* borders CT_Borders ? */
/* cellStyleXfs CT_CellStyleXfs ? */
/* cellXfs CT_CellXfs ? */
if((t=data.match(/<cellXfs([^>]*)>.*<\/cellXfs>/))) parse_cellXfs(t, opts);
if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts);
/* dxfs CT_Dxfs ? */
/* tableStyles CT_TableStyles ? */
@ -2283,7 +2328,8 @@ function parse_sty_xml(data, opts) {
/* extLst CT_ExtensionList ? */
return styles;
}
};
})();
var STYLES_XML_ROOT = writextag('styleSheet', null, {
'xmlns': XMLNS.main[0],
@ -2293,10 +2339,8 @@ var STYLES_XML_ROOT = writextag('styleSheet', null, {
RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
function write_sty_xml(wb, opts) {
var o = [], p = {}, w;
o[o.length] = (XML_HEADER);
o[o.length] = (STYLES_XML_ROOT);
if((w = write_numFmts(wb.SSF))) o[o.length] = (w);
var o = [XML_HEADER, STYLES_XML_ROOT], w;
if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
@ -2424,7 +2468,24 @@ function parse_sty_bin(data, opts) {
return styles;
}
function write_sty_bin(data, opts) { }
/* [MS-XLSB] 2.1.7.50 Styles */
function write_sty_bin(data, opts) {
var ba = buf_array();
write_record(ba, "BrtBeginStyleSheet");
/* [FMTS] */
/* [FONTS] */
/* [FILLS] */
/* [BORDERS] */
/* CELLSTYLEXFS */
/* CELLXFS*/
/* STYLES */
/* DXFS */
/* TABLESTYLES */
/* [COLORPALETTE] */
/* FRTSTYLESHEET*/
write_record(ba, "BrtEndStyleSheet");
return ba.end();
}
RELS.THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
/* 20.1.6.2 clrScheme CT_ColorScheme */
@ -2680,14 +2741,14 @@ var _ssfopts = {}; // spreadsheet formatting options
RELS.WS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
function get_sst_id(sst, str) {
for(var i = 0; i != sst.length; ++i) if(sst[i].t === str) { sst.Count ++; return i; }
sst[sst.length] = {t:str}; sst.Count ++; sst.Unique ++; return sst.length-1;
for(var i = 0, len = sst.length; i < len; ++i) if(sst[i].t === str) { sst.Count ++; return i; }
sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len;
}
function get_cell_style(styles, cell, opts) {
var z = opts.revssf[cell.z != null ? cell.z : "General"];
for(var i = 0; i != styles.length; ++i) if(styles[i].numFmtId === z) return i;
styles[styles.length] = {
for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i;
styles[len] = {
numFmtId:z,
fontId:0,
fillId:0,
@ -2695,7 +2756,7 @@ function get_cell_style(styles, cell, opts) {
xfId:0,
applyNumberFormat:1
};
return styles.length-1;
return len;
}
function safe_format(p, fmtid, fillid, opts) {
@ -2725,11 +2786,13 @@ function safe_format(p, fmtid, fillid, opts) {
}
function parse_ws_xml_dim(ws, s) {
var d = safe_decode_range(s);
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.e.r>=0) ws["!ref"] = encode_range(d);
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
}
var mergecregex = /<mergeCell ref="[A-Z0-9:]+"\s*\/>/g;
var sheetdataregex = /<(?:\w+:)?sheetData>([^\u2603]*)<\/(?:\w+:)?sheetData>/;
var hlinkregex = /<hyperlink[^>]*\/>/g;
var dimregex = /"(\w*:\w*)"/;
var colregex = /<col[^>]*\/>/g;
/* 18.3 Worksheets */
function parse_ws_xml(data, opts, rels) {
if(!data) return data;
@ -2739,7 +2802,7 @@ function parse_ws_xml(data, opts, rels) {
/* 18.3.1.35 dimension CT_SheetDimension ? */
var ridx = data.indexOf("<dimension");
if(ridx > 0) {
var ref = data.substr(ridx,50).match(/"(\w*:\w*)"/);
var ref = data.substr(ridx,50).match(dimregex);
if(ref != null) parse_ws_xml_dim(s, ref[1]);
}
@ -2755,7 +2818,7 @@ function parse_ws_xml(data, opts, rels) {
var columns = [];
if(opts.cellStyles && data.indexOf("</cols>")!==-1) {
/* 18.3.1.13 col CT_Col */
var cols = data.match(/<col[^>]*\/>/g);
var cols = data.match(colregex);
parse_ws_xml_cols(columns, cols);
}
@ -2851,15 +2914,15 @@ function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) {
var os = get_cell_style(opts.cellXfs, cell, opts);
if(os !== 0) o.s = os;
switch(cell.t) {
case 's': case 'str':
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
default:
if(opts.bookSST) {
v = writetag('v', ''+get_sst_id(opts.Strings, cell.v));
o.t = "s"; break;
}
o.t = "str"; break;
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
}
return writextag('c', v, o);
}
@ -2874,20 +2937,22 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
var tag;
var sstr;
var fmtid = 0, fillid = 0, do_format = Array.isArray(styles.CellXf), cf;
for(var marr = sdata.split(rowregex), mt = 0; mt != marr.length; ++mt) {
for(var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) {
x = marr[mt].trim();
if(x.length === 0) continue;
var xlen = x.length;
if(xlen === 0) continue;
/* 18.3.1.73 row CT_Row */
for(ri = 0; ri != x.length; ++ri) if(x.charCodeAt(ri) === 62) break; ++ri;
for(ri = 0; ri < xlen; ++ri) if(x.charCodeAt(ri) === 62) break; ++ri;
tag = parsexmltag(x.substr(0,ri), true);
if(opts.sheetRows && opts.sheetRows < +tag.r) continue;
if(guess.s.r > tag.r - 1) guess.s.r = tag.r - 1;
if(guess.e.r < tag.r - 1) guess.e.r = tag.r - 1;
var tagr = parseInt(tag.r, 10);
if(opts.sheetRows && opts.sheetRows < tagr) continue;
if(guess.s.r > tagr - 1) guess.s.r = tagr - 1;
if(guess.e.r < tagr - 1) guess.e.r = tagr - 1;
/* 18.3.1.4 c CT_Cell */
cells = x.substr(ri).split(cellregex);
for(ri = 0; ri != cells.length; ++ri) {
for(ri = 1, cellen = cells.length; ri != cellen; ++ri) {
x = cells[ri].trim();
if(x.length === 0) continue;
cref = x.match(rregex); idx = ri; i=0; cc=0;
@ -2946,7 +3011,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
cf = styles.CellXf[tag.s];
if(cf != null) {
if(cf.numFmtId != null) fmtid = cf.numFmtId;
if(opts.cellStyles && cf.fillId != undefined) fillid = cf.fillId;
if(opts.cellStyles && cf.fillId != null) fillid = cf.fillId;
}
}
safe_format(p, fmtid, fillid, opts);
@ -2956,17 +3021,17 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
}; })();
function write_ws_xml_data(ws, opts, idx, wb) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [];
for(var R = range.s.r; R <= range.e.r; ++R) {
var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R, C;
for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
for(R = range.s.r; R <= range.e.r; ++R) {
r = [];
rr = encode_row(R);
for(var C = range.s.c; C <= range.e.c; ++C) {
if(R === range.s.r) cols[C] = encode_col(C);
for(C = range.s.c; C <= range.e.c; ++C) {
ref = cols[C] + rr;
if(!ws[ref]) continue;
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb))) r.push(cell);
if(ws[ref] === undefined) continue;
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
}
if(r.length) o[o.length] = (writextag('row', r.join(""), {r:rr}));
if(r.length > 0) o[o.length] = (writextag('row', r.join(""), {r:rr}));
}
return o.join("");
}
@ -2978,13 +3043,18 @@ var WS_XML_ROOT = writextag('worksheet', null, {
function write_ws_xml(idx, opts, wb) {
var o = [XML_HEADER, WS_XML_ROOT];
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {}, sidx = 0, rdata = "";
o[o.length] = (writextag('dimension', null, {'ref': ws['!ref'] || 'A1'}));
if((ws['!cols']||[]).length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
sidx = o.length;
o[o.length] = (writextag('sheetData', null));
if(ws['!ref']) rdata = write_ws_xml_data(ws, opts, idx, wb);
if(rdata.length) o[o.length] = (rdata);
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
var ws = wb.Sheets[s];
if(ws === undefined) ws = {};
var ref = ws['!ref']; if(ref === undefined) ref = 'A1';
o[o.length] = (writextag('dimension', null, {'ref': ref}));
if(ws['!cols'] !== undefined && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
o[sidx = o.length] = '<sheetData/>';
if(ws['!ref'] !== undefined) {
rdata = write_ws_xml_data(ws, opts, idx, wb);
if(rdata.length > 0) o[o.length] = (rdata);
}
if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); }
if(o.length>2) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }
@ -3017,6 +3087,11 @@ function parse_BrtCellBlank(data, length) {
var cell = parse_Cell(data);
return [cell];
}
function write_BrtCellBlank(cell, val, o) {
if(o == null) o = new_buf(8);
return write_Cell(val, o);
}
/* [MS-XLSB] 2.4.304 BrtCellBool */
function parse_BrtCellBool(data, length) {
@ -3291,6 +3366,15 @@ function parse_ws_bin(data, opts, rels) {
case 'BrtCustomFilter': break;
case 'BrtEndCustomFilters': break;
/* Smart Tags */
case 'BrtBeginSmartTags': break;
case 'BrtBeginCellSmartTags': break;
case 'BrtBeginCellSmartTag': break;
case 'BrtCellSmartTagProperty': break;
case 'BrtEndCellSmartTag': break;
case 'BrtEndCellSmartTags': break;
case 'BrtEndSmartTags': break;
/* Cell Watch */
case 'BrtBeginCellWatches': break;
case 'BrtCellWatch': break;
@ -3324,14 +3408,47 @@ function parse_ws_bin(data, opts, rels) {
return s;
}
/* TODO: something useful -- this is a stub */
function write_ws_bin_cell(ba, cell, R, C, opts) {
if(cell.v === undefined) return "";
var vv = "";
switch(cell.t) {
case 'b': vv = cell.v ? "1" : "0"; break;
case 'n': case 'e': vv = ''+cell.v; break;
default: vv = cell.v; break;
}
var o = {r:R, c:C};
/* TODO: cell style */
o.s = get_cell_style(opts.cellXfs, cell, opts);
switch(cell.t) {
case 's': case 'str':
if(opts.bookSST) {
vv = get_sst_id(opts.Strings, cell.v);
o.t = "s"; break;
}
o.t = "str"; break;
case 'n': break;
case 'b': o.t = "b"; break;
case 'e': o.t = "e"; break;
}
write_record(ba, "BrtCellBlank", write_BrtCellBlank(cell, o));
}
function write_CELLTABLE(ba, ws, idx, opts, wb) {
var r = safe_decode_range(ws['!ref'] || "A1");
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
write_record(ba, 'BrtBeginSheetData');
for(var i = r.s.r; i <= r.e.r; ++i) {
for(var R = range.s.r; R <= range.e.r; ++R) {
rr = encode_row(R);
/* [ACCELLTABLE] */
/* BrtRowHdr */
/* *16384CELL */
for(var C = range.s.c; C <= range.e.c; ++C) {
/* *16384CELL */
if(R === range.s.r) cols[C] = encode_col(C);
ref = cols[C] + rr;
if(!ws[ref]) continue;
/* write cell */
write_ws_bin_cell(ba, ws[ref], R, C, opts);
}
}
write_record(ba, 'BrtEndSheetData');
}
@ -3483,6 +3600,7 @@ function parse_wb_defaults(wb) {
_ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904, 'date1904');
}
/* 18.2 Workbook */
var wbnsregex = /<\w+:workbook/;
function parse_wb_xml(data, opts) {
var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
var pass = false, xmlns = "xmlns";
@ -3493,7 +3611,7 @@ function parse_wb_xml(data, opts) {
/* 18.2.27 workbook CT_Workbook 1 */
case '<workbook':
if(x.match(/<\w+:workbook/)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
if(x.match(wbnsregex)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
wb.xmlns = y[xmlns];
break;
case '</workbook>': break;
@ -3704,11 +3822,18 @@ function parse_wb_bin(data, opts) {
case 'BrtBeginWebPubItem': break;
case 'BrtEndWebPubItem': break;
case 'BrtEndWebPubItems': break;*/
/* Smart Tags */
case 'BrtBeginSmartTagTypes': break;
case 'BrtSmartTagType': break;
case 'BrtEndSmartTagTypes': break;
case 'BrtFRTBegin': pass = true; break;
case 'BrtFRTArchID$': break;
case 'BrtWorkBookPr15': break;
case 'BrtFRTEnd': pass = false; break;
case 'BrtEndBook': break;
default: if(!pass) throw new Error("Unexpected record " + R.n);
default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n);
}
});
@ -4675,7 +4800,7 @@ function fix_opts_func(defaults) {
return function fix_opts(opts) {
for(var i = 0; i != defaults.length; ++i) {
var d = defaults[i];
if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1];
if(opts[d[0]] === undefined) opts[d[0]] = d[1];
if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
}
};
@ -4936,7 +5061,7 @@ function write_zip(wb, opts) {
function readSync(data, opts) {
var zip, d = data;
var o = opts||{};
if(!o.type) o.type = (typeof Buffer !== 'undefined' && data instanceof Buffer) ? "buffer" : "base64";
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
switch(o.type) {
case "base64": zip = new jszip(d, { base64:true }); break;
case "binary": zip = new jszip(d, { base64:false }); break;
@ -4999,27 +5124,28 @@ function encode_range(cs,ce) {
function safe_decode_range(range) {
var o = {s:{c:0,r:0},e:{c:0,r:0}};
var idx = 0, i = 0, cc = 0;
for(idx = 0; i != range.length; ++i) {
var len = range.length;
for(idx = 0; i < len; ++i) {
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
idx = 26*idx + cc;
}
o.s.c = --idx;
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i < len; ++i) {
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
idx = 10*idx + cc;
}
o.s.r = --idx;
if(i === range.length || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
if(i === len || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i != len; ++i) {
if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
idx = 26*idx + cc;
}
o.e.c = --idx;
for(idx = 0; i != range.length; ++i) {
for(idx = 0; i != len; ++i) {
if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
idx = 10*idx + cc;
}
@ -5042,9 +5168,9 @@ function format_cell(cell, v) {
function sheet_to_json(sheet, opts){
var val, row, range, header = 0, offset = 1, r, hdr = [], isempty, R, C, v;
var out = [];
var o = opts != null ? opts : {};
if(!sheet || !sheet["!ref"]) return out;
var raw = o.raw;
if(sheet == null || sheet["!ref"] == null) return [];
range = o.range !== undefined ? o.range : sheet["!ref"];
if(o.header === 1) header = 1;
else if(o.header === "A") header = 2;
@ -5056,7 +5182,9 @@ function sheet_to_json(sheet, opts){
}
if(header > 0) offset = 0;
var rr = encode_row(r.s.r);
var cols = [];
var cols = new Array(r.e.c-r.s.c+1);
var out = new Array(r.e.r-r.s.r-offset+1);
var outi = 0;
for(C = r.s.c; C <= r.e.c; ++C) {
cols[C] = encode_col(C);
val = sheet[cols[C] + rr];
@ -5065,7 +5193,7 @@ function sheet_to_json(sheet, opts){
case 2: hdr[C] = cols[C]; break;
case 3: hdr[C] = o.header[C - r.s.c]; break;
default:
if(!val) continue;
if(val === undefined) continue;
hdr[C] = format_cell(val);
}
}
@ -5076,7 +5204,7 @@ function sheet_to_json(sheet, opts){
row = header === 1 ? [] : Object.create({ __rowNum__ : R });
for (C = r.s.c; C <= r.e.c; ++C) {
val = sheet[cols[C] + rr];
if(!val || !val.t) continue;
if(val === undefined || val.t === undefined) continue;
v = val.v;
switch(val.t){
case 'e': continue;
@ -5085,16 +5213,17 @@ function sheet_to_json(sheet, opts){
default: throw 'unrecognized type ' + val.t;
}
if(v !== undefined) {
row[hdr[C]] = o.raw ? v : format_cell(val,v);
row[hdr[C]] = raw ? v : format_cell(val,v);
isempty = false;
}
}
if(!isempty) out.push(row);
if(isempty === false) out[outi++] = row;
}
out.length = outi;
return out;
}
function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts == null ? opts : {}); }
function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts != null ? opts : {}); }
function sheet_to_csv(sheet, opts) {
var out = "", txt = "", qreg = /"/g;
@ -5106,11 +5235,11 @@ function sheet_to_csv(sheet, opts) {
var row = "", rr = "", cols = [];
var i = 0, cc = 0, val;
var R = 0, C = 0;
for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
for(R = r.s.r; R <= r.e.r; ++R) {
row = "";
rr = encode_row(R);
for(C = r.s.c; C <= r.e.c; ++C) {
if(R === r.s.r) cols[C] = encode_col(C);
val = sheet[cols[C] + rr];
txt = val !== undefined ? ''+format_cell(val) : "";
for(i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34) {
@ -5126,13 +5255,13 @@ var make_csv = sheet_to_csv;
function sheet_to_formulae(sheet) {
var cmds, y = "", x, val="";
if(sheet == null || sheet["!ref"] == null) return "";
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [];
var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C;
cmds = new Array((r.e.r-r.s.r+1)*(r.e.c-r.s.c+1));
var i = 0;
for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
for(var R = r.s.r; R <= r.e.r; ++R) {
rr = encode_row(R);
for(var C = r.s.c; C <= r.e.c; ++C) {
if(R === r.s.r) cols[C] = encode_col(C);
for(C = r.s.c; C <= r.e.c; ++C) {
y = cols[C] + rr;
x = sheet[y];
val = "";