ludc
2023-08-24 56c45e1f4be85d6bbfb3a03437021c6742b32ad9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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();
 
    /* OpenDocument Part 3 Section 2.2.1 OpenDocument Package */
    if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
 
    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);
 
    // parse themes before styles so that we can reliably decode theme/tint into rgb when parsing styles
    themes = {};
    if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipdata(zip, dir.themes[0].replace(/^\//,''), true),dir.themes[0], opts);
 
    styles = {};
        if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style, 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;
}