From 09fba37eacecdb6e7a96a1ed2f93bc971bbfa776 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Sun, 16 Apr 2017 22:08:23 -0400 Subject: [PATCH] switch to eslint - eslint pass (eliminates jshint and jscs) - moved cell reference functions to reduce forward references - themeXLSX override XLSX/XLSB/XLSM theme --- .eslintrc | 18 +++++ .npmignore | 2 + Makefile | 7 +- README.md | 3 + bits/27_csfutils.js | 76 ++++++++++++++++++++ bits/49_theme.js | 1 + bits/67_wsxml.js | 2 +- bits/90_utils.js | 76 -------------------- docbits/81_writeopts.md | 3 + xlsx.flow.js | 155 ++++++++++++++++++++-------------------- xlsx.js | 145 ++++++++++++++++++------------------- 11 files changed, 261 insertions(+), 227 deletions(-) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..20c365e --- /dev/null +++ b/.eslintrc @@ -0,0 +1,18 @@ +{ + "env": { "shared-node-browser":true }, + "globals": {}, + "parserOptions": { + "ecmaVersion": 3, + }, + "plugins": [ "html", "json" ], + "rules": { + "no-use-before-define": [ 1, { + "functions":true, "classes":true, "variables":true + }], + "no-bitwise": 0, + "curly": 0, + "comma-style": [ 2, "last" ], + "no-trailing-spaces": 2, + "comma-dangle": [ 2, "never" ] + } +} diff --git a/.npmignore b/.npmignore index 72e5e41..9b5abcd 100644 --- a/.npmignore +++ b/.npmignore @@ -28,9 +28,11 @@ tmp *.sheetjs *.exe .gitignore +.eslintrc .jshintrc CONTRIBUTING.md Makefile +make.cmd *.lst .npmignore xlsworker.js diff --git a/Makefile b/Makefile index 3e99473..9abaf2e 100644 --- a/Makefile +++ b/Makefile @@ -143,7 +143,12 @@ demo-systemjs: ## Run systemjs demo build ## Code Checking .PHONY: lint -lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks +lint: $(TARGET) $(AUXTARGETS) ## Run eslint checks + @eslint --ext .js,.njs,.json,.html,.htm $(TARGET) $(AUXTARGETS) $(CMDS) $(HTMLLINT) package.json bower.json + if [ -e $(CLOSURE) ]; then java -jar $(CLOSURE) $(REQS) $(FLOWTARGET) --jscomp_warning=reportUnknownTypes >/dev/null; fi + +.PHONY: old-lint +old-lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks @jshint --show-non-errors $(TARGET) $(AUXTARGETS) @jshint --show-non-errors $(CMDS) @jshint --show-non-errors package.json bower.json diff --git a/README.md b/README.md index c6af3df..9e225d0 100644 --- a/README.md +++ b/README.md @@ -1025,6 +1025,7 @@ The exported `write` and `writeFile` functions accept an options argument: | sheet | `""` | Name of Worksheet for single-sheet formats ** | | compression | `false` | Use ZIP compression for ZIP-based formats ** | | Props | | Override workbook properties when writing ** | +| themeXLSX | | Override theme XML when writing XLSX/XLSB/XLSM ** | - `bookSST` is slower and more memory intensive, but has better compatibility with older versions of iOS Numbers @@ -1035,6 +1036,8 @@ The exported `write` and `writeFile` functions accept an options argument: so non-Excel tools may ignore the data or blow up in the presence of dates. - `Props` is an object mirroring the workbook `Props` field. See the table from the [Workbook File Properties](#workbook-file-properties) section. +- if specified, the string from `themeXLSX` will be saved as the primary theme + for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP) ### Supported Output Formats diff --git a/bits/27_csfutils.js b/bits/27_csfutils.js index c170528..b199bd7 100644 --- a/bits/27_csfutils.js +++ b/bits/27_csfutils.js @@ -1,3 +1,79 @@ +function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; } +function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); } +function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); } +function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); } + +function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; } +function encode_col(col/*:number*/)/*:string*/ { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; } +function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); } +function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); } + +function split_cell(cstr/*:string*/)/*:Array*/ { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); } +function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; } +function encode_cell(cell/*:CellAddress*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); } +function fix_cell(cstr/*:string*/)/*:string*/ { return fix_col(fix_row(cstr)); } +function unfix_cell(cstr/*:string*/)/*:string*/ { return unfix_col(unfix_row(cstr)); } +function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } +/*# if only one arg, it is assumed to be a Range. If 2 args, both are cell addresses */ +function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ { + if(typeof ce === 'undefined' || typeof ce === 'number') { +/*:: if(!(cs instanceof Range)) throw "unreachable"; */ + return encode_range(cs.s, cs.e); + } +/*:: if((cs instanceof Range)) throw "unreachable"; */ + if(typeof cs !== 'string') cs = encode_cell((cs/*:any*/)); + if(typeof ce !== 'string') ce = encode_cell((ce/*:any*/)); +/*:: if(typeof cs !== 'string') throw "unreachable"; */ +/*:: if(typeof ce !== 'string') throw "unreachable"; */ + return cs == ce ? cs : cs + ":" + ce; +} + +function safe_decode_range(range/*:string*/)/*:Range*/ { + var o = {s:{c:0,r:0},e:{c:0,r:0}}; + var idx = 0, i = 0, cc = 0; + 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 < len; ++i) { + if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; + idx = 10*idx + cc; + } + o.s.r = --idx; + + 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 != len; ++i) { + if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break; + idx = 26*idx + cc; + } + o.e.c = --idx; + + for(idx = 0; i != len; ++i) { + if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; + idx = 10*idx + cc; + } + o.e.r = --idx; + return o; +} + +function safe_format_cell(cell/*:Cell*/, v/*:any*/) { + var q = (cell.t == 'd' && v instanceof Date); + if(cell.z != null) try { return (cell.w = SSF.format(cell.z, q ? datenum(v) : v)); } catch(e) { } + try { return (cell.w = SSF.format((cell.XF||{}).ifmt||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; } +} + +function format_cell(cell/*:Cell*/, v/*:any*/, o/*:any*/) { + if(cell == null || cell.t == null || cell.t == 'z') return ""; + if(cell.w !== undefined) return cell.w; + if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF; + if(v == undefined) return safe_format_cell(cell, cell.v, o); + return safe_format_cell(cell, v, o); +} + function sheet_to_workbook(sheet/*:Worksheet*/, opts)/*:Workbook*/ { var n = opts && opts.sheet ? opts.sheet : "Sheet1"; var sheets = {}; sheets[n] = sheet; diff --git a/bits/49_theme.js b/bits/49_theme.js index c3dd189..26b8978 100644 --- a/bits/49_theme.js +++ b/bits/49_theme.js @@ -111,6 +111,7 @@ function parse_theme_xml(data/*:string*/, opts) { } function write_theme(Themes, opts)/*:string*/ { + if(opts && opts.themeXLSX) return opts.themeXLSX; var o = [XML_HEADER]; o[o.length] = ''; o[o.length] = ''; diff --git a/bits/67_wsxml.js b/bits/67_wsxml.js index c58a3a1..633792f 100644 --- a/bits/67_wsxml.js +++ b/bits/67_wsxml.js @@ -264,7 +264,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) { } else ++tagc; for(i = 0; i != x.length; ++i) if(x.charCodeAt(i) === 62) break; ++i; tag = parsexmltag(x.substr(0,i), true); - if(!tag.r) tag.r = utils.encode_cell({r:tagr-1, c:tagc}); + if(!tag.r) tag.r = encode_cell({r:tagr-1, c:tagc}); d = x.substr(i); p = ({t:""}/*:any*/); diff --git a/bits/90_utils.js b/bits/90_utils.js index fd6d84f..9df6d87 100644 --- a/bits/90_utils.js +++ b/bits/90_utils.js @@ -1,79 +1,3 @@ -function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; } -function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); } -function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); } -function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); } - -function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; } -function encode_col(col/*:number*/)/*:string*/ { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; } -function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); } -function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); } - -function split_cell(cstr/*:string*/)/*:Array*/ { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); } -function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; } -function encode_cell(cell/*:CellAddress*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); } -function fix_cell(cstr/*:string*/)/*:string*/ { return fix_col(fix_row(cstr)); } -function unfix_cell(cstr/*:string*/)/*:string*/ { return unfix_col(unfix_row(cstr)); } -function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } -/*# if only one arg, it is assumed to be a Range. If 2 args, both are cell addresses */ -function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ { - if(typeof ce === 'undefined' || typeof ce === 'number') { -/*:: if(!(cs instanceof Range)) throw "unreachable"; */ - return encode_range(cs.s, cs.e); - } -/*:: if((cs instanceof Range)) throw "unreachable"; */ - if(typeof cs !== 'string') cs = encode_cell((cs/*:any*/)); - if(typeof ce !== 'string') ce = encode_cell((ce/*:any*/)); -/*:: if(typeof cs !== 'string') throw "unreachable"; */ -/*:: if(typeof ce !== 'string') throw "unreachable"; */ - return cs == ce ? cs : cs + ":" + ce; -} - -function safe_decode_range(range/*:string*/)/*:Range*/ { - var o = {s:{c:0,r:0},e:{c:0,r:0}}; - var idx = 0, i = 0, cc = 0; - 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 < len; ++i) { - if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; - idx = 10*idx + cc; - } - o.s.r = --idx; - - 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 != len; ++i) { - if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break; - idx = 26*idx + cc; - } - o.e.c = --idx; - - for(idx = 0; i != len; ++i) { - if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; - idx = 10*idx + cc; - } - o.e.r = --idx; - return o; -} - -function safe_format_cell(cell/*:Cell*/, v/*:any*/) { - var q = (cell.t == 'd' && v instanceof Date); - if(cell.z != null) try { return (cell.w = SSF.format(cell.z, q ? datenum(v) : v)); } catch(e) { } - try { return (cell.w = SSF.format((cell.XF||{}).ifmt||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; } -} - -function format_cell(cell/*:Cell*/, v/*:any*/, o/*:any*/) { - if(cell == null || cell.t == null || cell.t == 'z') return ""; - if(cell.w !== undefined) return cell.w; - if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF; - if(v == undefined) return safe_format_cell(cell, cell.v, o); - return safe_format_cell(cell, v, o); -} - function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/){ if(sheet == null || sheet["!ref"] == null) return []; var val = {t:'n',v:0}, header = 0, offset = 1, hdr/*:Array*/ = [], isempty = true, v=0, vv=""; diff --git a/docbits/81_writeopts.md b/docbits/81_writeopts.md index ff113ee..cda875b 100644 --- a/docbits/81_writeopts.md +++ b/docbits/81_writeopts.md @@ -11,6 +11,7 @@ The exported `write` and `writeFile` functions accept an options argument: | sheet | `""` | Name of Worksheet for single-sheet formats ** | | compression | `false` | Use ZIP compression for ZIP-based formats ** | | Props | | Override workbook properties when writing ** | +| themeXLSX | | Override theme XML when writing XLSX/XLSB/XLSM ** | - `bookSST` is slower and more memory intensive, but has better compatibility with older versions of iOS Numbers @@ -21,6 +22,8 @@ The exported `write` and `writeFile` functions accept an options argument: so non-Excel tools may ignore the data or blow up in the presence of dates. - `Props` is an object mirroring the workbook `Props` field. See the table from the [Workbook File Properties](#workbook-file-properties) section. +- if specified, the string from `themeXLSX` will be saved as the primary theme + for XLSX/XLSB/XLSM files (to `xl/theme/theme1.xml` in the ZIP) ### Supported Output Formats diff --git a/xlsx.flow.js b/xlsx.flow.js index 5d9efba..21201b9 100644 --- a/xlsx.flow.js +++ b/xlsx.flow.js @@ -2106,6 +2106,82 @@ var make_offcrypto = function(O, _crypto) { /*:: declare var crypto:any; */ make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined); +function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; } +function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); } +function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); } +function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); } + +function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; } +function encode_col(col/*:number*/)/*:string*/ { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; } +function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); } +function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); } + +function split_cell(cstr/*:string*/)/*:Array*/ { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); } +function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; } +function encode_cell(cell/*:CellAddress*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); } +function fix_cell(cstr/*:string*/)/*:string*/ { return fix_col(fix_row(cstr)); } +function unfix_cell(cstr/*:string*/)/*:string*/ { return unfix_col(unfix_row(cstr)); } +function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } +/*# if only one arg, it is assumed to be a Range. If 2 args, both are cell addresses */ +function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ { + if(typeof ce === 'undefined' || typeof ce === 'number') { +/*:: if(!(cs instanceof Range)) throw "unreachable"; */ + return encode_range(cs.s, cs.e); + } +/*:: if((cs instanceof Range)) throw "unreachable"; */ + if(typeof cs !== 'string') cs = encode_cell((cs/*:any*/)); + if(typeof ce !== 'string') ce = encode_cell((ce/*:any*/)); +/*:: if(typeof cs !== 'string') throw "unreachable"; */ +/*:: if(typeof ce !== 'string') throw "unreachable"; */ + return cs == ce ? cs : cs + ":" + ce; +} + +function safe_decode_range(range/*:string*/)/*:Range*/ { + var o = {s:{c:0,r:0},e:{c:0,r:0}}; + var idx = 0, i = 0, cc = 0; + 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 < len; ++i) { + if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; + idx = 10*idx + cc; + } + o.s.r = --idx; + + 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 != len; ++i) { + if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break; + idx = 26*idx + cc; + } + o.e.c = --idx; + + for(idx = 0; i != len; ++i) { + if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; + idx = 10*idx + cc; + } + o.e.r = --idx; + return o; +} + +function safe_format_cell(cell/*:Cell*/, v/*:any*/) { + var q = (cell.t == 'd' && v instanceof Date); + if(cell.z != null) try { return (cell.w = SSF.format(cell.z, q ? datenum(v) : v)); } catch(e) { } + try { return (cell.w = SSF.format((cell.XF||{}).ifmt||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; } +} + +function format_cell(cell/*:Cell*/, v/*:any*/, o/*:any*/) { + if(cell == null || cell.t == null || cell.t == 'z') return ""; + if(cell.w !== undefined) return cell.w; + if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF; + if(v == undefined) return safe_format_cell(cell, cell.v, o); + return safe_format_cell(cell, v, o); +} + function sheet_to_workbook(sheet/*:Worksheet*/, opts)/*:Workbook*/ { var n = opts && opts.sheet ? opts.sheet : "Sheet1"; var sheets = {}; sheets[n] = sheet; @@ -6879,6 +6955,7 @@ function parse_theme_xml(data/*:string*/, opts) { } function write_theme(Themes, opts)/*:string*/ { + if(opts && opts.themeXLSX) return opts.themeXLSX; var o = [XML_HEADER]; o[o.length] = ''; o[o.length] = ''; @@ -10144,7 +10221,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) { } else ++tagc; for(i = 0; i != x.length; ++i) if(x.charCodeAt(i) === 62) break; ++i; tag = parsexmltag(x.substr(0,i), true); - if(!tag.r) tag.r = utils.encode_cell({r:tagr-1, c:tagc}); + if(!tag.r) tag.r = encode_cell({r:tagr-1, c:tagc}); d = x.substr(i); p = ({t:""}/*:any*/); @@ -16319,82 +16396,6 @@ function writeFileAsync(filename/*:string*/, wb/*:Workbook*/, opts/*:?WriteFileO var _cb = cb; if(!(_cb instanceof Function)) _cb = (opts/*:any*/); return _fs.writeFile(filename, writeSync(wb, o), _cb); } -function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; } -function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); } -function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); } -function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); } - -function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; } -function encode_col(col/*:number*/)/*:string*/ { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; } -function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); } -function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); } - -function split_cell(cstr/*:string*/)/*:Array*/ { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); } -function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; } -function encode_cell(cell/*:CellAddress*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); } -function fix_cell(cstr/*:string*/)/*:string*/ { return fix_col(fix_row(cstr)); } -function unfix_cell(cstr/*:string*/)/*:string*/ { return unfix_col(unfix_row(cstr)); } -function decode_range(range/*:string*/)/*:Range*/ { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } -/*# if only one arg, it is assumed to be a Range. If 2 args, both are cell addresses */ -function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ { - if(typeof ce === 'undefined' || typeof ce === 'number') { -/*:: if(!(cs instanceof Range)) throw "unreachable"; */ - return encode_range(cs.s, cs.e); - } -/*:: if((cs instanceof Range)) throw "unreachable"; */ - if(typeof cs !== 'string') cs = encode_cell((cs/*:any*/)); - if(typeof ce !== 'string') ce = encode_cell((ce/*:any*/)); -/*:: if(typeof cs !== 'string') throw "unreachable"; */ -/*:: if(typeof ce !== 'string') throw "unreachable"; */ - return cs == ce ? cs : cs + ":" + ce; -} - -function safe_decode_range(range/*:string*/)/*:Range*/ { - var o = {s:{c:0,r:0},e:{c:0,r:0}}; - var idx = 0, i = 0, cc = 0; - 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 < len; ++i) { - if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; - idx = 10*idx + cc; - } - o.s.r = --idx; - - 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 != len; ++i) { - if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break; - idx = 26*idx + cc; - } - o.e.c = --idx; - - for(idx = 0; i != len; ++i) { - if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; - idx = 10*idx + cc; - } - o.e.r = --idx; - return o; -} - -function safe_format_cell(cell/*:Cell*/, v/*:any*/) { - var q = (cell.t == 'd' && v instanceof Date); - if(cell.z != null) try { return (cell.w = SSF.format(cell.z, q ? datenum(v) : v)); } catch(e) { } - try { return (cell.w = SSF.format((cell.XF||{}).ifmt||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; } -} - -function format_cell(cell/*:Cell*/, v/*:any*/, o/*:any*/) { - if(cell == null || cell.t == null || cell.t == 'z') return ""; - if(cell.w !== undefined) return cell.w; - if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF; - if(v == undefined) return safe_format_cell(cell, cell.v, o); - return safe_format_cell(cell, v, o); -} - function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/){ if(sheet == null || sheet["!ref"] == null) return []; var val = {t:'n',v:0}, header = 0, offset = 1, hdr/*:Array*/ = [], isempty = true, v=0, vv=""; diff --git a/xlsx.js b/xlsx.js index de3e062..7a60fba 100644 --- a/xlsx.js +++ b/xlsx.js @@ -2052,6 +2052,77 @@ var make_offcrypto = function(O, _crypto) { }; make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined); +function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; } +function encode_row(row) { return "" + (row + 1); } +function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); } +function unfix_row(cstr) { return cstr.replace(/\$(\d+)$/,"$1"); } + +function decode_col(colstr) { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; } +function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; } +function fix_col(cstr) { return cstr.replace(/^([A-Z])/,"$$$1"); } +function unfix_col(cstr) { return cstr.replace(/^\$([A-Z])/,"$1"); } + +function split_cell(cstr) { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); } +function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; } +function encode_cell(cell) { return encode_col(cell.c) + encode_row(cell.r); } +function fix_cell(cstr) { return fix_col(fix_row(cstr)); } +function unfix_cell(cstr) { return unfix_col(unfix_row(cstr)); } +function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } +function encode_range(cs,ce) { + if(typeof ce === 'undefined' || typeof ce === 'number') { +return encode_range(cs.s, cs.e); + } +if(typeof cs !== 'string') cs = encode_cell((cs)); + if(typeof ce !== 'string') ce = encode_cell((ce)); +return cs == ce ? cs : 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; + 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 < len; ++i) { + if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; + idx = 10*idx + cc; + } + o.s.r = --idx; + + 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 != len; ++i) { + if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break; + idx = 26*idx + cc; + } + o.e.c = --idx; + + for(idx = 0; i != len; ++i) { + if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; + idx = 10*idx + cc; + } + o.e.r = --idx; + return o; +} + +function safe_format_cell(cell, v) { + var q = (cell.t == 'd' && v instanceof Date); + if(cell.z != null) try { return (cell.w = SSF.format(cell.z, q ? datenum(v) : v)); } catch(e) { } + try { return (cell.w = SSF.format((cell.XF||{}).ifmt||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; } +} + +function format_cell(cell, v, o) { + if(cell == null || cell.t == null || cell.t == 'z') return ""; + if(cell.w !== undefined) return cell.w; + if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF; + if(v == undefined) return safe_format_cell(cell, cell.v, o); + return safe_format_cell(cell, v, o); +} + function sheet_to_workbook(sheet, opts) { var n = opts && opts.sheet ? opts.sheet : "Sheet1"; var sheets = {}; sheets[n] = sheet; @@ -6823,6 +6894,7 @@ function parse_theme_xml(data, opts) { } function write_theme(Themes, opts) { + if(opts && opts.themeXLSX) return opts.themeXLSX; var o = [XML_HEADER]; o[o.length] = ''; o[o.length] = ''; @@ -10087,7 +10159,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) { } else ++tagc; for(i = 0; i != x.length; ++i) if(x.charCodeAt(i) === 62) break; ++i; tag = parsexmltag(x.substr(0,i), true); - if(!tag.r) tag.r = utils.encode_cell({r:tagr-1, c:tagc}); + if(!tag.r) tag.r = encode_cell({r:tagr-1, c:tagc}); d = x.substr(i); p = ({t:""}); @@ -16254,77 +16326,6 @@ function writeFileAsync(filename, wb, opts, cb) { var _cb = cb; if(!(_cb instanceof Function)) _cb = (opts); return _fs.writeFile(filename, writeSync(wb, o), _cb); } -function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; } -function encode_row(row) { return "" + (row + 1); } -function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); } -function unfix_row(cstr) { return cstr.replace(/\$(\d+)$/,"$1"); } - -function decode_col(colstr) { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; } -function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; } -function fix_col(cstr) { return cstr.replace(/^([A-Z])/,"$$$1"); } -function unfix_col(cstr) { return cstr.replace(/^\$([A-Z])/,"$1"); } - -function split_cell(cstr) { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); } -function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; } -function encode_cell(cell) { return encode_col(cell.c) + encode_row(cell.r); } -function fix_cell(cstr) { return fix_col(fix_row(cstr)); } -function unfix_cell(cstr) { return unfix_col(unfix_row(cstr)); } -function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } -function encode_range(cs,ce) { - if(typeof ce === 'undefined' || typeof ce === 'number') { -return encode_range(cs.s, cs.e); - } -if(typeof cs !== 'string') cs = encode_cell((cs)); - if(typeof ce !== 'string') ce = encode_cell((ce)); -return cs == ce ? cs : 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; - 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 < len; ++i) { - if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; - idx = 10*idx + cc; - } - o.s.r = --idx; - - 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 != len; ++i) { - if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break; - idx = 26*idx + cc; - } - o.e.c = --idx; - - for(idx = 0; i != len; ++i) { - if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; - idx = 10*idx + cc; - } - o.e.r = --idx; - return o; -} - -function safe_format_cell(cell, v) { - var q = (cell.t == 'd' && v instanceof Date); - if(cell.z != null) try { return (cell.w = SSF.format(cell.z, q ? datenum(v) : v)); } catch(e) { } - try { return (cell.w = SSF.format((cell.XF||{}).ifmt||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; } -} - -function format_cell(cell, v, o) { - if(cell == null || cell.t == null || cell.t == 'z') return ""; - if(cell.w !== undefined) return cell.w; - if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF; - if(v == undefined) return safe_format_cell(cell, cell.v, o); - return safe_format_cell(cell, v, o); -} - function sheet_to_json(sheet, opts){ if(sheet == null || sheet["!ref"] == null) return []; var val = {t:'n',v:0}, header = 0, offset = 1, hdr = [], isempty = true, v=0, vv="";