forked from sheetjs/sheetjs
version bump 0.6.0: avoid globals
- all utilities are now wrapped in XLSX object - codepage handling (h/t @xch89820) - formula tag attributes (h/t @shaunthomas999) - hyperlink support (h/t @sysarchitect, fixes #55) - coverage test spinner (to prevent travis timeouts)
This commit is contained in:
parent
76f0d920a1
commit
dc2d391fbc
@ -10,4 +10,4 @@ before_script:
|
|||||||
- "make init"
|
- "make init"
|
||||||
- "cd tests/files; make all; cd -"
|
- "cd tests/files; make all; cd -"
|
||||||
after_success:
|
after_success:
|
||||||
- "make coveralls"
|
- "make coveralls-spin"
|
||||||
|
13
Makefile
13
Makefile
@ -6,7 +6,7 @@ FMT=xlsx xlsm xlsb misc
|
|||||||
$(TARGET): $(DEPS)
|
$(TARGET): $(DEPS)
|
||||||
cat $^ > $@
|
cat $^ > $@
|
||||||
|
|
||||||
bits/31_version.js: package.json
|
bits/01_version.js: package.json
|
||||||
echo "XLSX.version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@
|
echo "XLSX.version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
@ -35,16 +35,21 @@ $(TESTFMT): test_%:
|
|||||||
lint: $(TARGET)
|
lint: $(TARGET)
|
||||||
jshint --show-non-errors $(TARGET)
|
jshint --show-non-errors $(TARGET)
|
||||||
|
|
||||||
.PHONY: cov
|
.PHONY: cov cov-spin
|
||||||
cov: misc/coverage.html
|
cov: misc/coverage.html
|
||||||
|
cov-spin:
|
||||||
|
make cov & bash misc/spin.sh $$!
|
||||||
|
|
||||||
misc/coverage.html: $(TARGET) test.js
|
misc/coverage.html: $(TARGET) test.js
|
||||||
mocha --require blanket -R html-cov > misc/coverage.html
|
mocha --require blanket -R html-cov > $@
|
||||||
|
|
||||||
.PHONY: coveralls
|
.PHONY: coveralls coveralls-spin
|
||||||
coveralls:
|
coveralls:
|
||||||
mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js
|
mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js
|
||||||
|
|
||||||
|
coveralls-spin:
|
||||||
|
make coveralls & bash misc/spin.sh $$!
|
||||||
|
|
||||||
.PHONY: dist
|
.PHONY: dist
|
||||||
dist: $(TARGET)
|
dist: $(TARGET)
|
||||||
cp $(TARGET) dist/
|
cp $(TARGET) dist/
|
||||||
|
@ -66,6 +66,7 @@ that does not start with `!` corresponds to a cell (using `A-1` notation).
|
|||||||
- `.h` : an HTML rendering of the rich text (if applicable)
|
- `.h` : an HTML rendering of the rich text (if applicable)
|
||||||
- `.c` : comments associated with the cell
|
- `.c` : comments associated with the cell
|
||||||
- `.z` : the number format string associated with the cell (if requested)
|
- `.z` : the number format string associated with the cell (if requested)
|
||||||
|
- `.l` : the hyperlink of the cell (.Target holds link, .tooltip is tooltip)
|
||||||
|
|
||||||
For dates, `.v` holds the raw date code from the sheet and `.w` holds the text
|
For dates, `.v` holds the raw date code from the sheet and `.w` holds the text
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
/* xlsx.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
/* xlsx.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||||
/* vim: set ts=2: */
|
/* vim: set ts=2: */
|
||||||
/*jshint eqnull:true */
|
/*jshint eqnull:true */
|
||||||
|
var XLSX = {};
|
||||||
|
(function(XLSX){
|
||||||
|
1
bits/01_version.js
Normal file
1
bits/01_version.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
XLSX.version = '0.6.0';
|
@ -1,4 +1,3 @@
|
|||||||
/* Spreadsheet Format -- jump to XLSX for the XLSX code */
|
|
||||||
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||||
var SSF = {};
|
var SSF = {};
|
||||||
var make_ssf = function(SSF){
|
var make_ssf = function(SSF){
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
var XLSX = {};
|
|
||||||
(function(XLSX){
|
|
@ -1 +0,0 @@
|
|||||||
XLSX.version = '0.5.17';
|
|
@ -1,4 +1,4 @@
|
|||||||
var current_codepage, current_cptable, cptable;
|
var current_codepage, current_cptable;
|
||||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||||
if(typeof cptable === 'undefined') cptable = require('codepage');
|
if(typeof cptable === 'undefined') cptable = require('codepage');
|
||||||
current_codepage = 1252; current_cptable = cptable[1252];
|
current_codepage = 1252; current_cptable = cptable[1252];
|
||||||
|
@ -67,7 +67,7 @@ var utf8read = function(orig) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// matches <foo>...</foo> extracts content
|
// matches <foo>...</foo> extracts content
|
||||||
function matchtag(f,g) {return new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")+"m");}
|
function matchtag(f,g) {return new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")+"m");}
|
||||||
|
|
||||||
function parseVector(data) {
|
function parseVector(data) {
|
||||||
var h = parsexmltag(data);
|
var h = parsexmltag(data);
|
||||||
|
@ -274,7 +274,7 @@ function parseRels(data, currentFilePath) {
|
|||||||
currentFilePath = '/'+currentFilePath;
|
currentFilePath = '/'+currentFilePath;
|
||||||
}
|
}
|
||||||
var rels = {};
|
var rels = {};
|
||||||
|
var hash = {};
|
||||||
var resolveRelativePathIntoAbsolute = function (to) {
|
var resolveRelativePathIntoAbsolute = function (to) {
|
||||||
var toksFrom = currentFilePath.split('/');
|
var toksFrom = currentFilePath.split('/');
|
||||||
toksFrom.pop(); // folder path
|
toksFrom.pop(); // folder path
|
||||||
@ -296,11 +296,12 @@ function parseRels(data, currentFilePath) {
|
|||||||
/* 9.3.2.2 OPC_Relationships */
|
/* 9.3.2.2 OPC_Relationships */
|
||||||
if (y[0] === '<Relationship') {
|
if (y[0] === '<Relationship') {
|
||||||
var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
|
var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
|
||||||
var canonictarget = resolveRelativePathIntoAbsolute(y.Target);
|
var canonictarget = y.TargetMode === 'External' ? y.Target : resolveRelativePathIntoAbsolute(y.Target);
|
||||||
rels[canonictarget] = rel;
|
rels[canonictarget] = rel;
|
||||||
|
hash[y.Id] = rel;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
rels["!id"] = hash;
|
||||||
return rels;
|
return rels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* 18.3 Worksheets */
|
/* 18.3 Worksheets */
|
||||||
function parse_ws_xml(data, opts) {
|
function parse_ws_xml(data, opts, rels) {
|
||||||
if(!data) return data;
|
if(!data) return data;
|
||||||
/* 18.3.1.99 worksheet CT_Worksheet */
|
/* 18.3.1.99 worksheet CT_Worksheet */
|
||||||
var s = {};
|
var s = {};
|
||||||
@ -87,6 +87,25 @@ function parse_ws_xml(data, opts) {
|
|||||||
s[cell.r] = p;
|
s[cell.r] = p;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
|
||||||
|
if(data.match(/<\/hyperlinks>/)) data.match(/<hyperlink[^>]*\/>/g).forEach(function(h) {
|
||||||
|
var val = parsexmltag(h); delete val[0];
|
||||||
|
if(!val.ref) return;
|
||||||
|
var rel = rels['!id'][val.id];
|
||||||
|
if(rel) {
|
||||||
|
val.Target = rel.Target;
|
||||||
|
if(val.location) val.Target += "#"+val.location;
|
||||||
|
val.Rel = rel;
|
||||||
|
}
|
||||||
|
var rng = decode_range(val.ref);
|
||||||
|
for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) {
|
||||||
|
var addr = encode_cell({c:C,r:R});
|
||||||
|
if(!s[addr]) s[addr] = {t:"str",v:undefined};
|
||||||
|
s[addr].l = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
|
if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
|
||||||
if(opts.sheetRows && s["!ref"]) {
|
if(opts.sheetRows && s["!ref"]) {
|
||||||
var tmpref = decode_range(s["!ref"]);
|
var tmpref = decode_range(s["!ref"]);
|
||||||
|
@ -123,16 +123,29 @@ var parse_BrtFmlaString = function(data, length, opts) {
|
|||||||
/* [MS-XLSB] 2.4.676 BrtMergeCell */
|
/* [MS-XLSB] 2.4.676 BrtMergeCell */
|
||||||
var parse_BrtMergeCell = parse_UncheckedRfX;
|
var parse_BrtMergeCell = parse_UncheckedRfX;
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.656 BrtHLink */
|
||||||
|
var parse_BrtHLink = function(data, length, opts) {
|
||||||
|
var end = data.l + length;
|
||||||
|
var rfx = parse_UncheckedRfX(data, 16);
|
||||||
|
var relId = parse_XLNullableWideString(data);
|
||||||
|
var loc = parse_XLWideString(data);
|
||||||
|
var tooltip = parse_XLWideString(data);
|
||||||
|
var display = parse_XLWideString(data);
|
||||||
|
data.l = end;
|
||||||
|
return {rfx:rfx, relId:relId, loc:loc, tooltip:tooltip, display:display};
|
||||||
|
};
|
||||||
|
|
||||||
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
||||||
var parse_ws_bin = function(data, opts) {
|
var parse_ws_bin = function(data, opts, rels) {
|
||||||
if(!data) return data;
|
if(!data) return data;
|
||||||
|
if(!rels) rels = {'!id':{}};
|
||||||
var s = {};
|
var s = {};
|
||||||
|
|
||||||
var ref;
|
var ref;
|
||||||
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||||
|
|
||||||
var pass = false, end = false;
|
var pass = false, end = false;
|
||||||
var row, p, cf;
|
var row, p, cf, R, C,addr;
|
||||||
var mergecells = [];
|
var mergecells = [];
|
||||||
recordhopper(data, function(val, R) {
|
recordhopper(data, function(val, R) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
@ -186,7 +199,21 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtBeginMergeCells': break;
|
case 'BrtBeginMergeCells': break;
|
||||||
case 'BrtEndMergeCells': break;
|
case 'BrtEndMergeCells': break;
|
||||||
case 'BrtMergeCell': mergecells.push(val); break;
|
case 'BrtMergeCell': mergecells.push(val); break;
|
||||||
|
|
||||||
|
case 'BrtHLink':
|
||||||
|
var rel = rels['!id'][val.relId];
|
||||||
|
if(rel) {
|
||||||
|
val.Target = rel.Target;
|
||||||
|
if(val.loc) val.Target += "#"+val.loc;
|
||||||
|
val.Rel = rel;
|
||||||
|
}
|
||||||
|
for(R=val.rfx.s.r;R<=val.rfx.e.r;++R) for(C=val.rfx.s.c;C<=val.rfx.e.c;++C) {
|
||||||
|
addr = encode_cell({c:C,r:R});
|
||||||
|
if(!s[addr]) s[addr] = {t:"str",v:undefined};
|
||||||
|
s[addr].l = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'BrtArrFmla': break; // TODO
|
case 'BrtArrFmla': break; // TODO
|
||||||
case 'BrtShrFmla': break; // TODO
|
case 'BrtShrFmla': break; // TODO
|
||||||
case 'BrtBeginSheet': break;
|
case 'BrtBeginSheet': break;
|
||||||
@ -215,7 +242,6 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtFRTBegin': pass = true; break;
|
case 'BrtFRTBegin': pass = true; break;
|
||||||
case 'BrtFRTEnd': pass = false; break;
|
case 'BrtFRTEnd': pass = false; break;
|
||||||
case 'BrtEndSheet': break; // TODO
|
case 'BrtEndSheet': break; // TODO
|
||||||
case 'BrtHLink': break; // TODO
|
|
||||||
case 'BrtDrawing': break; // TODO
|
case 'BrtDrawing': break; // TODO
|
||||||
case 'BrtLegacyDrawing': break; // TODO
|
case 'BrtLegacyDrawing': break; // TODO
|
||||||
case 'BrtLegacyDrawingHF': break; // TODO
|
case 'BrtLegacyDrawingHF': break; // TODO
|
||||||
@ -266,7 +292,7 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtEndAFilter': break;
|
case 'BrtEndAFilter': break;
|
||||||
case 'BrtBeginFilterColumn': break;
|
case 'BrtBeginFilterColumn': break;
|
||||||
case 'BrtBeginFilters': break;
|
case 'BrtBeginFilters': break;
|
||||||
case 'BrtFilter': break;
|
case 'BrtFilter': break;
|
||||||
case 'BrtEndFilters': break;
|
case 'BrtEndFilters': break;
|
||||||
case 'BrtEndFilterColumn': break;
|
case 'BrtEndFilterColumn': break;
|
||||||
case 'BrtDynamicFilter': break;
|
case 'BrtDynamicFilter': break;
|
||||||
|
@ -2,8 +2,8 @@ function parse_wb(data, name, opts) {
|
|||||||
return name.substr(-4)===".bin" ? parse_wb_bin(data, opts) : parse_wb_xml(data, opts);
|
return name.substr(-4)===".bin" ? parse_wb_bin(data, opts) : parse_wb_xml(data, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_ws(data, name, opts) {
|
function parse_ws(data, name, opts, rels) {
|
||||||
return name.substr(-4)===".bin" ? parse_ws_bin(data, opts) : parse_ws_xml(data, opts);
|
return name.substr(-4)===".bin" ? parse_ws_bin(data, opts, rels) : parse_ws_xml(data, opts, rels);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_sty(data, name, opts) {
|
function parse_sty(data, name, opts) {
|
||||||
|
@ -423,7 +423,7 @@ var RecordEnum = {
|
|||||||
0x01EB: { n:"BrtEndMG", f:parsenoop },
|
0x01EB: { n:"BrtEndMG", f:parsenoop },
|
||||||
0x01EC: { n:"BrtBeginMap", f:parsenoop },
|
0x01EC: { n:"BrtBeginMap", f:parsenoop },
|
||||||
0x01ED: { n:"BrtEndMap", f:parsenoop },
|
0x01ED: { n:"BrtEndMap", f:parsenoop },
|
||||||
0x01EE: { n:"BrtHLink", f:parsenoop },
|
0x01EE: { n:"BrtHLink", f:parse_BrtHLink },
|
||||||
0x01EF: { n:"BrtBeginDCon", f:parsenoop },
|
0x01EF: { n:"BrtBeginDCon", f:parsenoop },
|
||||||
0x01F0: { n:"BrtEndDCon", f:parsenoop },
|
0x01F0: { n:"BrtEndDCon", f:parsenoop },
|
||||||
0x01F1: { n:"BrtBeginDRefs", f:parsenoop },
|
0x01F1: { n:"BrtBeginDRefs", f:parsenoop },
|
||||||
|
@ -76,8 +76,8 @@ function parseZip(zip, opts) {
|
|||||||
path = 'xl/worksheets/sheet'+(i+1-nmode)+(xlsb?'.bin':'.xml');
|
path = 'xl/worksheets/sheet'+(i+1-nmode)+(xlsb?'.bin':'.xml');
|
||||||
path = path.replace(/sheet0\./,"sheet.");
|
path = path.replace(/sheet0\./,"sheet.");
|
||||||
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
||||||
sheets[props.SheetNames[i]]=parse_ws(getzipdata(zip, path),path,opts);
|
|
||||||
sheetRels[props.SheetNames[i]]=parseRels(getzipdata(zip, relsPath, true), path);
|
sheetRels[props.SheetNames[i]]=parseRels(getzipdata(zip, relsPath, true), path);
|
||||||
|
sheets[props.SheetNames[i]]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[props.SheetNames[i]]);
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,3 @@ function readFileSync(data, options) {
|
|||||||
return readSync(data, o);
|
return readSync(data, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
XLSX.read = readSync;
|
|
||||||
XLSX.readFile = readFileSync;
|
|
||||||
XLSX.parseZip = parseZip;
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
return this;
|
|
||||||
|
|
||||||
})(XLSX);
|
|
||||||
|
|
4
bits/98_exports.js
Normal file
4
bits/98_exports.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
XLSX.read = readSync;
|
||||||
|
XLSX.readFile = readFileSync;
|
||||||
|
XLSX.parseZip = parseZip;
|
||||||
|
XLSX.SSF = SSF;
|
@ -1,7 +1 @@
|
|||||||
|
})(typeof exports !== 'undefined' ? exports : XLSX);
|
||||||
if(typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
|
||||||
exports.read = XLSX.read;
|
|
||||||
exports.readFile = XLSX.readFile;
|
|
||||||
exports.utils = XLSX.utils;
|
|
||||||
exports.version = XLSX.version;
|
|
||||||
}
|
|
||||||
|
102
dist/xlsx.js
vendored
102
dist/xlsx.js
vendored
@ -1,7 +1,9 @@
|
|||||||
/* xlsx.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
/* xlsx.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||||
/* vim: set ts=2: */
|
/* vim: set ts=2: */
|
||||||
/*jshint eqnull:true */
|
/*jshint eqnull:true */
|
||||||
/* Spreadsheet Format -- jump to XLSX for the XLSX code */
|
var XLSX = {};
|
||||||
|
(function(XLSX){
|
||||||
|
XLSX.version = '0.6.0';
|
||||||
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||||
var SSF = {};
|
var SSF = {};
|
||||||
var make_ssf = function(SSF){
|
var make_ssf = function(SSF){
|
||||||
@ -496,10 +498,7 @@ SSF.get_table = function() { return table_fmt; };
|
|||||||
SSF.load_table = function(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i]) SSF.load(tbl[i], i); };
|
SSF.load_table = function(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i]) SSF.load(tbl[i], i); };
|
||||||
};
|
};
|
||||||
make_ssf(SSF);
|
make_ssf(SSF);
|
||||||
var XLSX = {};
|
var current_codepage, current_cptable;
|
||||||
(function(XLSX){
|
|
||||||
XLSX.version = '0.5.17';
|
|
||||||
var current_codepage, current_cptable, cptable;
|
|
||||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||||
if(typeof cptable === 'undefined') cptable = require('codepage');
|
if(typeof cptable === 'undefined') cptable = require('codepage');
|
||||||
current_codepage = 1252; current_cptable = cptable[1252];
|
current_codepage = 1252; current_cptable = cptable[1252];
|
||||||
@ -613,7 +612,7 @@ var utf8read = function(orig) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// matches <foo>...</foo> extracts content
|
// matches <foo>...</foo> extracts content
|
||||||
function matchtag(f,g) {return new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")+"m");}
|
function matchtag(f,g) {return new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")+"m");}
|
||||||
|
|
||||||
function parseVector(data) {
|
function parseVector(data) {
|
||||||
var h = parsexmltag(data);
|
var h = parsexmltag(data);
|
||||||
@ -1468,7 +1467,7 @@ function parseRels(data, currentFilePath) {
|
|||||||
currentFilePath = '/'+currentFilePath;
|
currentFilePath = '/'+currentFilePath;
|
||||||
}
|
}
|
||||||
var rels = {};
|
var rels = {};
|
||||||
|
var hash = {};
|
||||||
var resolveRelativePathIntoAbsolute = function (to) {
|
var resolveRelativePathIntoAbsolute = function (to) {
|
||||||
var toksFrom = currentFilePath.split('/');
|
var toksFrom = currentFilePath.split('/');
|
||||||
toksFrom.pop(); // folder path
|
toksFrom.pop(); // folder path
|
||||||
@ -1490,11 +1489,12 @@ function parseRels(data, currentFilePath) {
|
|||||||
/* 9.3.2.2 OPC_Relationships */
|
/* 9.3.2.2 OPC_Relationships */
|
||||||
if (y[0] === '<Relationship') {
|
if (y[0] === '<Relationship') {
|
||||||
var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
|
var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
|
||||||
var canonictarget = resolveRelativePathIntoAbsolute(y.Target);
|
var canonictarget = y.TargetMode === 'External' ? y.Target : resolveRelativePathIntoAbsolute(y.Target);
|
||||||
rels[canonictarget] = rel;
|
rels[canonictarget] = rel;
|
||||||
|
hash[y.Id] = rel;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
rels["!id"] = hash;
|
||||||
return rels;
|
return rels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1664,7 +1664,7 @@ var strs = {}; // shared strings
|
|||||||
var _ssfopts = {}; // spreadsheet formatting options
|
var _ssfopts = {}; // spreadsheet formatting options
|
||||||
|
|
||||||
/* 18.3 Worksheets */
|
/* 18.3 Worksheets */
|
||||||
function parse_ws_xml(data, opts) {
|
function parse_ws_xml(data, opts, rels) {
|
||||||
if(!data) return data;
|
if(!data) return data;
|
||||||
/* 18.3.1.99 worksheet CT_Worksheet */
|
/* 18.3.1.99 worksheet CT_Worksheet */
|
||||||
var s = {};
|
var s = {};
|
||||||
@ -1752,6 +1752,25 @@ function parse_ws_xml(data, opts) {
|
|||||||
s[cell.r] = p;
|
s[cell.r] = p;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
|
||||||
|
if(data.match(/<\/hyperlinks>/)) data.match(/<hyperlink[^>]*\/>/g).forEach(function(h) {
|
||||||
|
var val = parsexmltag(h); delete val[0];
|
||||||
|
if(!val.ref) return;
|
||||||
|
var rel = rels['!id'][val.id];
|
||||||
|
if(rel) {
|
||||||
|
val.Target = rel.Target;
|
||||||
|
if(val.location) val.Target += "#"+val.location;
|
||||||
|
val.Rel = rel;
|
||||||
|
}
|
||||||
|
var rng = decode_range(val.ref);
|
||||||
|
for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) {
|
||||||
|
var addr = encode_cell({c:C,r:R});
|
||||||
|
if(!s[addr]) s[addr] = {t:"str",v:undefined};
|
||||||
|
s[addr].l = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
|
if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
|
||||||
if(opts.sheetRows && s["!ref"]) {
|
if(opts.sheetRows && s["!ref"]) {
|
||||||
var tmpref = decode_range(s["!ref"]);
|
var tmpref = decode_range(s["!ref"]);
|
||||||
@ -1894,16 +1913,29 @@ var parse_BrtFmlaString = function(data, length, opts) {
|
|||||||
/* [MS-XLSB] 2.4.676 BrtMergeCell */
|
/* [MS-XLSB] 2.4.676 BrtMergeCell */
|
||||||
var parse_BrtMergeCell = parse_UncheckedRfX;
|
var parse_BrtMergeCell = parse_UncheckedRfX;
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.656 BrtHLink */
|
||||||
|
var parse_BrtHLink = function(data, length, opts) {
|
||||||
|
var end = data.l + length;
|
||||||
|
var rfx = parse_UncheckedRfX(data, 16);
|
||||||
|
var relId = parse_XLNullableWideString(data);
|
||||||
|
var loc = parse_XLWideString(data);
|
||||||
|
var tooltip = parse_XLWideString(data);
|
||||||
|
var display = parse_XLWideString(data);
|
||||||
|
data.l = end;
|
||||||
|
return {rfx:rfx, relId:relId, loc:loc, tooltip:tooltip, display:display};
|
||||||
|
};
|
||||||
|
|
||||||
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
||||||
var parse_ws_bin = function(data, opts) {
|
var parse_ws_bin = function(data, opts, rels) {
|
||||||
if(!data) return data;
|
if(!data) return data;
|
||||||
|
if(!rels) rels = {'!id':{}};
|
||||||
var s = {};
|
var s = {};
|
||||||
|
|
||||||
var ref;
|
var ref;
|
||||||
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||||
|
|
||||||
var pass = false, end = false;
|
var pass = false, end = false;
|
||||||
var row, p, cf;
|
var row, p, cf, R, C,addr;
|
||||||
var mergecells = [];
|
var mergecells = [];
|
||||||
recordhopper(data, function(val, R) {
|
recordhopper(data, function(val, R) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
@ -1957,7 +1989,21 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtBeginMergeCells': break;
|
case 'BrtBeginMergeCells': break;
|
||||||
case 'BrtEndMergeCells': break;
|
case 'BrtEndMergeCells': break;
|
||||||
case 'BrtMergeCell': mergecells.push(val); break;
|
case 'BrtMergeCell': mergecells.push(val); break;
|
||||||
|
|
||||||
|
case 'BrtHLink':
|
||||||
|
var rel = rels['!id'][val.relId];
|
||||||
|
if(rel) {
|
||||||
|
val.Target = rel.Target;
|
||||||
|
if(val.loc) val.Target += "#"+val.loc;
|
||||||
|
val.Rel = rel;
|
||||||
|
}
|
||||||
|
for(R=val.rfx.s.r;R<=val.rfx.e.r;++R) for(C=val.rfx.s.c;C<=val.rfx.e.c;++C) {
|
||||||
|
addr = encode_cell({c:C,r:R});
|
||||||
|
if(!s[addr]) s[addr] = {t:"str",v:undefined};
|
||||||
|
s[addr].l = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'BrtArrFmla': break; // TODO
|
case 'BrtArrFmla': break; // TODO
|
||||||
case 'BrtShrFmla': break; // TODO
|
case 'BrtShrFmla': break; // TODO
|
||||||
case 'BrtBeginSheet': break;
|
case 'BrtBeginSheet': break;
|
||||||
@ -1986,7 +2032,6 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtFRTBegin': pass = true; break;
|
case 'BrtFRTBegin': pass = true; break;
|
||||||
case 'BrtFRTEnd': pass = false; break;
|
case 'BrtFRTEnd': pass = false; break;
|
||||||
case 'BrtEndSheet': break; // TODO
|
case 'BrtEndSheet': break; // TODO
|
||||||
case 'BrtHLink': break; // TODO
|
|
||||||
case 'BrtDrawing': break; // TODO
|
case 'BrtDrawing': break; // TODO
|
||||||
case 'BrtLegacyDrawing': break; // TODO
|
case 'BrtLegacyDrawing': break; // TODO
|
||||||
case 'BrtLegacyDrawingHF': break; // TODO
|
case 'BrtLegacyDrawingHF': break; // TODO
|
||||||
@ -2037,7 +2082,7 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtEndAFilter': break;
|
case 'BrtEndAFilter': break;
|
||||||
case 'BrtBeginFilterColumn': break;
|
case 'BrtBeginFilterColumn': break;
|
||||||
case 'BrtBeginFilters': break;
|
case 'BrtBeginFilters': break;
|
||||||
case 'BrtFilter': break;
|
case 'BrtFilter': break;
|
||||||
case 'BrtEndFilters': break;
|
case 'BrtEndFilters': break;
|
||||||
case 'BrtEndFilterColumn': break;
|
case 'BrtEndFilterColumn': break;
|
||||||
case 'BrtDynamicFilter': break;
|
case 'BrtDynamicFilter': break;
|
||||||
@ -2357,8 +2402,8 @@ function parse_wb(data, name, opts) {
|
|||||||
return name.substr(-4)===".bin" ? parse_wb_bin(data, opts) : parse_wb_xml(data, opts);
|
return name.substr(-4)===".bin" ? parse_wb_bin(data, opts) : parse_wb_xml(data, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_ws(data, name, opts) {
|
function parse_ws(data, name, opts, rels) {
|
||||||
return name.substr(-4)===".bin" ? parse_ws_bin(data, opts) : parse_ws_xml(data, opts);
|
return name.substr(-4)===".bin" ? parse_ws_bin(data, opts, rels) : parse_ws_xml(data, opts, rels);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_sty(data, name, opts) {
|
function parse_sty(data, name, opts) {
|
||||||
@ -2801,7 +2846,7 @@ var RecordEnum = {
|
|||||||
0x01EB: { n:"BrtEndMG", f:parsenoop },
|
0x01EB: { n:"BrtEndMG", f:parsenoop },
|
||||||
0x01EC: { n:"BrtBeginMap", f:parsenoop },
|
0x01EC: { n:"BrtBeginMap", f:parsenoop },
|
||||||
0x01ED: { n:"BrtEndMap", f:parsenoop },
|
0x01ED: { n:"BrtEndMap", f:parsenoop },
|
||||||
0x01EE: { n:"BrtHLink", f:parsenoop },
|
0x01EE: { n:"BrtHLink", f:parse_BrtHLink },
|
||||||
0x01EF: { n:"BrtBeginDCon", f:parsenoop },
|
0x01EF: { n:"BrtBeginDCon", f:parsenoop },
|
||||||
0x01F0: { n:"BrtEndDCon", f:parsenoop },
|
0x01F0: { n:"BrtEndDCon", f:parsenoop },
|
||||||
0x01F1: { n:"BrtBeginDRefs", f:parsenoop },
|
0x01F1: { n:"BrtBeginDRefs", f:parsenoop },
|
||||||
@ -3299,8 +3344,8 @@ function parseZip(zip, opts) {
|
|||||||
path = 'xl/worksheets/sheet'+(i+1-nmode)+(xlsb?'.bin':'.xml');
|
path = 'xl/worksheets/sheet'+(i+1-nmode)+(xlsb?'.bin':'.xml');
|
||||||
path = path.replace(/sheet0\./,"sheet.");
|
path = path.replace(/sheet0\./,"sheet.");
|
||||||
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
||||||
sheets[props.SheetNames[i]]=parse_ws(getzipdata(zip, path),path,opts);
|
|
||||||
sheetRels[props.SheetNames[i]]=parseRels(getzipdata(zip, relsPath, true), path);
|
sheetRels[props.SheetNames[i]]=parseRels(getzipdata(zip, relsPath, true), path);
|
||||||
|
sheets[props.SheetNames[i]]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[props.SheetNames[i]]);
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3346,13 +3391,6 @@ function readFileSync(data, options) {
|
|||||||
return readSync(data, o);
|
return readSync(data, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
XLSX.read = readSync;
|
|
||||||
XLSX.readFile = readFileSync;
|
|
||||||
XLSX.parseZip = parseZip;
|
|
||||||
return this;
|
|
||||||
|
|
||||||
})(XLSX);
|
|
||||||
|
|
||||||
var _chr = function(c) { return String.fromCharCode(c); };
|
var _chr = function(c) { return String.fromCharCode(c); };
|
||||||
|
|
||||||
function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = _chr(((col-1)%26) + 65) + s; return s; }
|
function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = _chr(((col-1)%26) + 65) + s; return s; }
|
||||||
@ -3469,10 +3507,8 @@ XLSX.utils = {
|
|||||||
get_formulae: get_formulae,
|
get_formulae: get_formulae,
|
||||||
sheet_to_row_object_array: sheet_to_row_object_array
|
sheet_to_row_object_array: sheet_to_row_object_array
|
||||||
};
|
};
|
||||||
|
XLSX.read = readSync;
|
||||||
if(typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
XLSX.readFile = readFileSync;
|
||||||
exports.read = XLSX.read;
|
XLSX.parseZip = parseZip;
|
||||||
exports.readFile = XLSX.readFile;
|
XLSX.SSF = SSF;
|
||||||
exports.utils = XLSX.utils;
|
})(typeof exports !== 'undefined' ? exports : XLSX);
|
||||||
exports.version = XLSX.version;
|
|
||||||
}
|
|
||||||
|
6
dist/xlsx.min.js
vendored
6
dist/xlsx.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
vendored
2
dist/xlsx.min.map
vendored
File diff suppressed because one or more lines are too long
14
misc/spin.sh
Executable file
14
misc/spin.sh
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# spin.sh -- show a spinner (for coverage test)
|
||||||
|
# Copyright (C) 2014 SheetJS
|
||||||
|
|
||||||
|
wpid=$1
|
||||||
|
delay=1
|
||||||
|
str="|/-\\"
|
||||||
|
while [ $(ps -a|awk '$1=='$wpid' {print $1}') ]; do
|
||||||
|
t=${str#?}
|
||||||
|
printf " [%c]" "$str"
|
||||||
|
str=$t${str%"$t"}
|
||||||
|
sleep $delay
|
||||||
|
printf "\b\b\b\b"
|
||||||
|
done
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xlsx",
|
"name": "xlsx",
|
||||||
"version": "0.5.17",
|
"version": "0.6.0",
|
||||||
"author": "sheetjs",
|
"author": "sheetjs",
|
||||||
"description": "XLSB / XLSX / XLSM (Excel 2007+ Spreadsheet) parser",
|
"description": "XLSB / XLSX / XLSM (Excel 2007+ Spreadsheet) parser",
|
||||||
"keywords": [ "xlsx", "xlsb", "xlsm", "office", "excel", "spreadsheet" ],
|
"keywords": [ "xlsx", "xlsb", "xlsm", "office", "excel", "spreadsheet" ],
|
||||||
@ -9,7 +9,7 @@
|
|||||||
},
|
},
|
||||||
"main": "./xlsx",
|
"main": "./xlsx",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ssf":"~0.6.3",
|
"ssf":"~0.6.4",
|
||||||
"codepage":"",
|
"codepage":"",
|
||||||
"cfb":"",
|
"cfb":"",
|
||||||
"jszip":"~2.1.0",
|
"jszip":"~2.1.0",
|
||||||
|
29
test.js
29
test.js
@ -28,6 +28,8 @@ var paths = {
|
|||||||
fst1: dir + 'formula_stress_test.xlsx',
|
fst1: dir + 'formula_stress_test.xlsx',
|
||||||
fst2: dir + 'formula_stress_test.xlsb',
|
fst2: dir + 'formula_stress_test.xlsb',
|
||||||
fstb: dir + 'formula_stress_test.xlsb',
|
fstb: dir + 'formula_stress_test.xlsb',
|
||||||
|
hl1: dir + 'hyperlink_stress_test_2011.xlsx',
|
||||||
|
hl2: dir + 'hyperlink_stress_test_2011.xlsb',
|
||||||
lon1: dir + 'LONumbers.xlsx',
|
lon1: dir + 'LONumbers.xlsx',
|
||||||
mc1: dir + 'merge_cells.xlsx',
|
mc1: dir + 'merge_cells.xlsx',
|
||||||
mc2: dir + 'merge_cells.xlsb',
|
mc2: dir + 'merge_cells.xlsb',
|
||||||
@ -73,7 +75,7 @@ function parsetest(x, wb, full) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if(!full) return;
|
if(!full) return;
|
||||||
describe(x + ' should generate correct output', function() {
|
describe(x + ' should generate correct output', function() {
|
||||||
wb.SheetNames.forEach(function(ws, i) {
|
wb.SheetNames.forEach(function(ws, i) {
|
||||||
var name = (dir + x + '.' + i + '.csv');
|
var name = (dir + x + '.' + i + '.csv');
|
||||||
@ -105,7 +107,7 @@ describe('should parse test files', function() {
|
|||||||
parsetest(x, wb, true);
|
parsetest(x, wb, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
fileA.forEach(function(x) {
|
fileA.forEach(function(x) {
|
||||||
it(x, x.substr(-8) == ".pending" ? null : function() {
|
it(x, x.substr(-8) == ".pending" ? null : function() {
|
||||||
var wb = X.readFile(dir + x, {WTF:opts.wtf, sheetRows:10});
|
var wb = X.readFile(dir + x, {WTF:opts.wtf, sheetRows:10});
|
||||||
parsetest(x, wb, false);
|
parsetest(x, wb, false);
|
||||||
@ -372,6 +374,29 @@ describe('features', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('should find hyperlinks', function() {
|
||||||
|
var wb1, wb2;
|
||||||
|
before(function() {
|
||||||
|
X = require('./');
|
||||||
|
wb1 = X.readFile(paths.hl1);
|
||||||
|
wb2 = X.readFile(paths.hl2);
|
||||||
|
});
|
||||||
|
|
||||||
|
function hlink(wb) {
|
||||||
|
var ws = wb.Sheets.Sheet1;
|
||||||
|
assert.equal(ws.A1.l.Target, "http://www.sheetjs.com");
|
||||||
|
assert.equal(ws.A2.l.Target, "http://oss.sheetjs.com");
|
||||||
|
assert.equal(ws.A3.l.Target, "http://oss.sheetjs.com#foo");
|
||||||
|
assert.equal(ws.A4.l.Target, "mailto:dev@sheetjs.com");
|
||||||
|
assert.equal(ws.A5.l.Target, "mailto:dev@sheetjs.com?subject=hyperlink");
|
||||||
|
assert.equal(ws.A6.l.Target, "../../sheetjs/Documents/Test.xlsx");
|
||||||
|
assert.equal(ws.A7.l.Target, "http://sheetjs.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
it(N1, function() { hlink(wb1); });
|
||||||
|
it(N2, function() { hlink(wb2); });
|
||||||
|
});
|
||||||
|
|
||||||
describe('should parse cells with date type (XLSX/XLSM)', function() {
|
describe('should parse cells with date type (XLSX/XLSM)', function() {
|
||||||
var wb, ws;
|
var wb, ws;
|
||||||
before(function() {
|
before(function() {
|
||||||
|
@ -3,10 +3,10 @@ BlankSheetTypes.xlsb
|
|||||||
NumberFormatCondition.xlsb
|
NumberFormatCondition.xlsb
|
||||||
RkNumber.xlsb
|
RkNumber.xlsb
|
||||||
calendar_stress_test.xlsb.pending
|
calendar_stress_test.xlsb.pending
|
||||||
calendar_stress_test.xlsx.pending
|
|
||||||
comments_stress_test.xlsb
|
comments_stress_test.xlsb
|
||||||
custom_properties.xlsb
|
custom_properties.xlsb
|
||||||
formula_stress_test.xlsb
|
formula_stress_test.xlsb
|
||||||
|
hyperlink_stress_test_2011.xlsb
|
||||||
large_strings.xlsb
|
large_strings.xlsb
|
||||||
merge_cells.xlsb
|
merge_cells.xlsb
|
||||||
named_ranges_2011.xlsb
|
named_ranges_2011.xlsb
|
||||||
@ -14,6 +14,7 @@ number_format.xlsb
|
|||||||
pivot_table_named_range.xlsb
|
pivot_table_named_range.xlsb
|
||||||
pivot_table_test.xlsb
|
pivot_table_test.xlsb
|
||||||
rich_text_stress.xlsb
|
rich_text_stress.xlsb
|
||||||
|
text_and_numbers.xlsb
|
||||||
time_stress_test_1.xlsb
|
time_stress_test_1.xlsb
|
||||||
xlsx-stream-d-date-cell.xlsb
|
xlsx-stream-d-date-cell.xlsb
|
||||||
2013/apachepoi_29982.xls.xlsb
|
2013/apachepoi_29982.xls.xlsb
|
||||||
@ -162,6 +163,7 @@ apachepoi_workbookProtection_workbook_structure_protected.xlsx
|
|||||||
apachepoi_workbookProtection_workbook_windows_protected.xlsx
|
apachepoi_workbookProtection_workbook_windows_protected.xlsx
|
||||||
apachepoi_workbookProtection_worksheet_protected.xlsx
|
apachepoi_workbookProtection_worksheet_protected.xlsx
|
||||||
apachepoi_xlsx-jdbc.xlsx
|
apachepoi_xlsx-jdbc.xlsx
|
||||||
|
calendar_stress_test.xlsx.pending
|
||||||
comments_stress_test.xlsx
|
comments_stress_test.xlsx
|
||||||
custom_properties.xlsx
|
custom_properties.xlsx
|
||||||
excel-reader-xlsx_data01.xlsx
|
excel-reader-xlsx_data01.xlsx
|
||||||
@ -176,6 +178,7 @@ excel-reader-xlsx_error08.xlsx.pending
|
|||||||
excel-reader-xlsx_inline01.xlsx
|
excel-reader-xlsx_inline01.xlsx
|
||||||
excel-reader-xlsx_libre01.xlsx
|
excel-reader-xlsx_libre01.xlsx
|
||||||
formula_stress_test.xlsx
|
formula_stress_test.xlsx
|
||||||
|
hyperlink_stress_test_2011.xlsx
|
||||||
interview.xlsx
|
interview.xlsx
|
||||||
issue.xlsx
|
issue.xlsx
|
||||||
jxls-core_formulaOneRow.xlsx
|
jxls-core_formulaOneRow.xlsx
|
||||||
@ -251,6 +254,7 @@ spreadsheet-parsexlsx_bug-6-2.xlsx
|
|||||||
spreadsheet-parsexlsx_bug-6.xlsx
|
spreadsheet-parsexlsx_bug-6.xlsx
|
||||||
spreadsheet-parsexlsx_bug-7.xlsx
|
spreadsheet-parsexlsx_bug-7.xlsx
|
||||||
spreadsheet-parsexlsx_bug-8.xlsx
|
spreadsheet-parsexlsx_bug-8.xlsx
|
||||||
|
text_and_numbers.xlsx
|
||||||
xlrd_merged_cells.xlsx
|
xlrd_merged_cells.xlsx
|
||||||
xlrd_reveng1.xlsx
|
xlrd_reveng1.xlsx
|
||||||
xlrd_test_comments_excel.xlsx
|
xlrd_test_comments_excel.xlsx
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 5591611cebf7454da2eab8fbaacbbb7f687cacb5
|
Subproject commit b422ac319612c2b54c9d46eeed78acde901eda7c
|
100
xlsx.js
100
xlsx.js
@ -1,7 +1,9 @@
|
|||||||
/* xlsx.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
/* xlsx.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||||
/* vim: set ts=2: */
|
/* vim: set ts=2: */
|
||||||
/*jshint eqnull:true */
|
/*jshint eqnull:true */
|
||||||
/* Spreadsheet Format -- jump to XLSX for the XLSX code */
|
var XLSX = {};
|
||||||
|
(function(XLSX){
|
||||||
|
XLSX.version = '0.6.0';
|
||||||
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||||
var SSF = {};
|
var SSF = {};
|
||||||
var make_ssf = function(SSF){
|
var make_ssf = function(SSF){
|
||||||
@ -496,9 +498,6 @@ SSF.get_table = function() { return table_fmt; };
|
|||||||
SSF.load_table = function(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i]) SSF.load(tbl[i], i); };
|
SSF.load_table = function(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i]) SSF.load(tbl[i], i); };
|
||||||
};
|
};
|
||||||
make_ssf(SSF);
|
make_ssf(SSF);
|
||||||
var XLSX = {};
|
|
||||||
(function(XLSX){
|
|
||||||
XLSX.version = '0.5.17';
|
|
||||||
var current_codepage, current_cptable;
|
var current_codepage, current_cptable;
|
||||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||||
if(typeof cptable === 'undefined') cptable = require('codepage');
|
if(typeof cptable === 'undefined') cptable = require('codepage');
|
||||||
@ -613,7 +612,7 @@ var utf8read = function(orig) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// matches <foo>...</foo> extracts content
|
// matches <foo>...</foo> extracts content
|
||||||
function matchtag(f,g) {return new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")+"m");}
|
function matchtag(f,g) {return new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")+"m");}
|
||||||
|
|
||||||
function parseVector(data) {
|
function parseVector(data) {
|
||||||
var h = parsexmltag(data);
|
var h = parsexmltag(data);
|
||||||
@ -1468,7 +1467,7 @@ function parseRels(data, currentFilePath) {
|
|||||||
currentFilePath = '/'+currentFilePath;
|
currentFilePath = '/'+currentFilePath;
|
||||||
}
|
}
|
||||||
var rels = {};
|
var rels = {};
|
||||||
|
var hash = {};
|
||||||
var resolveRelativePathIntoAbsolute = function (to) {
|
var resolveRelativePathIntoAbsolute = function (to) {
|
||||||
var toksFrom = currentFilePath.split('/');
|
var toksFrom = currentFilePath.split('/');
|
||||||
toksFrom.pop(); // folder path
|
toksFrom.pop(); // folder path
|
||||||
@ -1490,11 +1489,12 @@ function parseRels(data, currentFilePath) {
|
|||||||
/* 9.3.2.2 OPC_Relationships */
|
/* 9.3.2.2 OPC_Relationships */
|
||||||
if (y[0] === '<Relationship') {
|
if (y[0] === '<Relationship') {
|
||||||
var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
|
var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; rel.TargetMode = y.TargetMode;
|
||||||
var canonictarget = resolveRelativePathIntoAbsolute(y.Target);
|
var canonictarget = y.TargetMode === 'External' ? y.Target : resolveRelativePathIntoAbsolute(y.Target);
|
||||||
rels[canonictarget] = rel;
|
rels[canonictarget] = rel;
|
||||||
|
hash[y.Id] = rel;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
rels["!id"] = hash;
|
||||||
return rels;
|
return rels;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1664,7 +1664,7 @@ var strs = {}; // shared strings
|
|||||||
var _ssfopts = {}; // spreadsheet formatting options
|
var _ssfopts = {}; // spreadsheet formatting options
|
||||||
|
|
||||||
/* 18.3 Worksheets */
|
/* 18.3 Worksheets */
|
||||||
function parse_ws_xml(data, opts) {
|
function parse_ws_xml(data, opts, rels) {
|
||||||
if(!data) return data;
|
if(!data) return data;
|
||||||
/* 18.3.1.99 worksheet CT_Worksheet */
|
/* 18.3.1.99 worksheet CT_Worksheet */
|
||||||
var s = {};
|
var s = {};
|
||||||
@ -1752,6 +1752,25 @@ function parse_ws_xml(data, opts) {
|
|||||||
s[cell.r] = p;
|
s[cell.r] = p;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* 18.3.1.48 hyperlinks CT_Hyperlinks */
|
||||||
|
if(data.match(/<\/hyperlinks>/)) data.match(/<hyperlink[^>]*\/>/g).forEach(function(h) {
|
||||||
|
var val = parsexmltag(h); delete val[0];
|
||||||
|
if(!val.ref) return;
|
||||||
|
var rel = rels['!id'][val.id];
|
||||||
|
if(rel) {
|
||||||
|
val.Target = rel.Target;
|
||||||
|
if(val.location) val.Target += "#"+val.location;
|
||||||
|
val.Rel = rel;
|
||||||
|
}
|
||||||
|
var rng = decode_range(val.ref);
|
||||||
|
for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) {
|
||||||
|
var addr = encode_cell({c:C,r:R});
|
||||||
|
if(!s[addr]) s[addr] = {t:"str",v:undefined};
|
||||||
|
s[addr].l = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
|
if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
|
||||||
if(opts.sheetRows && s["!ref"]) {
|
if(opts.sheetRows && s["!ref"]) {
|
||||||
var tmpref = decode_range(s["!ref"]);
|
var tmpref = decode_range(s["!ref"]);
|
||||||
@ -1894,16 +1913,29 @@ var parse_BrtFmlaString = function(data, length, opts) {
|
|||||||
/* [MS-XLSB] 2.4.676 BrtMergeCell */
|
/* [MS-XLSB] 2.4.676 BrtMergeCell */
|
||||||
var parse_BrtMergeCell = parse_UncheckedRfX;
|
var parse_BrtMergeCell = parse_UncheckedRfX;
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.656 BrtHLink */
|
||||||
|
var parse_BrtHLink = function(data, length, opts) {
|
||||||
|
var end = data.l + length;
|
||||||
|
var rfx = parse_UncheckedRfX(data, 16);
|
||||||
|
var relId = parse_XLNullableWideString(data);
|
||||||
|
var loc = parse_XLWideString(data);
|
||||||
|
var tooltip = parse_XLWideString(data);
|
||||||
|
var display = parse_XLWideString(data);
|
||||||
|
data.l = end;
|
||||||
|
return {rfx:rfx, relId:relId, loc:loc, tooltip:tooltip, display:display};
|
||||||
|
};
|
||||||
|
|
||||||
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
/* [MS-XLSB] 2.1.7.61 Worksheet */
|
||||||
var parse_ws_bin = function(data, opts) {
|
var parse_ws_bin = function(data, opts, rels) {
|
||||||
if(!data) return data;
|
if(!data) return data;
|
||||||
|
if(!rels) rels = {'!id':{}};
|
||||||
var s = {};
|
var s = {};
|
||||||
|
|
||||||
var ref;
|
var ref;
|
||||||
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||||
|
|
||||||
var pass = false, end = false;
|
var pass = false, end = false;
|
||||||
var row, p, cf;
|
var row, p, cf, R, C,addr;
|
||||||
var mergecells = [];
|
var mergecells = [];
|
||||||
recordhopper(data, function(val, R) {
|
recordhopper(data, function(val, R) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
@ -1957,7 +1989,21 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtBeginMergeCells': break;
|
case 'BrtBeginMergeCells': break;
|
||||||
case 'BrtEndMergeCells': break;
|
case 'BrtEndMergeCells': break;
|
||||||
case 'BrtMergeCell': mergecells.push(val); break;
|
case 'BrtMergeCell': mergecells.push(val); break;
|
||||||
|
|
||||||
|
case 'BrtHLink':
|
||||||
|
var rel = rels['!id'][val.relId];
|
||||||
|
if(rel) {
|
||||||
|
val.Target = rel.Target;
|
||||||
|
if(val.loc) val.Target += "#"+val.loc;
|
||||||
|
val.Rel = rel;
|
||||||
|
}
|
||||||
|
for(R=val.rfx.s.r;R<=val.rfx.e.r;++R) for(C=val.rfx.s.c;C<=val.rfx.e.c;++C) {
|
||||||
|
addr = encode_cell({c:C,r:R});
|
||||||
|
if(!s[addr]) s[addr] = {t:"str",v:undefined};
|
||||||
|
s[addr].l = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'BrtArrFmla': break; // TODO
|
case 'BrtArrFmla': break; // TODO
|
||||||
case 'BrtShrFmla': break; // TODO
|
case 'BrtShrFmla': break; // TODO
|
||||||
case 'BrtBeginSheet': break;
|
case 'BrtBeginSheet': break;
|
||||||
@ -1986,7 +2032,6 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtFRTBegin': pass = true; break;
|
case 'BrtFRTBegin': pass = true; break;
|
||||||
case 'BrtFRTEnd': pass = false; break;
|
case 'BrtFRTEnd': pass = false; break;
|
||||||
case 'BrtEndSheet': break; // TODO
|
case 'BrtEndSheet': break; // TODO
|
||||||
case 'BrtHLink': break; // TODO
|
|
||||||
case 'BrtDrawing': break; // TODO
|
case 'BrtDrawing': break; // TODO
|
||||||
case 'BrtLegacyDrawing': break; // TODO
|
case 'BrtLegacyDrawing': break; // TODO
|
||||||
case 'BrtLegacyDrawingHF': break; // TODO
|
case 'BrtLegacyDrawingHF': break; // TODO
|
||||||
@ -2037,7 +2082,7 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
case 'BrtEndAFilter': break;
|
case 'BrtEndAFilter': break;
|
||||||
case 'BrtBeginFilterColumn': break;
|
case 'BrtBeginFilterColumn': break;
|
||||||
case 'BrtBeginFilters': break;
|
case 'BrtBeginFilters': break;
|
||||||
case 'BrtFilter': break;
|
case 'BrtFilter': break;
|
||||||
case 'BrtEndFilters': break;
|
case 'BrtEndFilters': break;
|
||||||
case 'BrtEndFilterColumn': break;
|
case 'BrtEndFilterColumn': break;
|
||||||
case 'BrtDynamicFilter': break;
|
case 'BrtDynamicFilter': break;
|
||||||
@ -2357,8 +2402,8 @@ function parse_wb(data, name, opts) {
|
|||||||
return name.substr(-4)===".bin" ? parse_wb_bin(data, opts) : parse_wb_xml(data, opts);
|
return name.substr(-4)===".bin" ? parse_wb_bin(data, opts) : parse_wb_xml(data, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_ws(data, name, opts) {
|
function parse_ws(data, name, opts, rels) {
|
||||||
return name.substr(-4)===".bin" ? parse_ws_bin(data, opts) : parse_ws_xml(data, opts);
|
return name.substr(-4)===".bin" ? parse_ws_bin(data, opts, rels) : parse_ws_xml(data, opts, rels);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_sty(data, name, opts) {
|
function parse_sty(data, name, opts) {
|
||||||
@ -2801,7 +2846,7 @@ var RecordEnum = {
|
|||||||
0x01EB: { n:"BrtEndMG", f:parsenoop },
|
0x01EB: { n:"BrtEndMG", f:parsenoop },
|
||||||
0x01EC: { n:"BrtBeginMap", f:parsenoop },
|
0x01EC: { n:"BrtBeginMap", f:parsenoop },
|
||||||
0x01ED: { n:"BrtEndMap", f:parsenoop },
|
0x01ED: { n:"BrtEndMap", f:parsenoop },
|
||||||
0x01EE: { n:"BrtHLink", f:parsenoop },
|
0x01EE: { n:"BrtHLink", f:parse_BrtHLink },
|
||||||
0x01EF: { n:"BrtBeginDCon", f:parsenoop },
|
0x01EF: { n:"BrtBeginDCon", f:parsenoop },
|
||||||
0x01F0: { n:"BrtEndDCon", f:parsenoop },
|
0x01F0: { n:"BrtEndDCon", f:parsenoop },
|
||||||
0x01F1: { n:"BrtBeginDRefs", f:parsenoop },
|
0x01F1: { n:"BrtBeginDRefs", f:parsenoop },
|
||||||
@ -3299,8 +3344,8 @@ function parseZip(zip, opts) {
|
|||||||
path = 'xl/worksheets/sheet'+(i+1-nmode)+(xlsb?'.bin':'.xml');
|
path = 'xl/worksheets/sheet'+(i+1-nmode)+(xlsb?'.bin':'.xml');
|
||||||
path = path.replace(/sheet0\./,"sheet.");
|
path = path.replace(/sheet0\./,"sheet.");
|
||||||
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
|
||||||
sheets[props.SheetNames[i]]=parse_ws(getzipdata(zip, path),path,opts);
|
|
||||||
sheetRels[props.SheetNames[i]]=parseRels(getzipdata(zip, relsPath, true), path);
|
sheetRels[props.SheetNames[i]]=parseRels(getzipdata(zip, relsPath, true), path);
|
||||||
|
sheets[props.SheetNames[i]]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[props.SheetNames[i]]);
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3346,13 +3391,6 @@ function readFileSync(data, options) {
|
|||||||
return readSync(data, o);
|
return readSync(data, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
XLSX.read = readSync;
|
|
||||||
XLSX.readFile = readFileSync;
|
|
||||||
XLSX.parseZip = parseZip;
|
|
||||||
return this;
|
|
||||||
|
|
||||||
})(XLSX);
|
|
||||||
|
|
||||||
var _chr = function(c) { return String.fromCharCode(c); };
|
var _chr = function(c) { return String.fromCharCode(c); };
|
||||||
|
|
||||||
function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = _chr(((col-1)%26) + 65) + s; return s; }
|
function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = _chr(((col-1)%26) + 65) + s; return s; }
|
||||||
@ -3469,10 +3507,8 @@ XLSX.utils = {
|
|||||||
get_formulae: get_formulae,
|
get_formulae: get_formulae,
|
||||||
sheet_to_row_object_array: sheet_to_row_object_array
|
sheet_to_row_object_array: sheet_to_row_object_array
|
||||||
};
|
};
|
||||||
|
XLSX.read = readSync;
|
||||||
if(typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
XLSX.readFile = readFileSync;
|
||||||
exports.read = XLSX.read;
|
XLSX.parseZip = parseZip;
|
||||||
exports.readFile = XLSX.readFile;
|
XLSX.SSF = SSF;
|
||||||
exports.utils = XLSX.utils;
|
})(typeof exports !== 'undefined' ? exports : XLSX);
|
||||||
exports.version = XLSX.version;
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user