updating to 0.11.2

This commit is contained in:
SheetJS 2017-08-10 19:55:45 -04:00
parent 705e09d4a9
commit 2fffd43aa8
6 changed files with 138 additions and 72 deletions

@ -14,3 +14,4 @@ update:
git show master:tests/mocha.css > tests/mocha.css
git show master:tests/mocha.js > tests/mocha.js
git show master:tests/xhr-hack.js > tests/xhr-hack.js
git show master:demos/datagrid/index.html > datagrid.html

@ -105,6 +105,8 @@ function process_wb(wb) {
var data = XLSX.utils.sheet_to_json(ws, {header:1});
if(!cDg) cDg = canvasDatagrid({ parentNode:document.getElementById('htmlout'), data:data });
else cDg.data = data;
var range = XLSX.utils.decode_range(ws['!ref']);
for(var i = range.s.c; i <= range.e.c; ++i) cDg.schema[i - range.s.c].title = XLSX.utils.encode_col(i);
document.getElementById('xport').disabled = false;
if(typeof console !== 'undefined') console.log("output", new Date());
}

@ -568,14 +568,14 @@ describe('input formats', function() {
X.read(fs.readFileSync(paths.cstxlsb, 'base64'), {type: 'base64'});
});
var k = browser ? 'array' : 'buffer';
(typeof UInt8Array !== 'undefined' ? it : it.skip)('should read ' + k + 's', function() {
X.read(fs.readFileSync(paths.cstxls, 'buffer'), {type: k});
X.read(fs.readFileSync(paths.cstxml, 'buffer'), {type: k});
X.read(fs.readFileSync(paths.cstods, 'buffer'), {type: k});
X.read(fs.readFileSync(paths.cstxlsx, 'buffer'), {type: k});
X.read(fs.readFileSync(paths.cstxlsb, 'buffer'), {type: k});
(typeof Uint8Array !== 'undefined' ? it : it.skip)('should read ' + k + 's', function() {
X.read(fs.readFileSync(paths.cstxls, browser ? 'buffer' : null), {type: k});
X.read(fs.readFileSync(paths.cstxml, browser ? 'buffer' : null), {type: k});
X.read(fs.readFileSync(paths.cstods, browser ? 'buffer' : null), {type: k});
X.read(fs.readFileSync(paths.cstxlsx, browser ? 'buffer' : null), {type: k});
X.read(fs.readFileSync(paths.cstxlsb, browser ? 'buffer' : null), {type: k});
});
(typeof UInt8Array !== 'undefined' ? it : it.skip)('should read array', function() {
(typeof Uint8Array !== 'undefined' ? it : it.skip)('should read array', function() {
X.read(fs.readFileSync(paths.cstxls, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
X.read(fs.readFileSync(paths.cstxml, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
X.read(fs.readFileSync(paths.cstxlsx, 'binary').split("").map(function(x) { return x.charCodeAt(0); }), {type:'array'});
@ -1845,6 +1845,40 @@ describe('csv', function() {
});
});
describe('HTML', function() {
describe('input', function(){
var b = "<table><tr><td>-0.08</td><td>4,001</td><td>\u00e3\u0081\u0082 1</td></tr><tr><td>$41.08</td><td>11%</td></tr></table>";
it('should generate numbers by default', function() {
var sheet = X.read(b, {type:"binary"}).Sheets.Sheet1;
var cell = get_cell(sheet, "A1");
assert.equal(cell.v, -0.08);
assert.equal(cell.t, 'n');
cell = get_cell(sheet, "B1");
assert.equal(cell.v, 4001);
cell = get_cell(sheet, "C1");
assert.equal(cell.v, "あ 1");
cell = get_cell(sheet, "A2");
assert.equal(cell.v, 41.08);
cell = get_cell(sheet, "B2");
assert.equal(cell.v, .11);
});
it('should generate strings if raw option is passed', function() {
var sheet = X.read(b, {type:"binary", raw:true}).Sheets.Sheet1;
var cell = get_cell(sheet, "A1");
assert.equal(cell.v, "-0.08");
assert.equal(cell.t, 's');
cell = get_cell(sheet, "B1");
assert.equal(cell.v, "4,001");
cell = get_cell(sheet, "C1");
assert.equal(cell.v, "あ 1");
cell = get_cell(sheet, "A2");
assert.equal(cell.v, "$41.08");
cell = get_cell(sheet, "B2");
assert.equal(cell.v, "11%");
});
});
});
describe('js -> file -> js', function() {
var data, ws, wb, BIN="binary";
var bef = (function() {

24
xlsx.core.min.js vendored

File diff suppressed because one or more lines are too long

24
xlsx.full.min.js vendored

File diff suppressed because one or more lines are too long

111
xlsx.js

@ -6,7 +6,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.11.1';
XLSX.version = '0.11.2';
var current_codepage = 1200;
/*global cptable:true */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
@ -1026,7 +1026,7 @@ var DO_NOT_EXPORT_CFB = true;
/* [MS-CFB] v20130118 */
var CFB = (function _CFB(){
var exports = {};
exports.version = '0.12.0';
exports.version = '0.12.1';
function parse(file, options) {
var mver = 3; // major version
var ssz = 512; // sector size
@ -1197,7 +1197,7 @@ function build_full_paths(FI, FPD, FP, Paths) {
if(FI[i].type === 0 /* unknown */) continue;
j = dad[i];
if(j === 0) FP[i] = FP[0] + "/" + FP[i];
else while(j !== 0) {
else while(j !== 0 && j !== dad[j]) {
FP[i] = FP[j] + "/" + FP[i];
j = dad[j];
}
@ -1298,7 +1298,6 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
var blob = sector.slice(i, i+128);
prep_blob(blob, 64);
namelen = blob.read_shift(2);
if(namelen === 0) continue;
name = __utf16le(blob,0,namelen-pl);
Paths.push(name);
var o = ({
@ -1319,6 +1318,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
if(mtime !== 0) o.mt = read_date(blob, blob.l-8);
o.start = blob.read_shift(4, 'i');
o.size = blob.read_shift(4, 'i');
if(o.size < 0 && o.start < 0) { o.size = o.type = 0; o.start = ENDOFCHAIN; o.name = ""; }
if(o.type === 5) { /* root */
minifat_store = o.start;
if(nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData";
@ -1331,7 +1331,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
prep_blob(o.content, 0);
} else {
o.storage = 'minifat';
if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN) {
if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
o.content = (sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size));
prep_blob(o.content, 0);
}
@ -1360,6 +1360,9 @@ function readSync(blob, options) {
return parse(blob, options);
}
function find(cfb, path) {
return cfb.find(path);
}
/** CFB Constants */
var MSSZ = 64; /* Mini Sector Size = 1<<6 */
//var MSCSZ = 4096; /* Mini Stream Cutoff Size */
@ -1385,6 +1388,7 @@ var consts = {
EntryTypes: ['unknown','storage','stream','lockbytes','property','root']
};
exports.find = find;
exports.read = readSync;
exports.parse = parse;
exports.utils = {
@ -1473,7 +1477,7 @@ function parse_isodur(s) {
var good_pd_date = new Date('2017-02-19T19:06:09.000Z');
if(isNaN(good_pd_date.getFullYear())) good_pd_date = new Date('2/19/17');
var good_pd = good_pd_date.getFullYear() == 2017;
/* parses aa date as a local date */
/* parses a date as a local date */
function parseDate(str, fixdate) {
var d = new Date(str);
if(good_pd) {
@ -1488,7 +1492,9 @@ if(fixdate > 0) d.setTime(d.getTime() + d.getTimezoneOffset() * 60 * 1000);
d.setFullYear(d.getFullYear() + 100); return d;
}
var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
return new Date(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0));
var out = new Date(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0));
if(str.indexOf("Z") > -1) out = new Date(out.getTime() - out.getTimezoneOffset() * 60 * 1000);
return out;
}
function cc2str(arr) {
@ -1514,6 +1520,16 @@ function dup(o) {
function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; }
/* TODO: stress test */
function fuzzynum(s) {
var v = Number(s);
if(!isNaN(v)) return v;
var wt = 1;
var ss = s.replace(/([\d]),([\d])/g,"$1$2").replace(/[$]/g,"").replace(/[%]/g, function() { wt *= 100; return "";});
if(!isNaN(v = Number(ss))) return v / wt;
ss = ss.replace(/[(](.*)[)]/,function($$, $1) { wt = -wt; return $1;});
if(!isNaN(v = Number(ss))) return v / wt;
return v;
}
function fuzzydate(s) {
var o = new Date(s), n = new Date(NaN);
var y = o.getYear(), m = o.getMonth(), d = o.getDate();
@ -1521,10 +1537,17 @@ function fuzzydate(s) {
if(y < 0 || y > 8099) return n;
if((m > 0 || d > 1) && y != 101) return o;
if(s.toLowerCase().match(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/)) return o;
if(!s.match(/[a-zA-Z]/)) return o;
if(s.match(/[^-0-9:,\/\\]/)) return o;
return n;
}
var safe_split_regex = "abacaba".split(/(:?b)/i).length == 5;
function split_regex(str, re, def) {
if(safe_split_regex || typeof re == "string") return str.split(re);
var p = str.split(re), o = [p[0]];
for(var i = 1; i < p.length; ++i) { o.push(def); o.push(p[i]); }
return o;
}
function getdatastr(data) {
if(!data) return null;
if(data.data) return debom(data.data);
@ -1600,7 +1623,7 @@ function resolve_path(path, base) {
return result.join('/');
}
var attregexg=/([^"\s?>\/]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex=/<[^>]*>/g;
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+=(?:"[^"]*"|'[^']*'|[^'">\s]+))*\s?[\/\?]?>/g;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
function parsexmltag(tag, skip_root) {
var z = ({});
@ -1645,8 +1668,10 @@ var unescapexml = (function() {
/* 22.4.2.4 bstr (Basic String) */
var encregex = /&(?:quot|apos|gt|lt|amp|#x?([\da-fA-F]+));/g, coderegex = /_x([\da-fA-F]{4})_/g;
return function unescapexml(text) {
var s = text + '';
return s.replace(encregex, function($$, $1) { return encodings[$$]||String.fromCharCode(parseInt($1,$$.indexOf("x")>-1?16:10))||$$; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
var s = text + '', i = s.indexOf("<![CDATA[");
if(i == -1) return s.replace(encregex, function($$, $1) { return encodings[$$]||String.fromCharCode(parseInt($1,$$.indexOf("x")>-1?16:10))||$$; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
var j = s.indexOf("]]>");
return unescapexml(s.slice(0, i)) + s.slice(i+9,j) + unescapexml(s.slice(j+3));
};
})();
@ -5409,8 +5434,8 @@ var SYLK = (function() {
if(val.charAt(0) === '"') val = val.substr(1,val.length - 2);
else if(val === 'TRUE') val = true;
else if(val === 'FALSE') val = false;
else if(+val === +val) {
val = +val;
else if(!isNaN(fuzzynum(val))) {
val = fuzzynum(val);
if(next_cell_format !== null && SSF.is_date(next_cell_format)) val = numdate(val);
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
@ -5571,7 +5596,7 @@ var DIF = (function() {
case 0:
if(data === 'TRUE') arr[R][C] = true;
else if(data === 'FALSE') arr[R][C] = false;
else if(+value == +value) arr[R][C] = +value;
else if(!isNaN(fuzzynum(value))) arr[R][C] = fuzzynum(value);
else if(!isNaN(fuzzydate(value).getDate())) arr[R][C] = parseDate(value);
else arr[R][C] = value;
++C; break;
@ -5657,7 +5682,7 @@ var PRN = (function() {
else if(data === 'TRUE') arr[R][C] = true;
else if(data === 'FALSE') arr[R][C] = false;
else if(data === ""){/* empty */}
else if(+data == +data) arr[R][C] = +data;
else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
else arr[R][C] = data;
}
@ -5708,7 +5733,7 @@ var PRN = (function() {
else if(s.charCodeAt(0) == 0x3D) { cell.t = 'n'; cell.f = s.substr(1); }
else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; }
else if(!isNaN(v = fuzzynum(s))) { cell.t = 'n'; cell.w = s; cell.v = v; }
else if(!isNaN(fuzzydate(s).getDate()) || _re && s.match(_re)) {
cell.z = o.dateNF || SSF._table[14];
var k = 0;
@ -14854,11 +14879,11 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
/* TODO: WTF */
function parse_props(cfb) {
/* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
var DSI = cfb.find('!DocumentSummaryInformation');
var DSI = CFB.find(cfb, '!DocumentSummaryInformation');
if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {/* empty */}
/* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
var SI = cfb.find('!SummaryInformation');
var SI = CFB.find(cfb, '!SummaryInformation');
if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {/* empty */}
}
@ -14866,27 +14891,28 @@ function parse_xlscfb(cfb, options) {
if(!options) options = {};
fix_read_opts(options);
reset_cp();
var CompObj, Summary, Workbook;
var CompObj, Summary, WB;
if(cfb.FullPaths) {
CompObj = cfb.find('!CompObj');
Summary = cfb.find('!SummaryInformation');
Workbook = cfb.find('/Workbook');
CompObj = CFB.find(cfb, '!CompObj');
Summary = CFB.find(cfb, '!SummaryInformation');
WB = CFB.find(cfb, '/Workbook');
} else {
prep_blob(cfb, 0);
Workbook = ({content: cfb});
WB = ({content: cfb});
}
if(!Workbook) Workbook = cfb.find('/Book');
if(!WB) WB = CFB.find(cfb, '/Book');
var CompObjP, SummaryP, WorkbookP;
var _data;
if(CompObj) CompObjP = parse_compobj(CompObj);
if(options.bookProps && !options.bookSheets) WorkbookP = ({});
else {
if(Workbook) WorkbookP = parse_workbook(Workbook.content, options);
if(WB && WB.content) WorkbookP = parse_workbook(WB.content, options);
/* Quattro Pro 7-8 */
else if(cfb.find('PerfectOffice_MAIN')) WorkbookP = WK_.to_workbook(cfb.find('PerfectOffice_MAIN').content, options);
else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
/* Quattro Pro 9 */
else if(cfb.find('NativeContent_MAIN')) WorkbookP = WK_.to_workbook(cfb.find('NativeContent_MAIN').content, options);
else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, options);
else throw new Error("Cannot find Workbook stream");
}
@ -16271,7 +16297,7 @@ var HTML_ = (function() {
if(!mtch) throw new Error("Invalid HTML: could not find <table>");
var mtch2 = str.match(/<\/table/i);
var i = mtch.index, j = mtch2 && mtch2.index || str.length;
var rows = str.slice(i, j).split(/(:?<tr[^>]*>)/i);
var rows = split_regex(str.slice(i, j), /(:?<tr[^>]*>)/i, "<tr>");
var R = -1, C = 0, RS = 0, CS = 0;
var range = {s:{r:10000000, c:10000000},e:{r:0,c:0}};
var merges = [], midx = 0;
@ -16300,12 +16326,14 @@ var HTML_ = (function() {
if(range.e.c < C) range.e.c = C;
if(opts.dense) {
if(!ws[R]) ws[R] = [];
if(Number(m) == Number(m)) ws[R][C] = {t:'n', v:+m};
if(opts.raw) ws[R][C] = {t:'s', v:m};
else if(!isNaN(fuzzynum(m))) ws[R][C] = {t:'n', v:fuzzynum(m)};
else ws[R][C] = {t:'s', v:m};
} else {
var coord = encode_cell({r:R, c:C});
/* TODO: value parsing */
if(Number(m) == Number(m)) ws[coord] = {t:'n', v:+m};
if(opts.raw) ws[coord] = {t:'s', v:m};
else if(!isNaN(fuzzynum(m))) ws[coord] = {t:'n', v:fuzzynum(m)};
else ws[coord] = {t:'s', v:m};
}
C += CS;
@ -16397,7 +16425,8 @@ function parse_dom_table(table, _opts) {
if((RS = +elt.getAttribute("rowspan"))>0 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
var o = {t:'s', v:v};
if(v != null && v.length) {
if(!isNaN(Number(v))) o = {t:'n', v:Number(v)};
if(opts.raw) o = {t:'s', v:v};
else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
else if(!isNaN(fuzzydate(v).getDate())) {
o = ({t:'d', v:parseDate(v)});
if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)});
@ -17320,20 +17349,20 @@ function parse_zip(zip, opts) {
/* references to [MS-OFFCRYPTO] */
function parse_xlsxcfb(cfb, opts) {
var f = 'Version';
var data = cfb.find(f);
var data = CFB.find(cfb, f);
if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
var version = parse_DataSpaceVersionInfo(data.content);
/* 2.3.4.1 */
f = 'DataSpaceMap';
data = cfb.find(f);
data = CFB.find(cfb, f);
if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
var dsm = parse_DataSpaceMap(data.content);
if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage")
throw new Error("ECMA-376 Encrypted file bad " + f);
f = 'StrongEncryptionDataSpace';
data = cfb.find(f);
data = CFB.find(cfb, f);
if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
var seds = parse_DataSpaceDefinition(data.content);
if(seds.length != 1 || seds[0] != "StrongEncryptionTransform")
@ -17341,12 +17370,12 @@ function parse_xlsxcfb(cfb, opts) {
/* 2.3.4.3 */
f = '!Primary';
data = cfb.find(f);
data = CFB.find(cfb, f);
if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
var hdr = parse_Primary(data.content);
f = 'EncryptionInfo';
data = cfb.find(f);
data = CFB.find(cfb, f);
if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
var einfo = parse_EncryptionInfo(data.content);
@ -17491,7 +17520,7 @@ function firstbyte(f,o) {
}
function read_cfb(cfb, opts) {
if(cfb.find("EncryptedPackage")) return parse_xlsxcfb(cfb, opts);
if(CFB.find(cfb, "EncryptedPackage")) return parse_xlsxcfb(cfb, opts);
return parse_xlscfb(cfb, opts);
}
@ -17688,11 +17717,11 @@ function writeFileAsync(filename, wb, opts, cb) {
var _cb = cb; if(!(_cb instanceof Function)) _cb = (opts);
return _fs.writeFile(filename, writeSync(wb, o), _cb);
}
function sheet_to_json(sheet, opts){
function sheet_to_json(sheet, opts) {
if(sheet == null || sheet["!ref"] == null) return [];
var val = {t:'n',v:0}, header = 0, offset = 1, hdr = [], isempty = true, v=0, vv="";
var r = {s:{r:0,c:0},e:{r:0,c:0}};
var o = opts != null ? opts : {};
var o = opts || {};
var raw = o.raw;
var defval = o.defval;
var range = o.range != null ? o.range : sheet["!ref"];
@ -17706,8 +17735,8 @@ function sheet_to_json(sheet, opts){
}
if(header > 0) offset = 0;
var rr = encode_row(r.s.r);
var cols = new Array(r.e.c-r.s.c+1);
var out = new Array(r.e.r-r.s.r-offset+1);
var cols = [];
var out = [];
var outi = 0, counter = 0;
var dense = Array.isArray(sheet);
var R = r.s.r, C = 0, CC = 0;