From 5dd16ae6405e84156789e9288d3aa4e40a6158b8 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Wed, 28 Feb 2018 05:41:49 -0500 Subject: [PATCH] version bump 0.12.3: cleanup - PtgList and old Ptg record support - fleshed out ftab constants from macrosheet support - reimplemented / fixed / removed shim functions - demo refresh --- README.md | 8 +- bits/01_version.js | 2 +- bits/20_jsutils.js | 6 +- bits/21_ziputils.js | 6 + bits/62_fxls.js | 91 +++- bits/64_ftab.js | 13 + bits/80_parseods.js | 1 + bits/85_parsezip.js | 3 +- bits/86_writezip.js | 8 +- bits/90_utils.js | 2 +- demos/altjs/Makefile | 2 +- demos/rollup/Makefile | 2 +- demos/rollup/rollup.config.js | 7 +- demos/rollup/rollup.config.node.js | 10 +- demos/rollup/rollup.config.worker.js | 7 +- dist/shim.min.js | 2 +- dist/xlsx.core.min.js | 28 +- dist/xlsx.core.min.map | 2 +- dist/xlsx.extendscript.js | 608 ++++++++++----------------- dist/xlsx.full.min.js | 32 +- dist/xlsx.full.min.map | 2 +- dist/xlsx.js | 132 +++++- dist/xlsx.min.js | 24 +- dist/xlsx.min.map | 2 +- docbits/12_optional.md | 6 +- docbits/82_util.md | 2 +- misc/docs/README.md | 8 +- package.json | 2 +- shim.js | 476 ++++++--------------- test.js | 10 +- tests.lst | 2 +- tests/base64.js | 67 +++ tests/core.js | 10 +- tests/fs_.js | 6 +- tests/index.html | 1 + tests/sauce.html | 1 + xlsx.flow.js | 132 +++++- xlsx.js | 132 +++++- 38 files changed, 963 insertions(+), 892 deletions(-) create mode 100644 tests/base64.js diff --git a/README.md b/README.md index 31e9d26..16199df 100644 --- a/README.md +++ b/README.md @@ -257,11 +257,15 @@ To use the shim, add the shim before the script tag that loads `xlsx.js`: ```html - + ``` +The script also includes `IE_LoadFile` and `IE_SaveFile` for loading and saving +files in Internet Explorer versions 6-9. The `xlsx.extendscript.js` script +bundles the shim in a format suitable for Photoshop and other Adobe products. + ## Philosophy
@@ -2050,7 +2054,7 @@ For the example sheet: ```js > var o = XLSX.utils.sheet_to_formulae(ws); -> o.filter(function(v, i) { return i % 5 === 0; }); +> [o[0], o[5], o[10], o[15], o[20]]; [ 'A1=\'S', 'F1=\'J', 'D2=4', 'B3=3', 'G3=8' ] ```
diff --git a/bits/01_version.js b/bits/01_version.js index b00391e..db2f6d3 100644 --- a/bits/01_version.js +++ b/bits/01_version.js @@ -1 +1 @@ -XLSX.version = '0.12.2'; +XLSX.version = '0.12.3'; diff --git a/bits/20_jsutils.js b/bits/20_jsutils.js index edd389d..0e6474a 100644 --- a/bits/20_jsutils.js +++ b/bits/20_jsutils.js @@ -1,4 +1,8 @@ -function keys(o/*:any*/)/*:Array*/ { return Object.keys(o); } +function keys(o/*:any*/)/*:Array*/ { + var ks = Object.keys(o), o2 = []; + for(var i = 0; i < ks.length; ++i) if(o.hasOwnProperty(ks[i])) o2.push(ks[i]); + return o2; +} function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ { var o = ([]/*:any*/), K = keys(obj); diff --git a/bits/21_ziputils.js b/bits/21_ziputils.js index 6a2b9e4..3f7c06f 100644 --- a/bits/21_ziputils.js +++ b/bits/21_ziputils.js @@ -51,6 +51,12 @@ function getzipstr(zip, file/*:string*/, safe/*:?boolean*/)/*:?string*/ { try { return getzipstr(zip, file); } catch(e) { return null; } } +function zipentries(zip) { + var k = keys(zip.files), o = []; + for(var i = 0; i < k.length; ++i) if(k[i].slice(-1) != '/') o.push(k[i]); + return o.sort(); +} + var jszip; /*:: declare var JSZip:any; */ /*global JSZip:true */ diff --git a/bits/62_fxls.js b/bits/62_fxls.js index a9f926f..c70f622 100644 --- a/bits/62_fxls.js +++ b/bits/62_fxls.js @@ -100,7 +100,7 @@ function parse_PtgArea3d(blob, length, opts) { /* [MS-XLS] 2.5.198.29 ; [MS-XLSB] 2.5.97.20 */ function parse_PtgAreaErr(blob, length, opts) { var type = (blob[blob.l++] & 0x60) >> 5; - blob.l += opts && opts.biff > 8 ? 12 : 8; + blob.l += opts && (opts.biff > 8) ? 12 : (opts.biff < 8 ? 6 : 8); return [type]; } /* [MS-XLS] 2.5.198.30 ; [MS-XLSB] 2.5.97.21 */ @@ -232,8 +232,8 @@ function parse_PtgFunc(blob, length, opts) { } /* [MS-XLS] 2.5.198.63 ; [MS-XLSB] 2.5.97.46 TODO */ function parse_PtgFuncVar(blob, length, opts) { - blob.l++; - var cparams = blob.read_shift(1), tab = opts && opts.biff <= 3 ? [0, blob.read_shift(1)]: parsetab(blob); + var type = blob[blob.l++]; + var cparams = blob.read_shift(1), tab = opts && opts.biff <= 3 ? [(type == 0x58 ? -1 : 0), blob.read_shift(1)]: parsetab(blob); return [cparams, (tab[0] === 0 ? Ftab : Cetab)[tab[1]]]; } @@ -430,12 +430,35 @@ var parse_PtgElfRw = parse_PtgElfLoc; /* [MS-XLS] 2.5.198.55 */ var parse_PtgElfRwV = parse_PtgElfLoc; -/* [MS-XLSB] 2.5.97.52 */ +/* [MS-XLSB] 2.5.97.52 TODO */ +var PtgListRT = [ + "Data", + "All", + "Headers", + "??", + "?Data2", + "??", + "?DataHeaders", + "??", + "Totals", + "??", + "??", + "??", + "?DataTotals", + "??", + "??", + "??", + "?Current" +]; function parse_PtgList(blob/*::, length, opts*/) { blob.l += 2; var ixti = blob.read_shift(2); - blob.l += 10; - return {ixti: ixti}; + var flags = blob.read_shift(2); + var idx = blob.read_shift(4); + var c = blob.read_shift(2); + var C = blob.read_shift(2); + var rt = PtgListRT[(flags >> 2) & 0x1F]; + return {ixti: ixti, coltype:(flags&0x3), rt:rt, idx:idx, c:c, C:C}; } /* [MS-XLS] 2.5.198.91 ; [MS-XLSB] 2.5.97.76 */ function parse_PtgSxName(blob/*::, length, opts*/) { @@ -443,6 +466,32 @@ function parse_PtgSxName(blob/*::, length, opts*/) { return [blob.read_shift(4)]; } +/* [XLS] old spec */ +function parse_PtgSheet(blob, length, opts) { + blob.l += 5; + blob.l += 2; + blob.l += (opts.biff == 2 ? 1 : 4); + return ["PTGSHEET"]; +} +function parse_PtgEndSheet(blob, length, opts) { + blob.l += (opts.biff == 2 ? 4 : 5); + return ["PTGENDSHEET"]; +} +function parse_PtgMemAreaN(blob/*::, length, opts*/) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var cce = blob.read_shift(2); + return [type, cce]; +} +function parse_PtgMemNoMemN(blob/*::, length, opts*/) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var cce = blob.read_shift(2); + return [type, cce]; +} +function parse_PtgAttrNoop(blob/*::, length, opts*/) { + blob.l += 4; + return [0, 0]; +} + /* [MS-XLS] 2.5.198.25 ; [MS-XLSB] 2.5.97.16 */ var PtgTypes = { /*::[*/0x01/*::]*/: { n:'PtgExp', f:parse_PtgExp }, @@ -468,6 +517,8 @@ var PtgTypes = { /*::[*/0x15/*::]*/: { n:'PtgParen', f:parseread1 }, /*::[*/0x16/*::]*/: { n:'PtgMissArg', f:parseread1 }, /*::[*/0x17/*::]*/: { n:'PtgStr', f:parse_PtgStr }, + /*::[*/0x1A/*::]*/: { n:'PtgSheet', f:parse_PtgSheet }, + /*::[*/0x1B/*::]*/: { n:'PtgEndSheet', f:parse_PtgEndSheet }, /*::[*/0x1C/*::]*/: { n:'PtgErr', f:parse_PtgErr }, /*::[*/0x1D/*::]*/: { n:'PtgBool', f:parse_PtgBool }, /*::[*/0x1E/*::]*/: { n:'PtgInt', f:parse_PtgInt }, @@ -486,6 +537,8 @@ var PtgTypes = { /*::[*/0x2B/*::]*/: { n:'PtgAreaErr', f:parse_PtgAreaErr }, /*::[*/0x2C/*::]*/: { n:'PtgRefN', f:parse_PtgRefN }, /*::[*/0x2D/*::]*/: { n:'PtgAreaN', f:parse_PtgAreaN }, + /*::[*/0x2E/*::]*/: { n:'PtgMemAreaN', f:parse_PtgMemAreaN }, + /*::[*/0x2F/*::]*/: { n:'PtgMemNoMemN', f:parse_PtgMemNoMemN }, /*::[*/0x39/*::]*/: { n:'PtgNameX', f:parse_PtgNameX }, /*::[*/0x3A/*::]*/: { n:'PtgRef3d', f:parse_PtgRef3d }, /*::[*/0x3B/*::]*/: { n:'PtgArea3d', f:parse_PtgArea3d }, @@ -509,6 +562,9 @@ var PtgDupes = { /*::[*/0x4B/*::]*/: 0x2B, /*::[*/0x6B/*::]*/: 0x2B, /*::[*/0x4C/*::]*/: 0x2C, /*::[*/0x6C/*::]*/: 0x2C, /*::[*/0x4D/*::]*/: 0x2D, /*::[*/0x6D/*::]*/: 0x2D, + /*::[*/0x4E/*::]*/: 0x2E, /*::[*/0x6E/*::]*/: 0x2E, + /*::[*/0x4F/*::]*/: 0x2F, /*::[*/0x6F/*::]*/: 0x2F, + /*::[*/0x58/*::]*/: 0x22, /*::[*/0x78/*::]*/: 0x22, /*::[*/0x59/*::]*/: 0x39, /*::[*/0x79/*::]*/: 0x39, /*::[*/0x5A/*::]*/: 0x3A, /*::[*/0x7A/*::]*/: 0x3A, /*::[*/0x5B/*::]*/: 0x3B, /*::[*/0x7B/*::]*/: 0x3B, @@ -533,6 +589,7 @@ var Ptg18 = { /*::[*/0xFF/*::]*/: {} }; var Ptg19 = { + /*::[*/0x00/*::]*/: { n:'PtgAttrNoop', f:parse_PtgAttrNoop }, /*::[*/0x01/*::]*/: { n:'PtgAttrSemi', f:parse_PtgAttrSemi }, /*::[*/0x02/*::]*/: { n:'PtgAttrIf', f:parse_PtgAttrIf }, /*::[*/0x04/*::]*/: { n:'PtgAttrChoose', f:parse_PtgAttrChoose }, @@ -589,10 +646,7 @@ function parse_Rgce(blob, length, opts) { length = target - blob.l; id = blob[blob.l]; R = PtgTypes[id]; - if(id === 0x18 || id === 0x19) { - id = blob[blob.l + 1]; - R = (id === 0x18 ? Ptg18 : Ptg19)[id]; - } + if(id === 0x18 || id === 0x19) R = (id === 0x18 ? Ptg18 : Ptg19)[blob[blob.l + 1]]; if(!R || !R.f) { /*ptgs.push*/(parsenoop(blob, length)); } // $FlowIgnore else { ptgs.push([R.n, R.f(blob, length, opts)]); } @@ -919,6 +973,18 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgAreaErr3d': /* [MS-XLS] 2.5.198.30 */ stack.push("#REF!"); break; + case 'PtgList': /* [MS-XLSB] 2.5.97.52 */ + // $FlowIgnore + stack.push("Table" + f[1].idx + "[#" + f[1].rt + "]"); + break; + + case 'PtgMemAreaN': + case 'PtgMemNoMemN': + case 'PtgAttrNoop': + case 'PtgSheet': + case 'PtgEndSheet': + break; + case 'PtgMemFunc': /* [MS-XLS] 2.5.198.72 TODO */ break; case 'PtgMemNoMem': /* [MS-XLS] 2.5.198.73 TODO */ @@ -938,13 +1004,10 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgSxName': /* [MS-XLS] 2.5.198.91 TODO -- find a test case */ throw new Error('Unrecognized Formula Token: ' + String(f)); - case 'PtgList': /* [MS-XLSB] 2.5.97.52 TODO -- find a test case */ - throw new Error('Unrecognized Formula Token: ' + String(f)); - default: throw new Error('Unrecognized Formula Token: ' + String(f)); } var PtgNonDisp = ['PtgAttrSpace', 'PtgAttrSpaceSemi', 'PtgAttrGoto']; - if(last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) { + if(opts.biff != 3) if(last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) { f = formula[0][last_sp]; var _left = true; switch(f[1][0]) { diff --git a/bits/64_ftab.js b/bits/64_ftab.js index ff0cb3d..bb3fa0b 100644 --- a/bits/64_ftab.js +++ b/bits/64_ftab.js @@ -885,6 +885,7 @@ var Ftab = { var FtabArgc = { /*::[*/0x0002/*::]*/: 1, /* ISNA */ /*::[*/0x0003/*::]*/: 1, /* ISERROR */ + /*::[*/0x000A/*::]*/: 0, /* NA */ /*::[*/0x000F/*::]*/: 1, /* SIN */ /*::[*/0x0010/*::]*/: 1, /* COS */ /*::[*/0x0011/*::]*/: 1, /* TAN */ @@ -902,6 +903,8 @@ var FtabArgc = { /*::[*/0x001F/*::]*/: 3, /* MID */ /*::[*/0x0020/*::]*/: 1, /* LEN */ /*::[*/0x0021/*::]*/: 1, /* VALUE */ + /*::[*/0x0022/*::]*/: 0, /* TRUE */ + /*::[*/0x0023/*::]*/: 0, /* FALSE */ /*::[*/0x0026/*::]*/: 1, /* NOT */ /*::[*/0x0027/*::]*/: 2, /* MOD */ /*::[*/0x0028/*::]*/: 3, /* DCOUNT */ @@ -914,6 +917,7 @@ var FtabArgc = { /*::[*/0x0030/*::]*/: 2, /* TEXT */ /*::[*/0x0035/*::]*/: 1, /* GOTO */ /*::[*/0x003D/*::]*/: 3, /* MIRR */ + /*::[*/0x003F/*::]*/: 0, /* RAND */ /*::[*/0x0041/*::]*/: 3, /* DATE */ /*::[*/0x0042/*::]*/: 3, /* TIME */ /*::[*/0x0043/*::]*/: 1, /* DAY */ @@ -923,6 +927,7 @@ var FtabArgc = { /*::[*/0x0047/*::]*/: 1, /* HOUR */ /*::[*/0x0048/*::]*/: 1, /* MINUTE */ /*::[*/0x0049/*::]*/: 1, /* SECOND */ + /*::[*/0x004A/*::]*/: 0, /* NOW */ /*::[*/0x004B/*::]*/: 1, /* AREAS */ /*::[*/0x004C/*::]*/: 1, /* ROWS */ /*::[*/0x004D/*::]*/: 1, /* COLUMNS */ @@ -931,13 +936,18 @@ var FtabArgc = { /*::[*/0x0053/*::]*/: 1, /* TRANSPOSE */ /*::[*/0x0055/*::]*/: 0, /* STEP */ /*::[*/0x0056/*::]*/: 1, /* TYPE */ + /*::[*/0x0059/*::]*/: 0, /* CALLER */ /*::[*/0x005A/*::]*/: 1, /* DEREF */ + /*::[*/0x005E/*::]*/: 0, /* ACTIVE.CELL */ + /*::[*/0x005F/*::]*/: 0, /* SELECTION */ /*::[*/0x0061/*::]*/: 2, /* ATAN2 */ /*::[*/0x0062/*::]*/: 1, /* ASIN */ /*::[*/0x0063/*::]*/: 1, /* ACOS */ /*::[*/0x0065/*::]*/: 3, /* HLOOKUP */ /*::[*/0x0066/*::]*/: 3, /* VLOOKUP */ /*::[*/0x0069/*::]*/: 1, /* ISREF */ + /*::[*/0x006A/*::]*/: 1, /* GET.FORMULA */ + /*::[*/0x006C/*::]*/: 2, /* SET.VALUE */ /*::[*/0x006F/*::]*/: 1, /* CHAR */ /*::[*/0x0070/*::]*/: 1, /* LOWER */ /*::[*/0x0071/*::]*/: 1, /* UPPER */ @@ -963,6 +973,7 @@ var FtabArgc = { /*::[*/0x008E/*::]*/: 3, /* SLN */ /*::[*/0x008F/*::]*/: 4, /* SYD */ /*::[*/0x0090/*::]*/: 4, /* DDB */ + /*::[*/0x00A1/*::]*/: 1, /* DIALOG.BOX */ /*::[*/0x00A2/*::]*/: 1, /* CLEAN */ /*::[*/0x00A3/*::]*/: 1, /* MDETERM */ /*::[*/0x00A4/*::]*/: 1, /* MINVERSE */ @@ -974,6 +985,7 @@ var FtabArgc = { /*::[*/0x00B2/*::]*/: 2, /* EXECUTE */ /*::[*/0x00B3/*::]*/: 1, /* TERMINATE */ /*::[*/0x00B8/*::]*/: 1, /* FACT */ + /*::[*/0x00BA/*::]*/: 1, /* GET.WORKSPACE */ /*::[*/0x00BD/*::]*/: 3, /* DPRODUCT */ /*::[*/0x00BE/*::]*/: 1, /* ISNONTEXT */ /*::[*/0x00C3/*::]*/: 3, /* DSTDEVP */ @@ -989,6 +1001,7 @@ var FtabArgc = { /*::[*/0x00D5/*::]*/: 2, /* ROUNDDOWN */ /*::[*/0x00D6/*::]*/: 1, /* ASC */ /*::[*/0x00D7/*::]*/: 1, /* DBCS */ + /*::[*/0x00E1/*::]*/: 0, /* END.IF */ /*::[*/0x00E5/*::]*/: 1, /* SINH */ /*::[*/0x00E6/*::]*/: 1, /* COSH */ /*::[*/0x00E7/*::]*/: 1, /* TANH */ diff --git a/bits/80_parseods.js b/bits/80_parseods.js index b41b71a..6a51acc 100644 --- a/bits/80_parseods.js +++ b/bits/80_parseods.js @@ -65,6 +65,7 @@ var parse_content_xml = (function() { if(merges.length) ws['!merges'] = merges; if(rowinfo.length) ws["!rows"] = rowinfo; sheetag.name = utf8read(sheetag['名称'] || sheetag.name); + if(typeof JSON !== 'undefined') JSON.stringify(sheetag); SheetNames.push(sheetag.name); Sheets[sheetag.name] = ws; intable = false; diff --git a/bits/85_parsezip.js b/bits/85_parsezip.js index 686e8ed..b260d7c 100644 --- a/bits/85_parsezip.js +++ b/bits/85_parsezip.js @@ -36,7 +36,6 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/ } catch(e) { if(opts.WTF) throw e; } } -var nodirs = function nodirs(x/*:string*/)/*:boolean*/{return x.slice(-1) != '/';}; function strip_front_slash(x/*:string*/)/*:string*/ { return x.charAt(0) == '/' ? x.slice(1) : x; } function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ { @@ -51,7 +50,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ { /* Numbers */ if(safegetzipfile(zip, 'Index/Document.iwa')) throw new Error('Unsupported NUMBERS file'); - var entries = keys(zip.files).filter(nodirs).sort(); + var entries = zipentries(zip); var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')/*:?any*/)); var xlsb = false; var sheets, binname; diff --git a/bits/86_writezip.js b/bits/86_writezip.js index 65e58ef..2489c34 100644 --- a/bits/86_writezip.js +++ b/bits/86_writezip.js @@ -34,8 +34,12 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ { f = "docProps/app.xml"; if(wb.Props && wb.Props.SheetNames){/* empty */} else if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames; - // $FlowIgnore - else wb.Props.SheetNames = wb.SheetNames.map(function(x,i) { return [(wb.Workbook.Sheets[i]||{}).Hidden != 2, x];}).filter(function(x) { return x[0]; }).map(function(x) { return x[1]; }); + else { + var _sn = []; + for(var _i = 0; _i < wb.SheetNames.length; ++_i) + if((wb.Workbook.Sheets[_i]||{}).Hidden != 2) _sn.push(wb.SheetNames[_i]); + wb.Props.SheetNames = _sn; + } wb.Props.Worksheets = wb.Props.SheetNames.length; zip.file(f, write_ext_props(wb.Props, opts)); ct.extprops.push(f); diff --git a/bits/90_utils.js b/bits/90_utils.js index 77db4a5..43f63b8 100644 --- a/bits/90_utils.js +++ b/bits/90_utils.js @@ -191,7 +191,7 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array*/, opts)/*:Worksheet var hdr/*:Array*/ = o.header || [], C = 0; js.forEach(function (JS, R/*:number*/) { - keys(JS).filter(function(x) { return JS.hasOwnProperty(x); }).forEach(function(k) { + keys(JS).forEach(function(k) { if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k; var v = JS[k]; var t = 'z'; diff --git a/demos/altjs/Makefile b/demos/altjs/Makefile index 21a607c..49047c4 100644 --- a/demos/altjs/Makefile +++ b/demos/altjs/Makefile @@ -40,7 +40,7 @@ SheetJSRhino.class: $(RHDEPS) javac -cp .:SheetJS.jar:rhino.jar SheetJSRhino.java rhino.jar: - if [ ! -e rhino ]; then git clone https://github.com/mozilla/rhino; fi + if [ ! -e rhino ]; then git clone --depth=1 https://github.com/mozilla/rhino; fi #if [ ! -e rhino/build/rhino*/js.jar ]; then cd rhino; ant jar; fi #cp rhino/build/rhino*/js.jar rhino.jar if [ ! -e rhino/buildGradle/libs/rhino*.jar ]; then cd rhino; ./gradlew jar; fi diff --git a/demos/rollup/Makefile b/demos/rollup/Makefile index 4041ee5..bea7264 100644 --- a/demos/rollup/Makefile +++ b/demos/rollup/Makefile @@ -20,4 +20,4 @@ worker.min.js: worker.js .PHONY: init init: @npm install rollup-plugin-node-resolve rollup-plugin-commonjs - @mkdir -p node_modules; cd node_modules; ln -s ../../../ xlsx; cd - + @mkdir -p node_modules; cd node_modules; if [ ! -e xlsx ]; then ln -s ../../../ xlsx; fi; cd - diff --git a/demos/rollup/rollup.config.js b/demos/rollup/rollup.config.js index b9a2e43..3b62c00 100644 --- a/demos/rollup/rollup.config.js +++ b/demos/rollup/rollup.config.js @@ -2,8 +2,13 @@ import resolve from 'rollup-plugin-node-resolve'; import commonjs from 'rollup-plugin-commonjs'; export default { + input: 'app.js', + output: { + file: 'rollup.js', + format: 'iife' + }, entry: 'app.js', - dest: 'rollup.js', + //dest: 'rollup.js', plugins: [ resolve({ module: false, diff --git a/demos/rollup/rollup.config.node.js b/demos/rollup/rollup.config.node.js index 0947f8f..7aaf1b1 100644 --- a/demos/rollup/rollup.config.node.js +++ b/demos/rollup/rollup.config.node.js @@ -2,12 +2,16 @@ import resolve from 'rollup-plugin-node-resolve'; import commonjs from 'rollup-plugin-commonjs'; export default { + input: 'main.js', + output: { + file: 'rollup.node.js', + format: 'cjs' + }, entry: 'main.js', - dest: 'rollup.node.js', + //dest: 'rollup.node.js', plugins: [ resolve({ - module: false, - browser: true, + module: false }), commonjs() ], diff --git a/demos/rollup/rollup.config.worker.js b/demos/rollup/rollup.config.worker.js index 61a4d33..966332c 100644 --- a/demos/rollup/rollup.config.worker.js +++ b/demos/rollup/rollup.config.worker.js @@ -2,8 +2,13 @@ import resolve from 'rollup-plugin-node-resolve'; import commonjs from 'rollup-plugin-commonjs'; export default { + input: 'xlsxworker.js', + output: { + file: 'worker.js', + format: 'iife' + }, entry: 'xlsxworker.js', - dest: 'worker.js', + //dest: 'worker.js', plugins: [ resolve({ module: false, diff --git a/dist/shim.min.js b/dist/shim.min.js index 2f669b4..4b72440 100644 --- a/dist/shim.min.js +++ b/dist/shim.min.js @@ -1,2 +1,2 @@ /* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ -if(!Object.keys){Object.keys=function(){var t=Object.prototype.hasOwnProperty,e=!{toString:null}.propertyIsEnumerable("toString"),r=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],i=r.length;return function(n){if(typeof n!=="object"&&typeof n!=="function"||n===null)throw new TypeError("Object.keys called on non-object");var o=[];for(var a in n){if(t.call(n,a))o.push(a)}if(e){for(var f=0;f>>0;if(typeof t!="function")throw new TypeError;var i=[];var n=arguments[1];for(var o=0;o>>0;if(typeof t!=="function")throw new TypeError;var i=arguments.length>=2?arguments[1]:void 0;for(var n=0;n>>0;if(typeof t!=="function"){throw new TypeError(t+" is not a function")}if(e){r=e}i=new Array(a);n=0;while(n>>0;e=+e||0;if(Math.abs(e)===Infinity){e=0}if(e<0){e+=r;if(e<0){e=0}}for(;e=r||t>=e){return new ArrayBuffer(0)}var i=Math.min(r-t,e-t);var n=new ArrayBuffer(i);var o=new Uint8Array(n);o.set(new Uint8Array(this,t,i));return n}}(function(){var t=typeof exports!="undefined"?exports:typeof self!="undefined"?self:$.global;var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function r(t){this.message=t}r.prototype=new Error;r.prototype.name="InvalidCharacterError";t.btoa||(t.btoa=function(t){var i=String(t);for(var n,o,a=0,f=e,l="";i.charAt(a|0)||(f="=",a%1);l+=f.charAt(63&n>>8-a%1*8)){o=i.charCodeAt(a+=3/4);if(o>255){throw new r("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.")}n=n<<8|o}return l});t.atob||(t.atob=function(t){var i=String(t).replace(/[=]+$/,"");if(i.length%4==1){throw new r("'atob' failed: The string to be decoded is not correctly encoded.")}for(var n=0,o,a,f=0,l="";a=i.charAt(f++);~a&&(o=n%4?o*64+a:a,n++%4)?l+=String.fromCharCode(255&o>>(-2*n&6)):0){a=e.indexOf(a)}return l})})();if(!Date.prototype.toISOString){(function(){function t(t){if(t<10){return"0"+t}return t}Date.prototype.toISOString=function(){return this.getUTCFullYear()+"-"+t(this.getUTCMonth()+1)+"-"+t(this.getUTCDate())+"T"+t(this.getUTCHours())+":"+t(this.getUTCMinutes())+":"+t(this.getUTCSeconds())+"."+(this.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z"}})()}if(typeof Uint8Array!=="undefined"&&!Uint8Array.prototype.slice)Uint8Array.prototype.slice=function(t,e){if(t<0){t+=this.length;if(t<0)t=0}if(t>=this.length)return new Uint8Array(0);if(e==null)e=this.length;if(e<0){e+=this.length;if(e<0)e=0}if(e>this.length)e=this.length;var r=new Uint8Array(e-t);while(t<=--e)r[e-t]=this[e];return r};var IE_SaveFile=function(){try{if(typeof IE_SaveFile_Impl=="undefined")document.write([' + ``` +The script also includes `IE_LoadFile` and `IE_SaveFile` for loading and saving +files in Internet Explorer versions 6-9. The `xlsx.extendscript.js` script +bundles the shim in a format suitable for Photoshop and other Adobe products. + diff --git a/docbits/82_util.md b/docbits/82_util.md index 58cbe2f..1410da1 100644 --- a/docbits/82_util.md +++ b/docbits/82_util.md @@ -254,7 +254,7 @@ For the example sheet: ```js > var o = XLSX.utils.sheet_to_formulae(ws); -> o.filter(function(v, i) { return i % 5 === 0; }); +> [o[0], o[5], o[10], o[15], o[20]]; [ 'A1=\'S', 'F1=\'J', 'D2=4', 'B3=3', 'G3=8' ] ``` diff --git a/misc/docs/README.md b/misc/docs/README.md index 698a588..a351fa3 100644 --- a/misc/docs/README.md +++ b/misc/docs/README.md @@ -245,11 +245,15 @@ To use the shim, add the shim before the script tag that loads `xlsx.js`: ```html - + ``` +The script also includes `IE_LoadFile` and `IE_SaveFile` for loading and saving +files in Internet Explorer versions 6-9. The `xlsx.extendscript.js` script +bundles the shim in a format suitable for Photoshop and other Adobe products. + ## Philosophy @@ -1889,7 +1893,7 @@ For the example sheet: ```js > var o = XLSX.utils.sheet_to_formulae(ws); -> o.filter(function(v, i) { return i % 5 === 0; }); +> [o[0], o[5], o[10], o[15], o[20]]; [ 'A1=\'S', 'F1=\'J', 'D2=4', 'B3=3', 'G3=8' ] ``` diff --git a/package.json b/package.json index 25d4ab1..86aa9e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xlsx", - "version": "0.12.2", + "version": "0.12.3", "author": "sheetjs", "description": "SheetJS Spreadsheet data parser and writer", "keywords": [ diff --git a/shim.js b/shim.js index 314f71f..45c6768 100644 --- a/shim.js +++ b/shim.js @@ -1,385 +1,143 @@ +/* shim.js (C) 2013-present SheetJS -- http://sheetjs.com */ +/* ES3/5 Compatibility shims and other utilities for older browsers. */ + // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys -if (!Object.keys) { - Object.keys = (function () { - var hasOwnProperty = Object.prototype.hasOwnProperty, - hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), - dontEnums = [ - 'toString', - 'toLocaleString', - 'valueOf', - 'hasOwnProperty', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'constructor' - ], - dontEnumsLength = dontEnums.length; +if(!Object.keys) Object.keys = (function() { + var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), + dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ], + dontEnumsLength = dontEnums.length; - return function (obj) { - if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object'); + return function(obj) { + if(typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object'); - var result = []; + var result = []; - for (var prop in obj) { - if (hasOwnProperty.call(obj, prop)) result.push(prop); - } + for(var prop in obj) if(hasOwnProperty.call(obj, prop)) result.push(prop); - if (hasDontEnumBug) { - for (var i=0; i < dontEnumsLength; i++) { - if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]); - } - } - return result; - }; - })(); -} - -// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter -if (!Array.prototype.filter) -{ - Array.prototype.filter = function(fun /*, thisp */) - { - "use strict"; - - if (this == null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (typeof fun != "function") - throw new TypeError(); - - var res = []; - var thisp = arguments[1]; - for (var i = 0; i < len; i++) - { - if (i in t) - { - var val = t[i]; // in case fun mutates this - if (fun.call(thisp, val, i, t)) - res.push(val); - } - } - - return res; + if(hasDontEnumBug) + for(var i=0; i < dontEnumsLength; ++i) + if(hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]); + return result; }; -} +})(); -// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim -if (!String.prototype.trim) { - String.prototype.trim = function () { - return this.replace(/^\s+|\s+$/g, ''); +if(!String.prototype.trim) String.prototype.trim = function() { + var s = this.replace(/^\s+/, ''); + for(var i = s.length - 1; i >=0 ; --i) if(!s.charAt(i).match(/^\s/)) return s.slice(0,i+1); + return ""; +}; + +if(!Array.prototype.forEach) Array.prototype.forEach = function(cb) { + var len = (this.length>>>0), self = (arguments[1]||void 0); + for(var i=0; i>>0), self = (arguments[1]||void 0), A = new Array(len); + for(var i=0; i>>0), i = ((arguments[1]|0)||0); + for(i<0 && (i+=len)<0 && (i=0); i9999) yr = '+' + p( y, 6); + else if(y<0) yr = '-' + p(-y, 6); + else yr = p( y, 4); + + return [ + yr, p(this.getUTCMonth()+1), p(this.getUTCDate()) + ].join('-') + 'T' + [ + p(this.getUTCHours()), p(this.getUTCMinutes()), p(this.getUTCSeconds()) + ].join(':') + '.' + p(this.getUTCMilliseconds(),3) + 'Z'; }; -} - -// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach -if (!Array.prototype.forEach) -{ - Array.prototype.forEach = function(fun /*, thisArg */) - { - "use strict"; - - if (this === void 0 || this === null) - throw new TypeError(); - - var t = Object(this); - var len = t.length >>> 0; - if (typeof fun !== "function") - throw new TypeError(); - - var thisArg = arguments.length >= 2 ? arguments[1] : void 0; - for (var i = 0; i < len; i++) - { - if (i in t) - fun.call(thisArg, t[i], i, t); - } - }; -} - -// Production steps of ECMA-262, Edition 5, 15.4.4.19 -// Reference: http://es5.github.com/#x15.4.4.19 -if (!Array.prototype.map) { - Array.prototype.map = function(callback, thisArg) { - - var T, A, k; - - if (this == null) { - throw new TypeError(" this is null or not defined"); - } - - // 1. Let O be the result of calling ToObject passing the |this| value as the argument. - var O = Object(this); - - // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length". - // 3. Let len be ToUint32(lenValue). - var len = O.length >>> 0; - - // 4. If IsCallable(callback) is false, throw a TypeError exception. - // See: http://es5.github.com/#x9.11 - if (typeof callback !== "function") { - throw new TypeError(callback + " is not a function"); - } - - // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. - if (thisArg) { - T = thisArg; - } - - // 6. Let A be a new array created as if by the expression new Array(len) where Array is - // the standard built-in constructor with that name and len is the value of len. - A = new Array(len); - - // 7. Let k be 0 - k = 0; - - // 8. Repeat, while k < len - while(k < len) { - - var kValue, mappedValue; - - // a. Let Pk be ToString(k). - // This is implicit for LHS operands of the in operator - // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. - // This step can be combined with c - // c. If kPresent is true, then - if (k in O) { - - // i. Let kValue be the result of calling the Get internal method of O with argument Pk. - kValue = O[ k ]; - - // ii. Let mappedValue be the result of calling the Call internal method of callback - // with T as the this value and argument list containing kValue, k, and O. - mappedValue = callback.call(T, kValue, k, O); - - // iii. Call the DefineOwnProperty internal method of A with arguments - // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true}, - // and false. - - // In browsers that support Object.defineProperty, use the following: - // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true }); - - // For best browser support, use the following: - A[ k ] = mappedValue; - } - // d. Increase k by 1. - k++; - } - - // 9. return A - return A; - }; -} - -// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf -if (!Array.prototype.indexOf) { - Array.prototype.indexOf = function (searchElement, fromIndex) { - if ( this === undefined || this === null ) { - throw new TypeError( '"this" is null or not defined' ); - } - - var length = this.length >>> 0; // Hack to convert object.length to a UInt32 - - fromIndex = +fromIndex || 0; - - if (Math.abs(fromIndex) === Infinity) { - fromIndex = 0; - } - - if (fromIndex < 0) { - fromIndex += length; - if (fromIndex < 0) { - fromIndex = 0; - } - } - - for (;fromIndex < length; fromIndex++) { - if (this[fromIndex] === searchElement) { - return fromIndex; - } - } - - 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 -// arraybuffer-slice may be freely distributed under the MIT license. - -"use strict"; - -if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) { - ArrayBuffer.prototype.slice = function (begin, end) { - begin = (begin|0) || 0; - var num = this.byteLength; - end = end === (void 0) ? num : (end|0); - - // Handle negative values. - if (begin < 0) begin += num; - if (end < 0) end += num; - - if (num === 0 || begin >= num || begin >= end) { - return new ArrayBuffer(0); - } - - var length = Math.min(num - begin, end - begin); - var target = new ArrayBuffer(length); - var targetArray = new Uint8Array(target); - targetArray.set(new Uint8Array(this, begin, length)); - return target; - }; -} - -// https://github.com/davidchambers/Base64.js -// (C) 2015 David Chambers -// Base64.js may be freely distributed under the Apache 2.0 License. -;(function () { - - var object = - typeof exports != 'undefined' ? exports : - typeof self != 'undefined' ? self : // #8: web workers - $.global; // #31: ExtendScript - - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - - function InvalidCharacterError(message) { - this.message = message; - } - InvalidCharacterError.prototype = new Error; - InvalidCharacterError.prototype.name = 'InvalidCharacterError'; - - // encoder - // [https://gist.github.com/999166] by [https://github.com/nignag] - object.btoa || ( - object.btoa = function (input) { - var str = String(input); - for ( - // initialize result and counter - var block, charCode, idx = 0, map = chars, output = ''; - // if the next str index does not exist: - // change the mapping table to "=" - // check if d has no fractional digits - str.charAt(idx | 0) || (map = '=', idx % 1); - // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 - output += map.charAt(63 & block >> 8 - idx % 1 * 8) - ) { - charCode = str.charCodeAt(idx += 3/4); - if (charCode > 0xFF) { - throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); - } - block = block << 8 | charCode; - } - return output; - }); - - // decoder - // [https://gist.github.com/1020396] by [https://github.com/atk] - object.atob || ( - object.atob = function (input) { - var str = String(input).replace(/[=]+$/, ''); // #31: ExtendScript bad parse of /= - if (str.length % 4 == 1) { - throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); - } - for ( - // initialize result and counters - var bc = 0, bs, buffer, idx = 0, output = ''; - // get next character - buffer = str.charAt(idx++); - // character found in table? initialize bit storage and add its ascii value; - ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, - // and if not first of each 4 characters, - // convert the first 8 bits to one ascii character - bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 - ) { - // try to find character in table (0-63, not found => -1) - buffer = chars.indexOf(buffer); - } - return output; - }); }()); - -// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString -if (!Date.prototype.toISOString) { - (function() { - - function pad(number) { - if (number < 10) { - return '0' + number; - } - return number; - } - - Date.prototype.toISOString = function() { - return this.getUTCFullYear() + - '-' + pad(this.getUTCMonth() + 1) + - '-' + pad(this.getUTCDate()) + - 'T' + pad(this.getUTCHours()) + - ':' + pad(this.getUTCMinutes()) + - ':' + pad(this.getUTCSeconds()) + - '.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) + - 'Z'; - }; - - }()); -} - -// note: MDN shim will not work in IE +if(typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) ArrayBuffer.prototype.slice = function(start, end) { + if(start == null) start = 0; + if(start < 0) { start += this.byteLength; if(start < 0) start = 0; } + if(start >= this.byteLength) return new Uint8Array(0); + if(end == null) end = this.byteLength; + if(end < 0) { end += this.byteLength; if(end < 0) end = 0; } + if(end > this.byteLength) end = this.byteLength; + if(start > end) return new Uint8Array(0); + var out = new ArrayBuffer(end - start); + var view = new Uint8Array(out); + var data = new Uint8Array(this, start, end - start) + /* IE10 should have Uint8Array#set */ + if(view.set) view.set(data); else while(start <= --end) view[end - start] = data[end]; + return out; +}; if(typeof Uint8Array !== 'undefined' && !Uint8Array.prototype.slice) Uint8Array.prototype.slice = function(start, end) { - if(start < 0) { start += this.length; if(start < 0) start = 0; } - if(start >= this.length) return new Uint8Array(0); - if(end == null) end = this.length; - if(end < 0) { end += this.length; if(end < 0) end = 0; } - if(end > this.length) end = this.length; - var out = new Uint8Array(end - start); - while(start <= --end) out[end - start] = this[end]; - return out; + if(start == null) start = 0; + if(start < 0) { start += this.length; if(start < 0) start = 0; } + if(start >= this.length) return new Uint8Array(0); + if(end == null) end = this.length; + if(end < 0) { end += this.length; if(end < 0) end = 0; } + if(end > this.length) end = this.length; + if(start > end) return new Uint8Array(0); + var out = new Uint8Array(end - start); + while(start <= --end) out[end - start] = this[end]; + return out; }; // VBScript + ActiveX fallback for IE5+ var IE_SaveFile = (function() { try { - if(typeof IE_SaveFile_Impl == "undefined") document.write([ + if(typeof IE_SaveFile_Impl == "undefined") document.write([ ' + diff --git a/tests/sauce.html b/tests/sauce.html index 4d4a63b..a4a84ee 100644 --- a/tests/sauce.html +++ b/tests/sauce.html @@ -36,6 +36,7 @@ })(); + diff --git a/xlsx.flow.js b/xlsx.flow.js index 5c5d8ca..23aaee4 100644 --- a/xlsx.flow.js +++ b/xlsx.flow.js @@ -4,7 +4,7 @@ /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ var XLSX = {}; (function make_xlsx(XLSX){ -XLSX.version = '0.12.2'; +XLSX.version = '0.12.3'; var current_codepage = 1200, current_ansi = 1252; /*:: declare var cptable:any; */ /*global cptable:true */ @@ -1954,7 +1954,11 @@ function read_binary(path/*:string*/) { } catch(e) { if(!e.message || !e.message.match(/onstruct/)) throw e; } throw new Error("Cannot access file " + path); } -function keys(o/*:any*/)/*:Array*/ { return Object.keys(o); } +function keys(o/*:any*/)/*:Array*/ { + var ks = Object.keys(o), o2 = []; + for(var i = 0; i < ks.length; ++i) if(o.hasOwnProperty(ks[i])) o2.push(ks[i]); + return o2; +} function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ { var o = ([]/*:any*/), K = keys(obj); @@ -2146,6 +2150,12 @@ function getzipstr(zip, file/*:string*/, safe/*:?boolean*/)/*:?string*/ { try { return getzipstr(zip, file); } catch(e) { return null; } } +function zipentries(zip) { + var k = keys(zip.files), o = []; + for(var i = 0; i < k.length; ++i) if(k[i].slice(-1) != '/') o.push(k[i]); + return o.sort(); +} + var jszip; /*:: declare var JSZip:any; */ /*global JSZip:true */ @@ -9468,7 +9478,7 @@ function parse_PtgArea3d(blob, length, opts) { /* [MS-XLS] 2.5.198.29 ; [MS-XLSB] 2.5.97.20 */ function parse_PtgAreaErr(blob, length, opts) { var type = (blob[blob.l++] & 0x60) >> 5; - blob.l += opts && opts.biff > 8 ? 12 : 8; + blob.l += opts && (opts.biff > 8) ? 12 : (opts.biff < 8 ? 6 : 8); return [type]; } /* [MS-XLS] 2.5.198.30 ; [MS-XLSB] 2.5.97.21 */ @@ -9600,8 +9610,8 @@ function parse_PtgFunc(blob, length, opts) { } /* [MS-XLS] 2.5.198.63 ; [MS-XLSB] 2.5.97.46 TODO */ function parse_PtgFuncVar(blob, length, opts) { - blob.l++; - var cparams = blob.read_shift(1), tab = opts && opts.biff <= 3 ? [0, blob.read_shift(1)]: parsetab(blob); + var type = blob[blob.l++]; + var cparams = blob.read_shift(1), tab = opts && opts.biff <= 3 ? [(type == 0x58 ? -1 : 0), blob.read_shift(1)]: parsetab(blob); return [cparams, (tab[0] === 0 ? Ftab : Cetab)[tab[1]]]; } @@ -9798,12 +9808,35 @@ var parse_PtgElfRw = parse_PtgElfLoc; /* [MS-XLS] 2.5.198.55 */ var parse_PtgElfRwV = parse_PtgElfLoc; -/* [MS-XLSB] 2.5.97.52 */ +/* [MS-XLSB] 2.5.97.52 TODO */ +var PtgListRT = [ + "Data", + "All", + "Headers", + "??", + "?Data2", + "??", + "?DataHeaders", + "??", + "Totals", + "??", + "??", + "??", + "?DataTotals", + "??", + "??", + "??", + "?Current" +]; function parse_PtgList(blob/*::, length, opts*/) { blob.l += 2; var ixti = blob.read_shift(2); - blob.l += 10; - return {ixti: ixti}; + var flags = blob.read_shift(2); + var idx = blob.read_shift(4); + var c = blob.read_shift(2); + var C = blob.read_shift(2); + var rt = PtgListRT[(flags >> 2) & 0x1F]; + return {ixti: ixti, coltype:(flags&0x3), rt:rt, idx:idx, c:c, C:C}; } /* [MS-XLS] 2.5.198.91 ; [MS-XLSB] 2.5.97.76 */ function parse_PtgSxName(blob/*::, length, opts*/) { @@ -9811,6 +9844,32 @@ function parse_PtgSxName(blob/*::, length, opts*/) { return [blob.read_shift(4)]; } +/* [XLS] old spec */ +function parse_PtgSheet(blob, length, opts) { + blob.l += 5; + blob.l += 2; + blob.l += (opts.biff == 2 ? 1 : 4); + return ["PTGSHEET"]; +} +function parse_PtgEndSheet(blob, length, opts) { + blob.l += (opts.biff == 2 ? 4 : 5); + return ["PTGENDSHEET"]; +} +function parse_PtgMemAreaN(blob/*::, length, opts*/) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var cce = blob.read_shift(2); + return [type, cce]; +} +function parse_PtgMemNoMemN(blob/*::, length, opts*/) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var cce = blob.read_shift(2); + return [type, cce]; +} +function parse_PtgAttrNoop(blob/*::, length, opts*/) { + blob.l += 4; + return [0, 0]; +} + /* [MS-XLS] 2.5.198.25 ; [MS-XLSB] 2.5.97.16 */ var PtgTypes = { /*::[*/0x01/*::]*/: { n:'PtgExp', f:parse_PtgExp }, @@ -9836,6 +9895,8 @@ var PtgTypes = { /*::[*/0x15/*::]*/: { n:'PtgParen', f:parseread1 }, /*::[*/0x16/*::]*/: { n:'PtgMissArg', f:parseread1 }, /*::[*/0x17/*::]*/: { n:'PtgStr', f:parse_PtgStr }, + /*::[*/0x1A/*::]*/: { n:'PtgSheet', f:parse_PtgSheet }, + /*::[*/0x1B/*::]*/: { n:'PtgEndSheet', f:parse_PtgEndSheet }, /*::[*/0x1C/*::]*/: { n:'PtgErr', f:parse_PtgErr }, /*::[*/0x1D/*::]*/: { n:'PtgBool', f:parse_PtgBool }, /*::[*/0x1E/*::]*/: { n:'PtgInt', f:parse_PtgInt }, @@ -9854,6 +9915,8 @@ var PtgTypes = { /*::[*/0x2B/*::]*/: { n:'PtgAreaErr', f:parse_PtgAreaErr }, /*::[*/0x2C/*::]*/: { n:'PtgRefN', f:parse_PtgRefN }, /*::[*/0x2D/*::]*/: { n:'PtgAreaN', f:parse_PtgAreaN }, + /*::[*/0x2E/*::]*/: { n:'PtgMemAreaN', f:parse_PtgMemAreaN }, + /*::[*/0x2F/*::]*/: { n:'PtgMemNoMemN', f:parse_PtgMemNoMemN }, /*::[*/0x39/*::]*/: { n:'PtgNameX', f:parse_PtgNameX }, /*::[*/0x3A/*::]*/: { n:'PtgRef3d', f:parse_PtgRef3d }, /*::[*/0x3B/*::]*/: { n:'PtgArea3d', f:parse_PtgArea3d }, @@ -9877,6 +9940,9 @@ var PtgDupes = { /*::[*/0x4B/*::]*/: 0x2B, /*::[*/0x6B/*::]*/: 0x2B, /*::[*/0x4C/*::]*/: 0x2C, /*::[*/0x6C/*::]*/: 0x2C, /*::[*/0x4D/*::]*/: 0x2D, /*::[*/0x6D/*::]*/: 0x2D, + /*::[*/0x4E/*::]*/: 0x2E, /*::[*/0x6E/*::]*/: 0x2E, + /*::[*/0x4F/*::]*/: 0x2F, /*::[*/0x6F/*::]*/: 0x2F, + /*::[*/0x58/*::]*/: 0x22, /*::[*/0x78/*::]*/: 0x22, /*::[*/0x59/*::]*/: 0x39, /*::[*/0x79/*::]*/: 0x39, /*::[*/0x5A/*::]*/: 0x3A, /*::[*/0x7A/*::]*/: 0x3A, /*::[*/0x5B/*::]*/: 0x3B, /*::[*/0x7B/*::]*/: 0x3B, @@ -9901,6 +9967,7 @@ var Ptg18 = { /*::[*/0xFF/*::]*/: {} }; var Ptg19 = { + /*::[*/0x00/*::]*/: { n:'PtgAttrNoop', f:parse_PtgAttrNoop }, /*::[*/0x01/*::]*/: { n:'PtgAttrSemi', f:parse_PtgAttrSemi }, /*::[*/0x02/*::]*/: { n:'PtgAttrIf', f:parse_PtgAttrIf }, /*::[*/0x04/*::]*/: { n:'PtgAttrChoose', f:parse_PtgAttrChoose }, @@ -9957,10 +10024,7 @@ function parse_Rgce(blob, length, opts) { length = target - blob.l; id = blob[blob.l]; R = PtgTypes[id]; - if(id === 0x18 || id === 0x19) { - id = blob[blob.l + 1]; - R = (id === 0x18 ? Ptg18 : Ptg19)[id]; - } + if(id === 0x18 || id === 0x19) R = (id === 0x18 ? Ptg18 : Ptg19)[blob[blob.l + 1]]; if(!R || !R.f) { /*ptgs.push*/(parsenoop(blob, length)); } // $FlowIgnore else { ptgs.push([R.n, R.f(blob, length, opts)]); } @@ -10287,6 +10351,18 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgAreaErr3d': /* [MS-XLS] 2.5.198.30 */ stack.push("#REF!"); break; + case 'PtgList': /* [MS-XLSB] 2.5.97.52 */ + // $FlowIgnore + stack.push("Table" + f[1].idx + "[#" + f[1].rt + "]"); + break; + + case 'PtgMemAreaN': + case 'PtgMemNoMemN': + case 'PtgAttrNoop': + case 'PtgSheet': + case 'PtgEndSheet': + break; + case 'PtgMemFunc': /* [MS-XLS] 2.5.198.72 TODO */ break; case 'PtgMemNoMem': /* [MS-XLS] 2.5.198.73 TODO */ @@ -10306,13 +10382,10 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgSxName': /* [MS-XLS] 2.5.198.91 TODO -- find a test case */ throw new Error('Unrecognized Formula Token: ' + String(f)); - case 'PtgList': /* [MS-XLSB] 2.5.97.52 TODO -- find a test case */ - throw new Error('Unrecognized Formula Token: ' + String(f)); - default: throw new Error('Unrecognized Formula Token: ' + String(f)); } var PtgNonDisp = ['PtgAttrSpace', 'PtgAttrSpaceSemi', 'PtgAttrGoto']; - if(last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) { + if(opts.biff != 3) if(last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) { f = formula[0][last_sp]; var _left = true; switch(f[1][0]) { @@ -11315,6 +11388,7 @@ var Ftab = { var FtabArgc = { /*::[*/0x0002/*::]*/: 1, /* ISNA */ /*::[*/0x0003/*::]*/: 1, /* ISERROR */ + /*::[*/0x000A/*::]*/: 0, /* NA */ /*::[*/0x000F/*::]*/: 1, /* SIN */ /*::[*/0x0010/*::]*/: 1, /* COS */ /*::[*/0x0011/*::]*/: 1, /* TAN */ @@ -11332,6 +11406,8 @@ var FtabArgc = { /*::[*/0x001F/*::]*/: 3, /* MID */ /*::[*/0x0020/*::]*/: 1, /* LEN */ /*::[*/0x0021/*::]*/: 1, /* VALUE */ + /*::[*/0x0022/*::]*/: 0, /* TRUE */ + /*::[*/0x0023/*::]*/: 0, /* FALSE */ /*::[*/0x0026/*::]*/: 1, /* NOT */ /*::[*/0x0027/*::]*/: 2, /* MOD */ /*::[*/0x0028/*::]*/: 3, /* DCOUNT */ @@ -11344,6 +11420,7 @@ var FtabArgc = { /*::[*/0x0030/*::]*/: 2, /* TEXT */ /*::[*/0x0035/*::]*/: 1, /* GOTO */ /*::[*/0x003D/*::]*/: 3, /* MIRR */ + /*::[*/0x003F/*::]*/: 0, /* RAND */ /*::[*/0x0041/*::]*/: 3, /* DATE */ /*::[*/0x0042/*::]*/: 3, /* TIME */ /*::[*/0x0043/*::]*/: 1, /* DAY */ @@ -11353,6 +11430,7 @@ var FtabArgc = { /*::[*/0x0047/*::]*/: 1, /* HOUR */ /*::[*/0x0048/*::]*/: 1, /* MINUTE */ /*::[*/0x0049/*::]*/: 1, /* SECOND */ + /*::[*/0x004A/*::]*/: 0, /* NOW */ /*::[*/0x004B/*::]*/: 1, /* AREAS */ /*::[*/0x004C/*::]*/: 1, /* ROWS */ /*::[*/0x004D/*::]*/: 1, /* COLUMNS */ @@ -11361,13 +11439,18 @@ var FtabArgc = { /*::[*/0x0053/*::]*/: 1, /* TRANSPOSE */ /*::[*/0x0055/*::]*/: 0, /* STEP */ /*::[*/0x0056/*::]*/: 1, /* TYPE */ + /*::[*/0x0059/*::]*/: 0, /* CALLER */ /*::[*/0x005A/*::]*/: 1, /* DEREF */ + /*::[*/0x005E/*::]*/: 0, /* ACTIVE.CELL */ + /*::[*/0x005F/*::]*/: 0, /* SELECTION */ /*::[*/0x0061/*::]*/: 2, /* ATAN2 */ /*::[*/0x0062/*::]*/: 1, /* ASIN */ /*::[*/0x0063/*::]*/: 1, /* ACOS */ /*::[*/0x0065/*::]*/: 3, /* HLOOKUP */ /*::[*/0x0066/*::]*/: 3, /* VLOOKUP */ /*::[*/0x0069/*::]*/: 1, /* ISREF */ + /*::[*/0x006A/*::]*/: 1, /* GET.FORMULA */ + /*::[*/0x006C/*::]*/: 2, /* SET.VALUE */ /*::[*/0x006F/*::]*/: 1, /* CHAR */ /*::[*/0x0070/*::]*/: 1, /* LOWER */ /*::[*/0x0071/*::]*/: 1, /* UPPER */ @@ -11393,6 +11476,7 @@ var FtabArgc = { /*::[*/0x008E/*::]*/: 3, /* SLN */ /*::[*/0x008F/*::]*/: 4, /* SYD */ /*::[*/0x0090/*::]*/: 4, /* DDB */ + /*::[*/0x00A1/*::]*/: 1, /* DIALOG.BOX */ /*::[*/0x00A2/*::]*/: 1, /* CLEAN */ /*::[*/0x00A3/*::]*/: 1, /* MDETERM */ /*::[*/0x00A4/*::]*/: 1, /* MINVERSE */ @@ -11404,6 +11488,7 @@ var FtabArgc = { /*::[*/0x00B2/*::]*/: 2, /* EXECUTE */ /*::[*/0x00B3/*::]*/: 1, /* TERMINATE */ /*::[*/0x00B8/*::]*/: 1, /* FACT */ + /*::[*/0x00BA/*::]*/: 1, /* GET.WORKSPACE */ /*::[*/0x00BD/*::]*/: 3, /* DPRODUCT */ /*::[*/0x00BE/*::]*/: 1, /* ISNONTEXT */ /*::[*/0x00C3/*::]*/: 3, /* DSTDEVP */ @@ -11419,6 +11504,7 @@ var FtabArgc = { /*::[*/0x00D5/*::]*/: 2, /* ROUNDDOWN */ /*::[*/0x00D6/*::]*/: 1, /* ASC */ /*::[*/0x00D7/*::]*/: 1, /* DBCS */ + /*::[*/0x00E1/*::]*/: 0, /* END.IF */ /*::[*/0x00E5/*::]*/: 1, /* SINH */ /*::[*/0x00E6/*::]*/: 1, /* COSH */ /*::[*/0x00E7/*::]*/: 1, /* TANH */ @@ -18025,6 +18111,7 @@ var parse_content_xml = (function() { if(merges.length) ws['!merges'] = merges; if(rowinfo.length) ws["!rows"] = rowinfo; sheetag.name = utf8read(sheetag['名称'] || sheetag.name); + if(typeof JSON !== 'undefined') JSON.stringify(sheetag); SheetNames.push(sheetag.name); Sheets[sheetag.name] = ws; intable = false; @@ -18839,7 +18926,6 @@ function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/ } catch(e) { if(opts.WTF) throw e; } } -var nodirs = function nodirs(x/*:string*/)/*:boolean*/{return x.slice(-1) != '/';}; function strip_front_slash(x/*:string*/)/*:string*/ { return x.charAt(0) == '/' ? x.slice(1) : x; } function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ { @@ -18854,7 +18940,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ { /* Numbers */ if(safegetzipfile(zip, 'Index/Document.iwa')) throw new Error('Unsupported NUMBERS file'); - var entries = keys(zip.files).filter(nodirs).sort(); + var entries = zipentries(zip); var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')/*:?any*/)); var xlsb = false; var sheets, binname; @@ -19056,8 +19142,12 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ { f = "docProps/app.xml"; if(wb.Props && wb.Props.SheetNames){/* empty */} else if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames; - // $FlowIgnore - else wb.Props.SheetNames = wb.SheetNames.map(function(x,i) { return [(wb.Workbook.Sheets[i]||{}).Hidden != 2, x];}).filter(function(x) { return x[0]; }).map(function(x) { return x[1]; }); + else { + var _sn = []; + for(var _i = 0; _i < wb.SheetNames.length; ++_i) + if((wb.Workbook.Sheets[_i]||{}).Hidden != 2) _sn.push(wb.SheetNames[_i]); + wb.Props.SheetNames = _sn; + } wb.Props.Worksheets = wb.Props.SheetNames.length; zip.file(f, write_ext_props(wb.Props, opts)); ct.extprops.push(f); @@ -19592,7 +19682,7 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array*/, opts)/*:Worksheet var hdr/*:Array*/ = o.header || [], C = 0; js.forEach(function (JS, R/*:number*/) { - keys(JS).filter(function(x) { return JS.hasOwnProperty(x); }).forEach(function(k) { + keys(JS).forEach(function(k) { if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k; var v = JS[k]; var t = 'z'; diff --git a/xlsx.js b/xlsx.js index dd1270c..58fd973 100644 --- a/xlsx.js +++ b/xlsx.js @@ -4,7 +4,7 @@ /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */ var XLSX = {}; (function make_xlsx(XLSX){ -XLSX.version = '0.12.2'; +XLSX.version = '0.12.3'; var current_codepage = 1200, current_ansi = 1252; /*global cptable:true */ if(typeof module !== "undefined" && typeof require !== 'undefined') { @@ -1879,7 +1879,11 @@ function read_binary(path) { } catch(e) { if(!e.message || !e.message.match(/onstruct/)) throw e; } throw new Error("Cannot access file " + path); } -function keys(o) { return Object.keys(o); } +function keys(o) { + var ks = Object.keys(o), o2 = []; + for(var i = 0; i < ks.length; ++i) if(o.hasOwnProperty(ks[i])) o2.push(ks[i]); + return o2; +} function evert_key(obj, key) { var o = ([]), K = keys(obj); @@ -2070,6 +2074,12 @@ function getzipstr(zip, file, safe) { try { return getzipstr(zip, file); } catch(e) { return null; } } +function zipentries(zip) { + var k = keys(zip.files), o = []; + for(var i = 0; i < k.length; ++i) if(k[i].slice(-1) != '/') o.push(k[i]); + return o.sort(); +} + var jszip; /*global JSZip:true */ if(typeof JSZip !== 'undefined') jszip = JSZip; @@ -9374,7 +9384,7 @@ function parse_PtgArea3d(blob, length, opts) { /* [MS-XLS] 2.5.198.29 ; [MS-XLSB] 2.5.97.20 */ function parse_PtgAreaErr(blob, length, opts) { var type = (blob[blob.l++] & 0x60) >> 5; - blob.l += opts && opts.biff > 8 ? 12 : 8; + blob.l += opts && (opts.biff > 8) ? 12 : (opts.biff < 8 ? 6 : 8); return [type]; } /* [MS-XLS] 2.5.198.30 ; [MS-XLSB] 2.5.97.21 */ @@ -9506,8 +9516,8 @@ function parse_PtgFunc(blob, length, opts) { } /* [MS-XLS] 2.5.198.63 ; [MS-XLSB] 2.5.97.46 TODO */ function parse_PtgFuncVar(blob, length, opts) { - blob.l++; - var cparams = blob.read_shift(1), tab = opts && opts.biff <= 3 ? [0, blob.read_shift(1)]: parsetab(blob); + var type = blob[blob.l++]; + var cparams = blob.read_shift(1), tab = opts && opts.biff <= 3 ? [(type == 0x58 ? -1 : 0), blob.read_shift(1)]: parsetab(blob); return [cparams, (tab[0] === 0 ? Ftab : Cetab)[tab[1]]]; } @@ -9704,12 +9714,35 @@ var parse_PtgElfRw = parse_PtgElfLoc; /* [MS-XLS] 2.5.198.55 */ var parse_PtgElfRwV = parse_PtgElfLoc; -/* [MS-XLSB] 2.5.97.52 */ +/* [MS-XLSB] 2.5.97.52 TODO */ +var PtgListRT = [ + "Data", + "All", + "Headers", + "??", + "?Data2", + "??", + "?DataHeaders", + "??", + "Totals", + "??", + "??", + "??", + "?DataTotals", + "??", + "??", + "??", + "?Current" +]; function parse_PtgList(blob) { blob.l += 2; var ixti = blob.read_shift(2); - blob.l += 10; - return {ixti: ixti}; + var flags = blob.read_shift(2); + var idx = blob.read_shift(4); + var c = blob.read_shift(2); + var C = blob.read_shift(2); + var rt = PtgListRT[(flags >> 2) & 0x1F]; + return {ixti: ixti, coltype:(flags&0x3), rt:rt, idx:idx, c:c, C:C}; } /* [MS-XLS] 2.5.198.91 ; [MS-XLSB] 2.5.97.76 */ function parse_PtgSxName(blob) { @@ -9717,6 +9750,32 @@ function parse_PtgSxName(blob) { return [blob.read_shift(4)]; } +/* [XLS] old spec */ +function parse_PtgSheet(blob, length, opts) { + blob.l += 5; + blob.l += 2; + blob.l += (opts.biff == 2 ? 1 : 4); + return ["PTGSHEET"]; +} +function parse_PtgEndSheet(blob, length, opts) { + blob.l += (opts.biff == 2 ? 4 : 5); + return ["PTGENDSHEET"]; +} +function parse_PtgMemAreaN(blob) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var cce = blob.read_shift(2); + return [type, cce]; +} +function parse_PtgMemNoMemN(blob) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var cce = blob.read_shift(2); + return [type, cce]; +} +function parse_PtgAttrNoop(blob) { + blob.l += 4; + return [0, 0]; +} + /* [MS-XLS] 2.5.198.25 ; [MS-XLSB] 2.5.97.16 */ var PtgTypes = { 0x01: { n:'PtgExp', f:parse_PtgExp }, @@ -9742,6 +9801,8 @@ var PtgTypes = { 0x15: { n:'PtgParen', f:parseread1 }, 0x16: { n:'PtgMissArg', f:parseread1 }, 0x17: { n:'PtgStr', f:parse_PtgStr }, +0x1A: { n:'PtgSheet', f:parse_PtgSheet }, +0x1B: { n:'PtgEndSheet', f:parse_PtgEndSheet }, 0x1C: { n:'PtgErr', f:parse_PtgErr }, 0x1D: { n:'PtgBool', f:parse_PtgBool }, 0x1E: { n:'PtgInt', f:parse_PtgInt }, @@ -9760,6 +9821,8 @@ var PtgTypes = { 0x2B: { n:'PtgAreaErr', f:parse_PtgAreaErr }, 0x2C: { n:'PtgRefN', f:parse_PtgRefN }, 0x2D: { n:'PtgAreaN', f:parse_PtgAreaN }, +0x2E: { n:'PtgMemAreaN', f:parse_PtgMemAreaN }, +0x2F: { n:'PtgMemNoMemN', f:parse_PtgMemNoMemN }, 0x39: { n:'PtgNameX', f:parse_PtgNameX }, 0x3A: { n:'PtgRef3d', f:parse_PtgRef3d }, 0x3B: { n:'PtgArea3d', f:parse_PtgArea3d }, @@ -9783,6 +9846,9 @@ var PtgDupes = { 0x4B: 0x2B, 0x6B: 0x2B, 0x4C: 0x2C, 0x6C: 0x2C, 0x4D: 0x2D, 0x6D: 0x2D, +0x4E: 0x2E, 0x6E: 0x2E, +0x4F: 0x2F, 0x6F: 0x2F, +0x58: 0x22, 0x78: 0x22, 0x59: 0x39, 0x79: 0x39, 0x5A: 0x3A, 0x7A: 0x3A, 0x5B: 0x3B, 0x7B: 0x3B, @@ -9807,6 +9873,7 @@ var Ptg18 = { 0xFF: {} }; var Ptg19 = { +0x00: { n:'PtgAttrNoop', f:parse_PtgAttrNoop }, 0x01: { n:'PtgAttrSemi', f:parse_PtgAttrSemi }, 0x02: { n:'PtgAttrIf', f:parse_PtgAttrIf }, 0x04: { n:'PtgAttrChoose', f:parse_PtgAttrChoose }, @@ -9863,10 +9930,7 @@ function parse_Rgce(blob, length, opts) { length = target - blob.l; id = blob[blob.l]; R = PtgTypes[id]; - if(id === 0x18 || id === 0x19) { - id = blob[blob.l + 1]; - R = (id === 0x18 ? Ptg18 : Ptg19)[id]; - } + if(id === 0x18 || id === 0x19) R = (id === 0x18 ? Ptg18 : Ptg19)[blob[blob.l + 1]]; if(!R || !R.f) { /*ptgs.push*/(parsenoop(blob, length)); } // $FlowIgnore else { ptgs.push([R.n, R.f(blob, length, opts)]); } @@ -10192,6 +10256,18 @@ ixti = f[1][1]; r = f[1][2]; case 'PtgAreaErr3d': /* [MS-XLS] 2.5.198.30 */ stack.push("#REF!"); break; + case 'PtgList': /* [MS-XLSB] 2.5.97.52 */ + // $FlowIgnore + stack.push("Table" + f[1].idx + "[#" + f[1].rt + "]"); + break; + + case 'PtgMemAreaN': + case 'PtgMemNoMemN': + case 'PtgAttrNoop': + case 'PtgSheet': + case 'PtgEndSheet': + break; + case 'PtgMemFunc': /* [MS-XLS] 2.5.198.72 TODO */ break; case 'PtgMemNoMem': /* [MS-XLS] 2.5.198.73 TODO */ @@ -10211,13 +10287,10 @@ ixti = f[1][1]; r = f[1][2]; case 'PtgSxName': /* [MS-XLS] 2.5.198.91 TODO -- find a test case */ throw new Error('Unrecognized Formula Token: ' + String(f)); - case 'PtgList': /* [MS-XLSB] 2.5.97.52 TODO -- find a test case */ - throw new Error('Unrecognized Formula Token: ' + String(f)); - default: throw new Error('Unrecognized Formula Token: ' + String(f)); } var PtgNonDisp = ['PtgAttrSpace', 'PtgAttrSpaceSemi', 'PtgAttrGoto']; - if(last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) { + if(opts.biff != 3) if(last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) { f = formula[0][last_sp]; var _left = true; switch(f[1][0]) { @@ -11220,6 +11293,7 @@ var Ftab = { var FtabArgc = { 0x0002: 1, /* ISNA */ 0x0003: 1, /* ISERROR */ +0x000A: 0, /* NA */ 0x000F: 1, /* SIN */ 0x0010: 1, /* COS */ 0x0011: 1, /* TAN */ @@ -11237,6 +11311,8 @@ var FtabArgc = { 0x001F: 3, /* MID */ 0x0020: 1, /* LEN */ 0x0021: 1, /* VALUE */ +0x0022: 0, /* TRUE */ +0x0023: 0, /* FALSE */ 0x0026: 1, /* NOT */ 0x0027: 2, /* MOD */ 0x0028: 3, /* DCOUNT */ @@ -11249,6 +11325,7 @@ var FtabArgc = { 0x0030: 2, /* TEXT */ 0x0035: 1, /* GOTO */ 0x003D: 3, /* MIRR */ +0x003F: 0, /* RAND */ 0x0041: 3, /* DATE */ 0x0042: 3, /* TIME */ 0x0043: 1, /* DAY */ @@ -11258,6 +11335,7 @@ var FtabArgc = { 0x0047: 1, /* HOUR */ 0x0048: 1, /* MINUTE */ 0x0049: 1, /* SECOND */ +0x004A: 0, /* NOW */ 0x004B: 1, /* AREAS */ 0x004C: 1, /* ROWS */ 0x004D: 1, /* COLUMNS */ @@ -11266,13 +11344,18 @@ var FtabArgc = { 0x0053: 1, /* TRANSPOSE */ 0x0055: 0, /* STEP */ 0x0056: 1, /* TYPE */ +0x0059: 0, /* CALLER */ 0x005A: 1, /* DEREF */ +0x005E: 0, /* ACTIVE.CELL */ +0x005F: 0, /* SELECTION */ 0x0061: 2, /* ATAN2 */ 0x0062: 1, /* ASIN */ 0x0063: 1, /* ACOS */ 0x0065: 3, /* HLOOKUP */ 0x0066: 3, /* VLOOKUP */ 0x0069: 1, /* ISREF */ +0x006A: 1, /* GET.FORMULA */ +0x006C: 2, /* SET.VALUE */ 0x006F: 1, /* CHAR */ 0x0070: 1, /* LOWER */ 0x0071: 1, /* UPPER */ @@ -11298,6 +11381,7 @@ var FtabArgc = { 0x008E: 3, /* SLN */ 0x008F: 4, /* SYD */ 0x0090: 4, /* DDB */ +0x00A1: 1, /* DIALOG.BOX */ 0x00A2: 1, /* CLEAN */ 0x00A3: 1, /* MDETERM */ 0x00A4: 1, /* MINVERSE */ @@ -11309,6 +11393,7 @@ var FtabArgc = { 0x00B2: 2, /* EXECUTE */ 0x00B3: 1, /* TERMINATE */ 0x00B8: 1, /* FACT */ +0x00BA: 1, /* GET.WORKSPACE */ 0x00BD: 3, /* DPRODUCT */ 0x00BE: 1, /* ISNONTEXT */ 0x00C3: 3, /* DSTDEVP */ @@ -11324,6 +11409,7 @@ var FtabArgc = { 0x00D5: 2, /* ROUNDDOWN */ 0x00D6: 1, /* ASC */ 0x00D7: 1, /* DBCS */ +0x00E1: 0, /* END.IF */ 0x00E5: 1, /* SINH */ 0x00E6: 1, /* COSH */ 0x00E7: 1, /* TANH */ @@ -17915,6 +18001,7 @@ var parse_content_xml = (function() { if(merges.length) ws['!merges'] = merges; if(rowinfo.length) ws["!rows"] = rowinfo; sheetag.name = utf8read(sheetag['名称'] || sheetag.name); + if(typeof JSON !== 'undefined') JSON.stringify(sheetag); SheetNames.push(sheetag.name); Sheets[sheetag.name] = ws; intable = false; @@ -18728,7 +18815,6 @@ function safe_parse_sheet(zip, path, relsPath, sheet, idx, sheetRels, sheets, st } catch(e) { if(opts.WTF) throw e; } } -var nodirs = function nodirs(x){return x.slice(-1) != '/';}; function strip_front_slash(x) { return x.charAt(0) == '/' ? x.slice(1) : x; } function parse_zip(zip, opts) { @@ -18743,7 +18829,7 @@ function parse_zip(zip, opts) { /* Numbers */ if(safegetzipfile(zip, 'Index/Document.iwa')) throw new Error('Unsupported NUMBERS file'); - var entries = keys(zip.files).filter(nodirs).sort(); + var entries = zipentries(zip); var dir = parse_ct((getzipstr(zip, '[Content_Types].xml'))); var xlsb = false; var sheets, binname; @@ -18941,8 +19027,12 @@ var zip = new jszip(); f = "docProps/app.xml"; if(wb.Props && wb.Props.SheetNames){/* empty */} else if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames; - // $FlowIgnore - else wb.Props.SheetNames = wb.SheetNames.map(function(x,i) { return [(wb.Workbook.Sheets[i]||{}).Hidden != 2, x];}).filter(function(x) { return x[0]; }).map(function(x) { return x[1]; }); + else { + var _sn = []; + for(var _i = 0; _i < wb.SheetNames.length; ++_i) + if((wb.Workbook.Sheets[_i]||{}).Hidden != 2) _sn.push(wb.SheetNames[_i]); + wb.Props.SheetNames = _sn; + } wb.Props.Worksheets = wb.Props.SheetNames.length; zip.file(f, write_ext_props(wb.Props, opts)); ct.extprops.push(f); @@ -19476,7 +19566,7 @@ function sheet_add_json(_ws, js, opts) { var hdr = o.header || [], C = 0; js.forEach(function (JS, R) { - keys(JS).filter(function(x) { return JS.hasOwnProperty(x); }).forEach(function(k) { + keys(JS).forEach(function(k) { if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k; var v = JS[k]; var t = 'z';