sheetjs-clone/bits/85_parsezip.js
SheetJS 6bc24374b9 version bump 0.7.7: needs more cowbell
- parsexmltag and other hot functions now better optimized for v8
- monomorphic functions (different types -> different funcs)
- more efficient decode_range implementation when source is trusted
- regular expressions cached and simplified without breaking correctness
- more efficient utf8 techniques when available
- XLSX: large functions broken down into sub-functions (e.g. `parse_ws_xml`)
- XLSB: avoid unnecessary binds
- XLSB: assume no exotic codepage exists (no one else tries to write XLSB)
- demo exposes rABS / worker / transferable options
- more tests
- jszip updated to 2.3.0
- SSF updated to 0.8.1
- codepage updated to 1.3.1
2014-06-29 14:29:45 -04:00

137 lines
4.4 KiB
JavaScript

function safe_parse_wbrels(wbrels, sheets) {
if(!wbrels) return 0;
try {
wbrels = sheets.map(function pwbr(w) { return [w.name, wbrels['!id'][w.id].Target]; });
} catch(e) { return null; }
return !wbrels || wbrels.length === 0 ? null : wbrels;
}
function safe_parse_ws(zip, path, relsPath, sheet, sheetRels, sheets, opts) {
try {
sheetRels[sheet]=parse_rels(getzipdata(zip, relsPath, true), path);
sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet]);
} catch(e) { if(opts.WTF) throw e; }
}
var nodirs = function nodirs(x){return x.substr(-1) != '/';};
function parse_zip(zip, opts) {
make_ssf(SSF);
opts = opts || {};
fix_read_opts(opts);
reset_cp();
var entries = keys(zip.files).filter(nodirs).sort();
var dir = parse_ct(getzipdata(zip, '[Content_Types].xml'), opts);
var xlsb = false;
var sheets, binname;
if(dir.workbooks.length === 0) {
binname = "xl/workbook.xml";
if(getzipdata(zip,binname, true)) dir.workbooks.push(binname);
}
if(dir.workbooks.length === 0) {
binname = "xl/workbook.bin";
if(!getzipfile(zip,binname,true)) throw new Error("Could not find workbook");
dir.workbooks.push(binname);
xlsb = true;
}
if(dir.workbooks[0].substr(-3) == "bin") xlsb = true;
if(xlsb) set_cp(1200);
if(!opts.bookSheets && !opts.bookProps) {
strs = [];
if(dir.sst) strs=parse_sst(getzipdata(zip, dir.sst.replace(/^\//,'')), dir.sst, opts);
styles = {};
if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style, opts);
themes = {};
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipdata(zip, dir.themes[0].replace(/^\//,''), true),dir.themes[0], opts);
}
var wb = parse_wb(getzipdata(zip, dir.workbooks[0].replace(/^\//,'')), dir.workbooks[0], opts);
var props = {}, propdata = "";
if(dir.coreprops.length !== 0) {
propdata = getzipdata(zip, dir.coreprops[0].replace(/^\//,''), true);
if(propdata) props = parse_core_props(propdata);
if(dir.extprops.length !== 0) {
propdata = getzipdata(zip, dir.extprops[0].replace(/^\//,''), true);
if(propdata) parse_ext_props(propdata, props);
}
}
var custprops = {};
if(!opts.bookSheets || opts.bookProps) {
if (dir.custprops.length !== 0) {
propdata = getzipdata(zip, dir.custprops[0].replace(/^\//,''), true);
if(propdata) custprops = parse_cust_props(propdata, opts);
}
}
var out = {};
if(opts.bookSheets || opts.bookProps) {
if(props.Worksheets && props.SheetNames.length > 0) sheets=props.SheetNames;
else if(wb.Sheets) sheets = wb.Sheets.map(function pluck(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;
}
sheets = {};
var deps = {};
if(opts.bookDeps && dir.calcchain) deps=parse_cc(getzipdata(zip, dir.calcchain.replace(/^\//,'')),dir.calcchain,opts);
var i=0;
var sheetRels = {};
var path, relsPath;
if(!props.Worksheets) {
var wbsheets = wb.Sheets;
props.Worksheets = wbsheets.length;
props.SheetNames = [];
for(var j = 0; j != wbsheets.length; ++j) {
props.SheetNames[j] = wbsheets[j].name;
}
}
var wbext = xlsb ? "bin" : "xml";
var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
var wbrels = parse_rels(getzipdata(zip, wbrelsfile, true), wbrelsfile);
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
/* Numbers iOS hack */
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
for(i = 0; i != props.Worksheets; ++i) {
if(wbrels) path = 'xl/' + (wbrels[i][1]).replace(/[\/]?xl\//, "");
else {
path = 'xl/worksheets/sheet'+(i+1-nmode)+"." + wbext;
path = path.replace(/sheet0\./,"sheet.");
}
relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts);
}
if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts);
out = {
Directory: dir,
Workbook: wb,
Props: props,
Custprops: custprops,
Deps: deps,
Sheets: sheets,
SheetNames: props.SheetNames,
Strings: strs,
Styles: styles,
Themes: themes,
SSF: SSF.get_table()
};
if(opts.bookFiles) {
out.keys = entries;
out.files = zip.files;
}
if(opts.bookVBA) {
if(dir.vba.length > 0) out.vbaraw = getzipdata(zip,dir.vba[0],true);
else if(dir.defaults.bin === 'application/vnd.ms-office.vbaProject') out.vbaraw = getzipdata(zip,'xl/vbaProject.bin',true);
}
return out;
}