From 2cb06e0fb8796523642df283272b96115acbc46d Mon Sep 17 00:00:00 2001 From: SheetJS Date: Fri, 14 Feb 2014 01:25:46 -0500 Subject: [PATCH] version bump 0.5.6: custom properties - custom properties (h/t @hmalphettes) - new option bookProps - added minified target (using uglify-js) --- Makefile | 6 +++++- README.md | 2 ++ bits/31_version.js | 2 +- bits/78_wbbin.js | 7 ++++++- bits/84_defaults.js | 1 + bits/85_parsezip.js | 18 ++++++++++++------ package.json | 3 ++- test.js | 29 +++++++++++++++++++++++++++-- tests.lst | 2 ++ tests/files | 2 +- xlsx.js | 28 ++++++++++++++++++++-------- 11 files changed, 79 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 5cb612f..642d5d9 100644 --- a/Makefile +++ b/Makefile @@ -40,9 +40,13 @@ lint: $(TARGET) .PHONY: cov cov: misc/coverage.html -misc/coverage.html: xlsx.js +misc/coverage.html: xlsx.js test.js mocha --require blanket -R html-cov > misc/coverage.html .PHONY: coveralls coveralls: mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js + +.PHONY: dist +dist: xlsx.js + uglifyjs xlsx.js -o dist/xlsx.min.js --source-map dist/xlsx.min.map --preamble "$$(head -n 1 bits/00_header.js)" diff --git a/README.md b/README.md index 2344268..e6e3cca 100644 --- a/README.md +++ b/README.md @@ -79,12 +79,14 @@ The exported `read` and `readFile` functions accept an options argument: | cellHTML | true | Parse rich text and save HTML to the .h field | | cellNF | false | Save number format string to the .z field | | sheetStubs | false | Create cell objects for stub cells | +| bookProps | false | If true, only parse enough to get book metadata ** | | bookSheets | false | If true, only parse enough to get the sheet names | - `cellFormula` only applies to constructing XLSB formulae. XLSX/XLSM formulae are stored in plaintext, but XLSB formulae are stored in a binary format. - Even if `cellNF` is false, formatted text (.w) will be generated - In some cases, sheets may be parsed even if `bookSheets` is false. +- `bookSheets` and `bookProps` combine to give both sets of information The defaults are enumerated in bits/84_defaults.js diff --git a/bits/31_version.js b/bits/31_version.js index d5ceec5..70a5ece 100644 --- a/bits/31_version.js +++ b/bits/31_version.js @@ -1 +1 @@ -XLSX.version = '0.5.5'; +XLSX.version = '0.5.6'; diff --git a/bits/78_wbbin.js b/bits/78_wbbin.js index 55085a3..caf7ddb 100644 --- a/bits/78_wbbin.js +++ b/bits/78_wbbin.js @@ -25,6 +25,12 @@ var parse_wb_bin = function(data) { case 'BrtEndBookViews': break; case 'BrtBeginBundleShs': break; case 'BrtEndBundleShs': break; + case 'BrtBeginFnGroup': break; + case 'BrtEndFnGroup': break; + case 'BrtBeginExternals': break; + case 'BrtSupSelf': break; + case 'BrtExternSheet': break; + case 'BrtEndExternals': break; case 'BrtName': break; case 'BrtCalcProp': break; case 'BrtBeginPivotCacheIDs': break; @@ -35,7 +41,6 @@ var parse_wb_bin = function(data) { case 'BrtFRTBegin': pass = true; break; case 'BrtFRTEnd': pass = false; break; case 'BrtEndBook': break; - case '': break; //default: if(!pass) throw new Error("Unexpected record " + R.n); } }); diff --git a/bits/84_defaults.js b/bits/84_defaults.js index 094938c..ff9c5ea 100644 --- a/bits/84_defaults.js +++ b/bits/84_defaults.js @@ -7,6 +7,7 @@ function fixopts(opts) { ['sheetStubs', false], /* emit empty cells */ ['bookSheets', false], /* only try to get sheet names (no Sheets) */ + ['bookProps', false], /* only try to get properties (no Sheets) */ ['WTF', false] /* WTF mode (do not use) */ ]; diff --git a/bits/85_parsezip.js b/bits/85_parsezip.js index d2989de..bb57abd 100644 --- a/bits/85_parsezip.js +++ b/bits/85_parsezip.js @@ -13,7 +13,7 @@ function parseZip(zip, opts) { xlsb = true; } - if(!opts.bookSheets) { + if(!opts.bookSheets && !opts.bookProps) { strs = {}; if(dir.sst) strs=parse_sst(getdata(getzipfile(zip, dir.sst.replace(/^\//,''))), dir.sst, opts); @@ -29,17 +29,23 @@ function parseZip(zip, opts) { propdata += dir.extprops.length !== 0 ? getdata(getzipfile(zip, dir.extprops[0].replace(/^\//,''))) : ""; props = propdata !== "" ? parseProps(propdata) : {}; } catch(e) { } + var custprops = {}; - if (dir.custprops.length !== 0) { - try { + if(!opts.bookSheets || opts.bookProps) { + if (dir.custprops.length !== 0) try { propdata = getdata(getzipfile(zip, dir.custprops[0].replace(/^\//,''))); custprops = parseCustomProps(propdata); } catch(e) {/*console.error(e);*/} } - if(opts.bookSheets) { - if(props.Worksheets && props.SheetNames.length > 0) return { SheetNames:props.SheetNames }; - else if(wb.Sheets) return { SheetNames:wb.Sheets.map(function(x) { return x.name; }) }; + var out = {}; + if(opts.bookSheets || opts.bookProps) { + var sheets; + if(props.Worksheets && props.SheetNames.length > 0) sheets=props.SheetNames; + else if(wb.Sheets) sheets = wb.Sheets.map(function(x){ return x.name; }); + if(opts.bookProps) { out.Props = props; out.Custprops = custprops; } + if(typeof sheets !== 'undefined') out.SheetNames = sheets; + if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out; } var deps = {}; diff --git a/package.json b/package.json index 1361ab8..3c4d11b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xlsx", - "version": "0.5.5", + "version": "0.5.6", "author": "sheetjs", "description": "XLSB / XLSX / XLSM parser", "keywords": [ "xlsx", "xlsb", "xlsm", "office", "excel", "spreadsheet" ], @@ -16,6 +16,7 @@ }, "devDependencies": { "mocha":"", + "uglify-js":"", "jasmine-node": "x" }, "repository": { "type":"git", "url":"git://github.com/SheetJS/js-xlsx.git" }, diff --git a/test.js b/test.js index ce5cbe1..1e5b513 100644 --- a/test.js +++ b/test.js @@ -157,13 +157,38 @@ describe('options', function() { }); }); }); + describe('book', function() { + it('bookSheets should not generate sheets', function() { + var wb = XLSX.readFile('./test_files/merge_cells.xlsx', {bookSheets:true}); + assert(typeof wb.Sheets === 'undefined'); + }); + it('bookProps should not generate sheets', function() { + var wb = XLSX.readFile('./test_files/number_format.xlsb', {bookProps:true}); + assert(typeof wb.Sheets === 'undefined'); + }); + it('bookProps && bookSheets should not generate sheets', function() { + var wb = XLSX.readFile('./test_files/LONumbers.xlsx', {bookProps:true, bookSheets:true}); + assert(typeof wb.Sheets === 'undefined'); + }); + }); }); -describe.skip('should have core properties and custom properties parsed', function() { +describe('input formats', function() { + it('should read binary strings', function() { + XLSX.read(fs.readFileSync('./test_files/comments_stress_test.xlsb', 'binary'), {type: 'binary'}); + XLSX.read(fs.readFileSync('./test_files/comments_stress_test.xlsx', 'binary'), {type: 'binary'}); + }); + it('should read base64 strings', function() { + XLSX.read(fs.readFileSync('./test_files/comments_stress_test.xlsb', 'base64'), {type: 'base64'}); + XLSX.read(fs.readFileSync('./test_files/comments_stress_test.xlsx', 'base64'), {type: 'base64'}); + }); +}); + +describe('should have core properties and custom properties parsed', function() { var wb; before(function() { XLSX = require('./'); - wb = XLSX.readFile('./test_files/excel-properties.xlsx', { sheetStubs: false }); + wb = XLSX.readFile('./test_files/custom_properties.xlsx'); }); it('Must have read the core properties', function() { assert.equal(wb.Props.Company, 'Vector Inc'); diff --git a/tests.lst b/tests.lst index e65b2c3..4b304fd 100644 --- a/tests.lst +++ b/tests.lst @@ -1,5 +1,6 @@ RkNumber.xlsb comments_stress_test.xlsb +custom_properties.xlsb formula_stress_test.xlsb large_strings.xlsb.pending merge_cells.xlsb @@ -140,6 +141,7 @@ apachepoi_workbookProtection_workbook_windows_protected.xlsx apachepoi_workbookProtection_worksheet_protected.xlsx apachepoi_xlsx-jdbc.xlsx comments_stress_test.xlsx +custom_properties.xlsx excel-reader-xlsx_data01.xlsx excel-reader-xlsx_data02.xlsx excel-reader-xlsx_error02.xlsx.pending diff --git a/tests/files b/tests/files index 5a2df78..255a962 160000 --- a/tests/files +++ b/tests/files @@ -1 +1 @@ -Subproject commit 5a2df78bfe58c087fc604450185ee3bc4fb2c077 +Subproject commit 255a962b8f9a0f07ac75281bded02fea93e00b16 diff --git a/xlsx.js b/xlsx.js index af2884d..1e78d3a 100644 --- a/xlsx.js +++ b/xlsx.js @@ -424,7 +424,7 @@ SSF.load_table = function(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i]) SSF.loa make_ssf(SSF); var XLSX = {}; (function(XLSX){ -XLSX.version = '0.5.5'; +XLSX.version = '0.5.6'; var current_codepage, current_cptable, cptable; if(typeof module !== "undefined" && typeof require !== 'undefined') { if(typeof cptable === 'undefined') cptable = require('codepage'); @@ -1795,6 +1795,12 @@ var parse_wb_bin = function(data) { case 'BrtEndBookViews': break; case 'BrtBeginBundleShs': break; case 'BrtEndBundleShs': break; + case 'BrtBeginFnGroup': break; + case 'BrtEndFnGroup': break; + case 'BrtBeginExternals': break; + case 'BrtSupSelf': break; + case 'BrtExternSheet': break; + case 'BrtEndExternals': break; case 'BrtName': break; case 'BrtCalcProp': break; case 'BrtBeginPivotCacheIDs': break; @@ -1805,7 +1811,6 @@ var parse_wb_bin = function(data) { case 'BrtFRTBegin': pass = true; break; case 'BrtFRTEnd': pass = false; break; case 'BrtEndBook': break; - case '': break; //default: if(!pass) throw new Error("Unexpected record " + R.n); } }); @@ -2665,6 +2670,7 @@ function fixopts(opts) { ['sheetStubs', false], /* emit empty cells */ ['bookSheets', false], /* only try to get sheet names (no Sheets) */ + ['bookProps', false], /* only try to get properties (no Sheets) */ ['WTF', false] /* WTF mode (do not use) */ ]; @@ -2685,7 +2691,7 @@ function parseZip(zip, opts) { xlsb = true; } - if(!opts.bookSheets) { + if(!opts.bookSheets && !opts.bookProps) { strs = {}; if(dir.sst) strs=parse_sst(getdata(getzipfile(zip, dir.sst.replace(/^\//,''))), dir.sst, opts); @@ -2701,17 +2707,23 @@ function parseZip(zip, opts) { propdata += dir.extprops.length !== 0 ? getdata(getzipfile(zip, dir.extprops[0].replace(/^\//,''))) : ""; props = propdata !== "" ? parseProps(propdata) : {}; } catch(e) { } + var custprops = {}; - if (dir.custprops.length !== 0) { - try { + if(!opts.bookSheets || opts.bookProps) { + if (dir.custprops.length !== 0) try { propdata = getdata(getzipfile(zip, dir.custprops[0].replace(/^\//,''))); custprops = parseCustomProps(propdata); } catch(e) {/*console.error(e);*/} } - if(opts.bookSheets) { - if(props.Worksheets && props.SheetNames.length > 0) return { SheetNames:props.SheetNames }; - else if(wb.Sheets) return { SheetNames:wb.Sheets.map(function(x) { return x.name; }) }; + var out = {}; + if(opts.bookSheets || opts.bookProps) { + var sheets; + if(props.Worksheets && props.SheetNames.length > 0) sheets=props.SheetNames; + else if(wb.Sheets) sheets = wb.Sheets.map(function(x){ return x.name; }); + if(opts.bookProps) { out.Props = props; out.Custprops = custprops; } + if(typeof sheets !== 'undefined') out.SheetNames = sheets; + if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out; } var deps = {};