forked from sheetjs/sheetjs
sheet visibility
- XLSB read V H VH + write V H VH - XLSX read V H VH + write V H VH - XLML read V H VH + write V H VH - XLS read V H VH - fixes #123 h/t @rla-dev @Mior - fixes #464 h/t @enobufs @thowk - fixes #498 h/t @digity - fixes #503 h/t @digity
This commit is contained in:
parent
233eae2f4e
commit
97f7c1d4bf
32
README.md
32
README.md
@ -44,6 +44,7 @@ with a unified JS representation, and ES3/ES5 browser compatibility back to IE6.
|
|||||||
+ [Formulae](#formulae)
|
+ [Formulae](#formulae)
|
||||||
+ [Column Properties](#column-properties)
|
+ [Column Properties](#column-properties)
|
||||||
+ [Hyperlinks](#hyperlinks)
|
+ [Hyperlinks](#hyperlinks)
|
||||||
|
+ [Sheet Visibility](#sheet-visibility)
|
||||||
- [Parsing Options](#parsing-options)
|
- [Parsing Options](#parsing-options)
|
||||||
* [Input Type](#input-type)
|
* [Input Type](#input-type)
|
||||||
* [Guessing File Type](#guessing-file-type)
|
* [Guessing File Type](#guessing-file-type)
|
||||||
@ -714,6 +715,37 @@ ws['A3'].l = { Target:"http://sheetjs.com", Tooltip:"Find us @ SheetJS.com!" };
|
|||||||
Note that Excel does not automatically style hyperlinks -- they will generally
|
Note that Excel does not automatically style hyperlinks -- they will generally
|
||||||
be displayed as normal text.
|
be displayed as normal text.
|
||||||
|
|
||||||
|
#### Sheet Visibility
|
||||||
|
|
||||||
|
Excel enables hiding sheets in the lower tab bar. The sheet data is stored in
|
||||||
|
the file but the UI does not readily make it available. Standard hidden sheets
|
||||||
|
are revealed in the unhide menu. Excel also has "very hidden" sheets which
|
||||||
|
cannot be revealed in the menu. It is only accessible in the VB Editor!
|
||||||
|
|
||||||
|
The visibility setting is stored in the `Hidden` property of the sheet props
|
||||||
|
array. The values are:
|
||||||
|
|
||||||
|
| Value | Definition |
|
||||||
|
|:-----:|:------------|
|
||||||
|
| 0 | Visible |
|
||||||
|
| 1 | Hidden |
|
||||||
|
| 2 | Very Hidden |
|
||||||
|
|
||||||
|
With <https://rawgit.com/SheetJS/test_files/master/sheet_visibility.xlsx>:
|
||||||
|
|
||||||
|
```js
|
||||||
|
> wb.Workbook.Sheets.map(function(x) { return [x.name, x.Hidden] })
|
||||||
|
[ [ 'Visible', 0 ], [ 'Hidden', 1 ], [ 'VeryHidden', 2 ] ]
|
||||||
|
```
|
||||||
|
|
||||||
|
Non-Excel formats do not support the Very Hidden state. The best way to test
|
||||||
|
if a sheet is visible is to check if the `Hidden` property is logical negation:
|
||||||
|
|
||||||
|
```js
|
||||||
|
> wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] })
|
||||||
|
[ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ]
|
||||||
|
```
|
||||||
|
|
||||||
## Parsing Options
|
## Parsing Options
|
||||||
|
|
||||||
The exported `read` and `readFile` functions accept an options argument:
|
The exported `read` and `readFile` functions accept an options argument:
|
||||||
|
@ -179,6 +179,7 @@ function prep_blob(blob, pos/*:number*/) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parsenoop(blob, length/*:number*/) { blob.l += length; }
|
function parsenoop(blob, length/*:number*/) { blob.l += length; }
|
||||||
|
function parsenooplog(blob, length/*:number*/) { if(typeof console != 'undefined') console.log(blob.slice(blob.l, blob.l + length)); blob.l += length; }
|
||||||
|
|
||||||
function writenoop(blob, length/*:number*/) { blob.l += length; }
|
function writenoop(blob, length/*:number*/) { blob.l += length; }
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ function parse_ext_props(data, p) {
|
|||||||
var v = parseVector(q.HeadingPairs);
|
var v = parseVector(q.HeadingPairs);
|
||||||
var parts = parseVector(q.TitlesOfParts).map(function(x) { return x.v; });
|
var parts = parseVector(q.TitlesOfParts).map(function(x) { return x.v; });
|
||||||
var idx = 0, len = 0;
|
var idx = 0, len = 0;
|
||||||
for(var i = 0; i !== v.length; ++i) {
|
for(var i = 0; i !== v.length; i+=2) {
|
||||||
len = +(v[++i].v);
|
len = +(v[i+1].v);
|
||||||
switch(v[i].v) {
|
switch(v[i].v) {
|
||||||
case "Worksheets":
|
case "Worksheets":
|
||||||
case "工作表":
|
case "工作表":
|
||||||
@ -69,6 +69,7 @@ function parse_ext_props(data, p) {
|
|||||||
idx += len;
|
idx += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
|||||||
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
|
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
|
||||||
}
|
}
|
||||||
if(r.length > 0) {
|
if(r.length > 0) {
|
||||||
var params = {r:rr}
|
var params = ({r:rr}/*:any*/);
|
||||||
if(rows && rows[R]) {
|
if(rows && rows[R]) {
|
||||||
var row = rows[R];
|
var row = rows[R];
|
||||||
if(row.hidden) params.hidden = 1;
|
if(row.hidden) params.hidden = 1;
|
||||||
|
@ -37,7 +37,7 @@ var WBViewDef = [
|
|||||||
|
|
||||||
/* 18.2.19 (CT_Sheet) Defaults */
|
/* 18.2.19 (CT_Sheet) Defaults */
|
||||||
var SheetDef = [
|
var SheetDef = [
|
||||||
['state', 'visible']
|
//['state', 'visible']
|
||||||
];
|
];
|
||||||
|
|
||||||
/* 18.2.2 (CT_CalcPr) Defaults */
|
/* 18.2.2 (CT_CalcPr) Defaults */
|
||||||
|
@ -43,7 +43,15 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
|
|||||||
/* 18.2.20 sheets CT_Sheets 1 */
|
/* 18.2.20 sheets CT_Sheets 1 */
|
||||||
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
||||||
/* 18.2.19 sheet CT_Sheet + */
|
/* 18.2.19 sheet CT_Sheet + */
|
||||||
case '<sheet': delete y[0]; y.name = unescapexml(utf8read(y.name)); wb.Sheets.push(y); break;
|
case '<sheet':
|
||||||
|
switch(y.state) {
|
||||||
|
case "hidden": y.Hidden = 1; break;
|
||||||
|
case "veryHidden": y.Hidden = 2; break;
|
||||||
|
default: y.Hidden = 0;
|
||||||
|
}
|
||||||
|
delete y.state;
|
||||||
|
y.name = unescapexml(utf8read(y.name));
|
||||||
|
delete y[0]; wb.Sheets.push(y); break;
|
||||||
case '</sheet>': break;
|
case '</sheet>': break;
|
||||||
|
|
||||||
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
||||||
@ -153,8 +161,17 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
|
|||||||
o[o.length] = WB_XML_ROOT;
|
o[o.length] = WB_XML_ROOT;
|
||||||
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb), codeName:"ThisWorkbook"}));
|
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb), codeName:"ThisWorkbook"}));
|
||||||
o[o.length] = "<sheets>";
|
o[o.length] = "<sheets>";
|
||||||
for(var i = 0; i != wb.SheetNames.length; ++i)
|
var sheets = wb.Workbook && wb.Workbook.Sheets || [];
|
||||||
o[o.length] = (writextag('sheet',null,{name:escapexml(wb.SheetNames[i].substr(0,31)), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
for(var i = 0; i != wb.SheetNames.length; ++i) {
|
||||||
|
var sht = ({name:escapexml(wb.SheetNames[i].substr(0,31))}/*:any*/);
|
||||||
|
sht.sheetId = ""+(i+1);
|
||||||
|
sht["r:id"] = "rId"+(i+1);
|
||||||
|
if(sheets[i]) switch(sheets[i].Hidden) {
|
||||||
|
case 1: sht.state = "hidden"; break;
|
||||||
|
case 2: sht.state = "veryHidden"; break;
|
||||||
|
}
|
||||||
|
o[o.length] = (writextag('sheet',null,sht));
|
||||||
|
}
|
||||||
o[o.length] = "</sheets>";
|
o[o.length] = "</sheets>";
|
||||||
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
||||||
return o.join("");
|
return o.join("");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* [MS-XLSB] 2.4.301 BrtBundleSh */
|
/* [MS-XLSB] 2.4.301 BrtBundleSh */
|
||||||
function parse_BrtBundleSh(data, length/*:number*/) {
|
function parse_BrtBundleSh(data, length/*:number*/) {
|
||||||
var z = {};
|
var z = {};
|
||||||
z.hsState = data.read_shift(4); //ST_SheetState
|
z.Hidden = data.read_shift(4); //hsState ST_SheetState
|
||||||
z.iTabID = data.read_shift(4);
|
z.iTabID = data.read_shift(4);
|
||||||
z.strRelID = parse_RelID(data,length-8);
|
z.strRelID = parse_RelID(data,length-8);
|
||||||
z.name = parse_XLWideString(data);
|
z.name = parse_XLWideString(data);
|
||||||
@ -9,7 +9,7 @@ function parse_BrtBundleSh(data, length/*:number*/) {
|
|||||||
}
|
}
|
||||||
function write_BrtBundleSh(data, o) {
|
function write_BrtBundleSh(data, o) {
|
||||||
if(!o) o = new_buf(127);
|
if(!o) o = new_buf(127);
|
||||||
o.write_shift(4, data.hsState);
|
o.write_shift(4, data.Hidden);
|
||||||
o.write_shift(4, data.iTabID);
|
o.write_shift(4, data.iTabID);
|
||||||
write_RelID(data.strRelID, o);
|
write_RelID(data.strRelID, o);
|
||||||
write_XLWideString(data.name.substr(0,31), o);
|
write_XLWideString(data.name.substr(0,31), o);
|
||||||
@ -138,7 +138,8 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
|
|||||||
function write_BUNDLESHS(ba, wb, opts) {
|
function write_BUNDLESHS(ba, wb, opts) {
|
||||||
write_record(ba, "BrtBeginBundleShs");
|
write_record(ba, "BrtBeginBundleShs");
|
||||||
for(var idx = 0; idx != wb.SheetNames.length; ++idx) {
|
for(var idx = 0; idx != wb.SheetNames.length; ++idx) {
|
||||||
var d = { hsState: 0, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] };
|
var viz = wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx] && wb.Workbook.Sheets[idx].Hidden || 0;
|
||||||
|
var d = { Hidden: viz, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] };
|
||||||
write_record(ba, "BrtBundleSh", write_BrtBundleSh(d));
|
write_record(ba, "BrtBundleSh", write_BrtBundleSh(d));
|
||||||
}
|
}
|
||||||
write_record(ba, "BrtEndBundleShs");
|
write_record(ba, "BrtEndBundleShs");
|
||||||
@ -156,9 +157,34 @@ function write_BrtFileVersion(data, o) {
|
|||||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.298 BrtBookView */
|
||||||
|
function write_BrtBookView(idx, o) {
|
||||||
|
if(!o) o = new_buf(29);
|
||||||
|
o.write_shift(-4, 0);
|
||||||
|
o.write_shift(-4, 460);
|
||||||
|
o.write_shift(4, 28800);
|
||||||
|
o.write_shift(4, 17600);
|
||||||
|
o.write_shift(4, 500);
|
||||||
|
o.write_shift(4, idx);
|
||||||
|
o.write_shift(4, idx);
|
||||||
|
var flags = 0x78;
|
||||||
|
o.write_shift(1, flags);
|
||||||
|
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||||
|
}
|
||||||
|
|
||||||
/* [MS-XLSB] 2.1.7.60 Workbook */
|
/* [MS-XLSB] 2.1.7.60 Workbook */
|
||||||
function write_BOOKVIEWS(ba, wb, opts) {
|
function write_BOOKVIEWS(ba, wb, opts) {
|
||||||
|
/* required if hidden tab appears before visible tab */
|
||||||
|
if(!wb.Workbook || !wb.Workbook.Sheets) return;
|
||||||
|
var sheets = wb.Workbook.Sheets;
|
||||||
|
var i = 0, vistab = -1, hidden = -1;
|
||||||
|
for(; i < sheets.length; ++i) {
|
||||||
|
if(!sheets[i] || !sheets[i].Hidden && vistab == -1) vistab = i;
|
||||||
|
else if(sheets[i].Hidden == 1 && hidden == -1) hidden = i;
|
||||||
|
}
|
||||||
|
if(hidden > vistab) return;
|
||||||
write_record(ba, "BrtBeginBookViews");
|
write_record(ba, "BrtBeginBookViews");
|
||||||
|
write_record(ba, "BrtBookView", write_BrtBookView(vistab));
|
||||||
/* 1*(BrtBookView *FRT) */
|
/* 1*(BrtBookView *FRT) */
|
||||||
write_record(ba, "BrtEndBookViews");
|
write_record(ba, "BrtEndBookViews");
|
||||||
}
|
}
|
||||||
@ -192,7 +218,7 @@ function write_wb_bin(wb, opts) {
|
|||||||
write_record(ba, "BrtWbProp", write_BrtWbProp());
|
write_record(ba, "BrtWbProp", write_BrtWbProp());
|
||||||
/* [ACABSPATH] */
|
/* [ACABSPATH] */
|
||||||
/* [[BrtBookProtectionIso] BrtBookProtection] */
|
/* [[BrtBookProtectionIso] BrtBookProtection] */
|
||||||
/* write_BOOKVIEWS(ba, wb, opts); */
|
write_BOOKVIEWS(ba, wb, opts);
|
||||||
write_BUNDLESHS(ba, wb, opts);
|
write_BUNDLESHS(ba, wb, opts);
|
||||||
/* [FNGROUP] */
|
/* [FNGROUP] */
|
||||||
/* [EXTERNALS] */
|
/* [EXTERNALS] */
|
||||||
|
@ -186,6 +186,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
|||||||
var cstys = [], csty, seencol = false;
|
var cstys = [], csty, seencol = false;
|
||||||
var arrayf = [];
|
var arrayf = [];
|
||||||
var rowinfo = [];
|
var rowinfo = [];
|
||||||
|
var Workbook = { Sheets:[] }, wsprops = {};
|
||||||
xlmlregex.lastIndex = 0;
|
xlmlregex.lastIndex = 0;
|
||||||
str = str.replace(/<!--([^\u2603]*?)-->/mg,"");
|
str = str.replace(/<!--([^\u2603]*?)-->/mg,"");
|
||||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||||
@ -260,6 +261,8 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
|||||||
mergecells = [];
|
mergecells = [];
|
||||||
arrayf = [];
|
arrayf = [];
|
||||||
rowinfo = [];
|
rowinfo = [];
|
||||||
|
wsprops = {name:sheetname, Hidden:0};
|
||||||
|
Workbook.Sheets.push(wsprops);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Table':
|
case 'Table':
|
||||||
@ -484,8 +487,15 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
|||||||
|
|
||||||
/* WorksheetOptions */
|
/* WorksheetOptions */
|
||||||
case 'WorksheetOptions': switch(Rn[3]) {
|
case 'WorksheetOptions': switch(Rn[3]) {
|
||||||
|
case 'Visible':
|
||||||
|
if(Rn[0].slice(-2) === "/>"){}
|
||||||
|
else if(Rn[1]==="/") switch(str.slice(pidx, Rn.index)) {
|
||||||
|
case "SheetHidden": wsprops.Hidden = 1; break;
|
||||||
|
case "SheetVeryHidden": wsprops.Hidden = 2; break;
|
||||||
|
}
|
||||||
|
else pidx = Rn.index + Rn[0].length;
|
||||||
|
break;
|
||||||
case 'Unsynced': break;
|
case 'Unsynced': break;
|
||||||
case 'Visible': break;
|
|
||||||
case 'Print': break;
|
case 'Print': break;
|
||||||
case 'Panes': break;
|
case 'Panes': break;
|
||||||
case 'Scale': break;
|
case 'Scale': break;
|
||||||
@ -740,6 +750,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
|||||||
var out = ({}/*:any*/);
|
var out = ({}/*:any*/);
|
||||||
if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
|
if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
|
||||||
out.SheetNames = sheetnames;
|
out.SheetNames = sheetnames;
|
||||||
|
out.Workbook = Workbook;
|
||||||
out.SSF = SSF.get_table();
|
out.SSF = SSF.get_table();
|
||||||
out.Props = Props;
|
out.Props = Props;
|
||||||
out.Custprops = Custprops;
|
out.Custprops = Custprops;
|
||||||
@ -776,6 +787,22 @@ function write_sty_xlml(wb, opts)/*:string*/ {
|
|||||||
/* Styles */
|
/* Styles */
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
/* WorksheetOptions */
|
||||||
|
function write_ws_xlml_wsopts(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
|
||||||
|
var o = [];
|
||||||
|
/* PageSetup */
|
||||||
|
if(wb && wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx]) {
|
||||||
|
/* Visible */
|
||||||
|
if(!!wb.Workbook.Sheets[idx].Hidden) o.push("<Visible>" + (wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden") + "</Visible>");
|
||||||
|
else {
|
||||||
|
/* Selected */
|
||||||
|
for(var i = 0; i < idx; ++i) if(wb.Workbook.Sheets[i] && !wb.Workbook.Sheets[i].Hidden) break;
|
||||||
|
if(i == idx) o.push("<Selected/>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(o.length == 0) return "";
|
||||||
|
return writextag("WorksheetOptions", o.join(""), {xmlns:XLMLNS.x});
|
||||||
|
}
|
||||||
/* TODO */
|
/* TODO */
|
||||||
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{
|
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{
|
||||||
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
||||||
@ -861,7 +888,10 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
|
|||||||
/* Table */
|
/* Table */
|
||||||
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||||
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
||||||
|
|
||||||
/* WorksheetOptions */
|
/* WorksheetOptions */
|
||||||
|
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
|
||||||
|
|
||||||
return o.join("");
|
return o.join("");
|
||||||
}
|
}
|
||||||
function write_xlml(wb, opts)/*:string*/ {
|
function write_xlml(wb, opts)/*:string*/ {
|
||||||
|
@ -98,6 +98,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
var cell_valid = true;
|
var cell_valid = true;
|
||||||
var XFs = []; /* XF records */
|
var XFs = []; /* XF records */
|
||||||
var palette = [];
|
var palette = [];
|
||||||
|
var Workbook = { Sheets:[] }, wsprops = {};
|
||||||
var get_rgb = function getrgb(icv) {
|
var get_rgb = function getrgb(icv) {
|
||||||
if(icv < 8) return XLSIcv[icv];
|
if(icv < 8) return XLSIcv[icv];
|
||||||
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
||||||
@ -269,6 +270,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if(objects.length > 0) out["!objects"] = objects;
|
if(objects.length > 0) out["!objects"] = objects;
|
||||||
if(colinfo.length > 0) out["!cols"] = colinfo;
|
if(colinfo.length > 0) out["!cols"] = colinfo;
|
||||||
if(rowinfo.length > 0) out["!rows"] = rowinfo;
|
if(rowinfo.length > 0) out["!rows"] = rowinfo;
|
||||||
|
Workbook.Sheets.push(wsprops);
|
||||||
}
|
}
|
||||||
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
|
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
|
||||||
out = {};
|
out = {};
|
||||||
@ -285,6 +287,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if(file_depth++) break;
|
if(file_depth++) break;
|
||||||
cell_valid = true;
|
cell_valid = true;
|
||||||
out = {};
|
out = {};
|
||||||
|
|
||||||
if(opts.biff < 5) {
|
if(opts.biff < 5) {
|
||||||
if(cur_sheet === "") cur_sheet = "Sheet1";
|
if(cur_sheet === "") cur_sheet = "Sheet1";
|
||||||
range = {s:{r:0,c:0},e:{r:0,c:0}};
|
range = {s:{r:0,c:0},e:{r:0,c:0}};
|
||||||
@ -301,6 +304,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
colinfo = []; rowinfo = [];
|
colinfo = []; rowinfo = [];
|
||||||
defwidth = defheight = 0;
|
defwidth = defheight = 0;
|
||||||
seencol = false;
|
seencol = false;
|
||||||
|
wsprops = {Hidden:(Directory[s]||{hs:0}).hs, name:cur_sheet };
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
|
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
|
||||||
@ -705,6 +709,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if(opts.enc) wb.Encryption = opts.enc;
|
if(opts.enc) wb.Encryption = opts.enc;
|
||||||
wb.Metadata = {};
|
wb.Metadata = {};
|
||||||
if(country !== undefined) wb.Metadata.Country = country;
|
if(country !== undefined) wb.Metadata.Country = country;
|
||||||
|
wb.Workbook = Workbook;
|
||||||
return wb;
|
return wb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,14 +114,15 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
|||||||
var i=0;
|
var i=0;
|
||||||
var sheetRels = ({}/*:any*/);
|
var sheetRels = ({}/*:any*/);
|
||||||
var path, relsPath;
|
var path, relsPath;
|
||||||
if(!props.Worksheets) {
|
|
||||||
|
//if(!props.Worksheets) {
|
||||||
var wbsheets = wb.Sheets;
|
var wbsheets = wb.Sheets;
|
||||||
props.Worksheets = wbsheets.length;
|
props.Worksheets = wbsheets.length;
|
||||||
props.SheetNames = [];
|
props.SheetNames = [];
|
||||||
for(var j = 0; j != wbsheets.length; ++j) {
|
for(var j = 0; j != wbsheets.length; ++j) {
|
||||||
props.SheetNames[j] = wbsheets[j].name;
|
props.SheetNames[j] = wbsheets[j].name;
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
|
|
||||||
var wbext = xlsb ? "bin" : "xml";
|
var wbext = xlsb ? "bin" : "xml";
|
||||||
var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
||||||
|
@ -33,8 +33,10 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
|
|
||||||
/*::if(!wb.Props) throw "unreachable"; */
|
/*::if(!wb.Props) throw "unreachable"; */
|
||||||
f = "docProps/app.xml";
|
f = "docProps/app.xml";
|
||||||
wb.Props.SheetNames = wb.SheetNames;
|
if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;
|
||||||
wb.Props.Worksheets = wb.SheetNames.length;
|
/*:: else if(!wb.Props) throw "unreachable"; */
|
||||||
|
else wb.Props.SheetNames = wb.Workbook.Sheets.filter(function(x) { return x.Hidden != 2; }).map(function(x) { return x.name; });
|
||||||
|
wb.Props.Worksheets = wb.Props.SheetNames.length;
|
||||||
zip.file(f, write_ext_props(wb.Props, opts));
|
zip.file(f, write_ext_props(wb.Props, opts));
|
||||||
ct.extprops.push(f);
|
ct.extprops.push(f);
|
||||||
add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
|
add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
|
||||||
|
31
docbits/73_sheetprops.md
Normal file
31
docbits/73_sheetprops.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#### Sheet Visibility
|
||||||
|
|
||||||
|
Excel enables hiding sheets in the lower tab bar. The sheet data is stored in
|
||||||
|
the file but the UI does not readily make it available. Standard hidden sheets
|
||||||
|
are revealed in the unhide menu. Excel also has "very hidden" sheets which
|
||||||
|
cannot be revealed in the menu. It is only accessible in the VB Editor!
|
||||||
|
|
||||||
|
The visibility setting is stored in the `Hidden` property of the sheet props
|
||||||
|
array. The values are:
|
||||||
|
|
||||||
|
| Value | Definition |
|
||||||
|
|:-----:|:------------|
|
||||||
|
| 0 | Visible |
|
||||||
|
| 1 | Hidden |
|
||||||
|
| 2 | Very Hidden |
|
||||||
|
|
||||||
|
With <https://rawgit.com/SheetJS/test_files/master/sheet_visibility.xlsx>:
|
||||||
|
|
||||||
|
```js
|
||||||
|
> wb.Workbook.Sheets.map(function(x) { return [x.name, x.Hidden] })
|
||||||
|
[ [ 'Visible', 0 ], [ 'Hidden', 1 ], [ 'VeryHidden', 2 ] ]
|
||||||
|
```
|
||||||
|
|
||||||
|
Non-Excel formats do not support the Very Hidden state. The best way to test
|
||||||
|
if a sheet is visible is to check if the `Hidden` property is logical negation:
|
||||||
|
|
||||||
|
```js
|
||||||
|
> wb.Workbook.Sheets.map(function(x) { return [x.name, !x.Hidden] })
|
||||||
|
[ [ 'Visible', true ], [ 'Hidden', false ], [ 'VeryHidden', false ] ]
|
||||||
|
```
|
||||||
|
|
@ -24,6 +24,7 @@
|
|||||||
+ [Formulae](README.md#formulae)
|
+ [Formulae](README.md#formulae)
|
||||||
+ [Column Properties](README.md#column-properties)
|
+ [Column Properties](README.md#column-properties)
|
||||||
+ [Hyperlinks](README.md#hyperlinks)
|
+ [Hyperlinks](README.md#hyperlinks)
|
||||||
|
+ [Sheet Visibility](README.md#sheet-visibility)
|
||||||
- [Parsing Options](README.md#parsing-options)
|
- [Parsing Options](README.md#parsing-options)
|
||||||
* [Input Type](README.md#input-type)
|
* [Input Type](README.md#input-type)
|
||||||
* [Guessing File Type](README.md#guessing-file-type)
|
* [Guessing File Type](README.md#guessing-file-type)
|
||||||
|
15
misc/flow.js
15
misc/flow.js
@ -17,10 +17,25 @@ type Workbook = {
|
|||||||
Custprops?: any;
|
Custprops?: any;
|
||||||
Themes?: any;
|
Themes?: any;
|
||||||
|
|
||||||
|
Workbook?: WBWBProps;
|
||||||
|
|
||||||
SSF?: {[n:number]:string};
|
SSF?: {[n:number]:string};
|
||||||
cfb?: any;
|
cfb?: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type WorkbookProps = {
|
||||||
|
SheetNames?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
type WBWBProps = {
|
||||||
|
Sheets: Array<WBWSProp>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type WBWSProp = {
|
||||||
|
Hidden?: number;
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface CellAddress {
|
interface CellAddress {
|
||||||
r:number;
|
r:number;
|
||||||
c:number;
|
c:number;
|
||||||
|
84
test.js
84
test.js
@ -73,6 +73,11 @@ var paths = {
|
|||||||
cwxml: dir + 'column_width.xml',
|
cwxml: dir + 'column_width.xml',
|
||||||
cwxlsx: dir + 'column_width.xlsx',
|
cwxlsx: dir + 'column_width.xlsx',
|
||||||
cwxlsb: dir + 'column_width.xlsx',
|
cwxlsb: dir + 'column_width.xlsx',
|
||||||
|
svxls: dir + 'sheet_visibility.xls',
|
||||||
|
svxls5: dir + 'sheet_visibility.xls',
|
||||||
|
svxml: dir + 'sheet_visibility.xml',
|
||||||
|
svxlsx: dir + 'sheet_visibility.xlsx',
|
||||||
|
svxlsb: dir + 'sheet_visibility.xlsb',
|
||||||
swcxls: dir + 'apachepoi_SimpleWithComments.xls',
|
swcxls: dir + 'apachepoi_SimpleWithComments.xls',
|
||||||
swcxml: dir + '2011/apachepoi_SimpleWithComments.xls.xml',
|
swcxml: dir + '2011/apachepoi_SimpleWithComments.xls.xml',
|
||||||
swcxlsx: dir + 'apachepoi_SimpleWithComments.xlsx',
|
swcxlsx: dir + 'apachepoi_SimpleWithComments.xlsx',
|
||||||
@ -616,21 +621,54 @@ function hlink(wb) {
|
|||||||
|
|
||||||
|
|
||||||
describe('parse features', function() {
|
describe('parse features', function() {
|
||||||
if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){
|
describe('sheet visibility', function() {
|
||||||
var X = require(modp);
|
var wb1, wb2, wb3, wb4, wb5;
|
||||||
var sheet = 'Sheet1';
|
var bef = (function() {
|
||||||
var wb1=X.readFile(paths.swcxlsx);
|
wb1 = X.readFile(paths.svxls);
|
||||||
var wb2=X.readFile(paths.swcxlsb);
|
wb2 = X.readFile(paths.svxls5);
|
||||||
var wb3=X.readFile(paths.swcxls);
|
wb3 = X.readFile(paths.svxml);
|
||||||
var wb4=X.readFile(paths.swcxml);
|
wb4 = X.readFile(paths.svxlsx);
|
||||||
|
wb5 = X.readFile(paths.svxlsb);
|
||||||
|
});
|
||||||
|
if(typeof before != 'undefined') before(bef);
|
||||||
|
else it('before', bef);
|
||||||
|
|
||||||
[wb1,wb2,wb3,wb4].map(function(wb) { return wb.Sheets[sheet]; }).forEach(function(ws, i) {
|
it('should detect visible sheets', function() {
|
||||||
assert.equal(ws.B1.c.length, 1,"must have 1 comment");
|
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||||
assert.equal(ws.B1.c[0].a, "Yegor Kozlov","must have the same author");
|
assert(!wb.Workbook.Sheets[0].Hidden);
|
||||||
assert.equal(ws.B1.c[0].t.replace(/\r\n/g,"\n").replace(/\r/g,"\n"), "Yegor Kozlov:\nfirst cell", "must have the concatenated texts");
|
});
|
||||||
if(i > 0) return;
|
});
|
||||||
assert.equal(ws.B1.c[0].r, '<r><rPr><b/><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t>Yegor Kozlov:</t></r><r><rPr><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t xml:space="preserve">\r\nfirst cell</t></r>', "must have the rich text representation");
|
it('should detect all hidden sheets', function() {
|
||||||
assert.equal(ws.B1.c[0].h, '<span style="font-weight: bold;">Yegor Kozlov:</span><span style=""><br/>first cell</span>', "must have the html representation");
|
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||||
|
assert(wb.Workbook.Sheets[1].Hidden);
|
||||||
|
assert(wb.Workbook.Sheets[2].Hidden);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should distinguish very hidden sheets', function() {
|
||||||
|
[wb1, wb2, wb3, wb4, wb5].forEach(function(wb) {
|
||||||
|
assert.equal(wb.Workbook.Sheets[1].Hidden,1);
|
||||||
|
assert.equal(wb.Workbook.Sheets[2].Hidden,2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('comments', function() {
|
||||||
|
if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){
|
||||||
|
var X = require(modp);
|
||||||
|
var sheet = 'Sheet1';
|
||||||
|
var wb1=X.readFile(paths.swcxlsx);
|
||||||
|
var wb2=X.readFile(paths.swcxlsb);
|
||||||
|
var wb3=X.readFile(paths.swcxls);
|
||||||
|
var wb4=X.readFile(paths.swcxml);
|
||||||
|
|
||||||
|
[wb1,wb2,wb3,wb4].map(function(wb) { return wb.Sheets[sheet]; }).forEach(function(ws, i) {
|
||||||
|
assert.equal(ws.B1.c.length, 1,"must have 1 comment");
|
||||||
|
assert.equal(ws.B1.c[0].a, "Yegor Kozlov","must have the same author");
|
||||||
|
assert.equal(ws.B1.c[0].t.replace(/\r\n/g,"\n").replace(/\r/g,"\n"), "Yegor Kozlov:\nfirst cell", "must have the concatenated texts");
|
||||||
|
if(i > 0) return;
|
||||||
|
assert.equal(ws.B1.c[0].r, '<r><rPr><b/><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t>Yegor Kozlov:</t></r><r><rPr><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t xml:space="preserve">\r\nfirst cell</t></r>', "must have the rich text representation");
|
||||||
|
assert.equal(ws.B1.c[0].h, '<span style="font-weight: bold;">Yegor Kozlov:</span><span style=""><br/>first cell</span>', "must have the html representation");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1000,6 +1038,24 @@ describe('roundtrip features', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('should preserve sheet visibility', function() { [
|
||||||
|
['xlml', paths.svxml],
|
||||||
|
['xlsx', paths.svxlsx],
|
||||||
|
['xlsb', paths.svxlsb]
|
||||||
|
].forEach(function(w) {
|
||||||
|
it(w[0], function() {
|
||||||
|
var wb1 = X.readFile(w[1]);
|
||||||
|
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"buffer"}), {type:"buffer"});
|
||||||
|
var wbs1 = wb1.Workbook.Sheets;
|
||||||
|
var wbs2 = wb2.Workbook.Sheets;
|
||||||
|
assert.equal(wbs1.length, wbs2.length);
|
||||||
|
for(var i = 0; i < wbs1.length; ++i) {
|
||||||
|
assert.equal(wbs1[i].name, wbs2[i].name);
|
||||||
|
assert.equal(wbs1[i].Hidden, wbs2[i].Hidden);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function password_file(x){return x.match(/^password.*\.xls$/); }
|
function password_file(x){return x.match(/^password.*\.xls$/); }
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit cbafd3a184d0c668aaae1f9f8420ccaed74ad8e5
|
Subproject commit 7926b8cd03370487edfa9476cad10b532ef22e99
|
19
tests.lst
19
tests.lst
@ -34,6 +34,7 @@ pivot_table_named_range.xlsb
|
|||||||
pivot_table_test.xlsb
|
pivot_table_test.xlsb
|
||||||
rich_text_stress.xlsb
|
rich_text_stress.xlsb
|
||||||
row_height.xlsb
|
row_height.xlsb
|
||||||
|
sheet_visibility.xlsb
|
||||||
sized_boxen.xlsb
|
sized_boxen.xlsb
|
||||||
smart_tags_2007.xlsb
|
smart_tags_2007.xlsb
|
||||||
sushi.xlsb
|
sushi.xlsb
|
||||||
@ -199,7 +200,6 @@ apachepoi_DataTableCities.xlsx
|
|||||||
apachepoi_DataValidationEvaluations.xlsx
|
apachepoi_DataValidationEvaluations.xlsx
|
||||||
apachepoi_DataValidations-49244.xlsx
|
apachepoi_DataValidations-49244.xlsx
|
||||||
# apachepoi_DateFormatTests.xlsx # xlml
|
# apachepoi_DateFormatTests.xlsx # xlml
|
||||||
apachepoi_DateFormatTests.xlsx.xlsx
|
|
||||||
apachepoi_ElapsedFormatTests.xlsx
|
apachepoi_ElapsedFormatTests.xlsx
|
||||||
apachepoi_ExcelTables.xlsx
|
apachepoi_ExcelTables.xlsx
|
||||||
apachepoi_ForShifting.xlsx
|
apachepoi_ForShifting.xlsx
|
||||||
@ -288,6 +288,7 @@ apachepoi_workbookProtection_worksheet_protected.xlsx
|
|||||||
apachepoi_xlsx-jdbc.xlsx
|
apachepoi_xlsx-jdbc.xlsx
|
||||||
calendar_stress_test.xlsx.pending
|
calendar_stress_test.xlsx.pending
|
||||||
cell_style_simple.xlsx
|
cell_style_simple.xlsx
|
||||||
|
column_width.xlsx
|
||||||
comments_stress_test.xlsx
|
comments_stress_test.xlsx
|
||||||
custom_properties.xlsx
|
custom_properties.xlsx
|
||||||
defined_names_simple.xlsx
|
defined_names_simple.xlsx
|
||||||
@ -407,6 +408,10 @@ roo_time-test.xlsx
|
|||||||
roo_whitespace.xlsx
|
roo_whitespace.xlsx
|
||||||
roo_x000D.xlsx
|
roo_x000D.xlsx
|
||||||
roo_zero-padded-number.xlsx
|
roo_zero-padded-number.xlsx
|
||||||
|
row_height.xlsx
|
||||||
|
sheet_visibility.xlsx
|
||||||
|
sheet_visibility_strict.xlsx
|
||||||
|
sized_boxen.xlsx
|
||||||
smart_tags_2007.xlsx
|
smart_tags_2007.xlsx
|
||||||
spout-xlsx_attack_billion_laughs.xlsx
|
spout-xlsx_attack_billion_laughs.xlsx
|
||||||
spout-xlsx_attack_quadratic_blowup.xlsx
|
spout-xlsx_attack_quadratic_blowup.xlsx
|
||||||
@ -578,6 +583,7 @@ roo_time-test.ods
|
|||||||
roo_type_excel.ods
|
roo_type_excel.ods
|
||||||
roo_type_excelx.ods
|
roo_type_excelx.ods
|
||||||
roo_whitespace.ods
|
roo_whitespace.ods
|
||||||
|
sheet_visibility.ods
|
||||||
spout-ods_attack_billion_laughs.ods
|
spout-ods_attack_billion_laughs.ods
|
||||||
spout-ods_attack_quadratic_blowup.ods
|
spout-ods_attack_quadratic_blowup.ods
|
||||||
# spout-ods_file_corrupted.ods
|
# spout-ods_file_corrupted.ods
|
||||||
@ -1001,6 +1007,7 @@ apachepoi_xor-encryption-abc.xls.pending
|
|||||||
# apachepoi_yearfracExamples.xls # xlml
|
# apachepoi_yearfracExamples.xls # xlml
|
||||||
calendar_stress_test.xls.pending
|
calendar_stress_test.xls.pending
|
||||||
cell_style_simple.xls
|
cell_style_simple.xls
|
||||||
|
column_width.xls
|
||||||
comments_stress_test.xls
|
comments_stress_test.xls
|
||||||
custom_properties.xls
|
custom_properties.xls
|
||||||
defined_names_simple.xls
|
defined_names_simple.xls
|
||||||
@ -1233,6 +1240,10 @@ roo_time-test.xls
|
|||||||
roo_type_excelx.xls
|
roo_type_excelx.xls
|
||||||
# roo_type_openoffice.xls # incorrect baseline
|
# roo_type_openoffice.xls # incorrect baseline
|
||||||
roo_whitespace.xls
|
roo_whitespace.xls
|
||||||
|
row_height.xls
|
||||||
|
sheet_visibility.xls
|
||||||
|
sheet_visibility5.xls
|
||||||
|
sized_boxen.xls
|
||||||
smart_tags_2007.xls
|
smart_tags_2007.xls
|
||||||
sushi.xls
|
sushi.xls
|
||||||
text_and_numbers.xls
|
text_and_numbers.xls
|
||||||
@ -1261,6 +1272,7 @@ RkNumber.xlsx.xml
|
|||||||
apachepoi_SampleSS.xml
|
apachepoi_SampleSS.xml
|
||||||
calendar_stress_test.xml.pending
|
calendar_stress_test.xml.pending
|
||||||
cell_style_simple.xml
|
cell_style_simple.xml
|
||||||
|
column_width.xml
|
||||||
comments_stress_test.xls.xml
|
comments_stress_test.xls.xml
|
||||||
comments_stress_test.xlsb.xml
|
comments_stress_test.xlsb.xml
|
||||||
comments_stress_test.xlsx.xml
|
comments_stress_test.xlsx.xml
|
||||||
@ -1327,12 +1339,15 @@ roo_formula_parse_error.xml
|
|||||||
# roo_numbers1.xml # SSF TODO
|
# roo_numbers1.xml # SSF TODO
|
||||||
roo_only_one_sheet.xml
|
roo_only_one_sheet.xml
|
||||||
roo_paragraph.xml
|
roo_paragraph.xml
|
||||||
|
# roo_sheet1.xml
|
||||||
# roo_simple_spreadsheet.xml # SSF TODO
|
# roo_simple_spreadsheet.xml # SSF TODO
|
||||||
# roo_simple_spreadsheet_from_italo.xml # SSF TODO
|
# roo_simple_spreadsheet_from_italo.xml # SSF TODO
|
||||||
roo_style.xml
|
roo_style.xml
|
||||||
# roo_time-test.xml # SSF TODO
|
# roo_time-test.xml # SSF TODO
|
||||||
# roo_whitespace.xml # SSF TODO
|
# roo_whitespace.xml # SSF TODO
|
||||||
# roo_sheet1.xml
|
row_height.xml
|
||||||
|
sheet_visibility.xml
|
||||||
|
sized_boxen.xml
|
||||||
smart_tags_2007.xml
|
smart_tags_2007.xml
|
||||||
sushi.xml
|
sushi.xml
|
||||||
text_and_numbers.xml
|
text_and_numbers.xml
|
||||||
|
@ -63,6 +63,11 @@ var paths = {
|
|||||||
cwxml: dir + 'column_width.xml',
|
cwxml: dir + 'column_width.xml',
|
||||||
cwxlsx: dir + 'column_width.xlsx',
|
cwxlsx: dir + 'column_width.xlsx',
|
||||||
cwxlsb: dir + 'column_width.xlsx',
|
cwxlsb: dir + 'column_width.xlsx',
|
||||||
|
svxls: dir + 'sheet_visibility.xls',
|
||||||
|
svxls5: dir + 'sheet_visibility.xls',
|
||||||
|
svxml: dir + 'sheet_visibility.xml',
|
||||||
|
svxlsx: dir + 'sheet_visibility.xlsx',
|
||||||
|
svxlsb: dir + 'sheet_visibility.xlsb',
|
||||||
swcxls: dir + 'apachepoi_SimpleWithComments.xls',
|
swcxls: dir + 'apachepoi_SimpleWithComments.xls',
|
||||||
swcxml: dir + '2011/apachepoi_SimpleWithComments.xls.xml',
|
swcxml: dir + '2011/apachepoi_SimpleWithComments.xls.xml',
|
||||||
swcxlsx: dir + 'apachepoi_SimpleWithComments.xlsx',
|
swcxlsx: dir + 'apachepoi_SimpleWithComments.xlsx',
|
||||||
@ -458,21 +463,54 @@ function hlink(wb) {
|
|||||||
|
|
||||||
|
|
||||||
describe('parse features', function() {
|
describe('parse features', function() {
|
||||||
if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){
|
describe('sheet visibility', function() {
|
||||||
var X = require(modp);
|
var wb1, wb2, wb3, wb4, wb5;
|
||||||
var sheet = 'Sheet1';
|
var bef = (function() {
|
||||||
var wb1=X.read(fs.readFileSync(paths.swcxlsx), {type:"binary"});
|
wb1 = X.read(fs.readFileSync(paths.svxls), {type:"binary"});
|
||||||
var wb2=X.read(fs.readFileSync(paths.swcxlsb), {type:"binary"});
|
wb2 = X.read(fs.readFileSync(paths.svxls5), {type:"binary"});
|
||||||
var wb3=X.read(fs.readFileSync(paths.swcxls), {type:"binary"});
|
wb3 = X.read(fs.readFileSync(paths.svxml), {type:"binary"});
|
||||||
var wb4=X.read(fs.readFileSync(paths.swcxml), {type:"binary"});
|
wb4 = X.read(fs.readFileSync(paths.svxlsx), {type:"binary"});
|
||||||
|
wb5 = X.read(fs.readFileSync(paths.svxlsb), {type:"binary"});
|
||||||
|
});
|
||||||
|
if(typeof before != 'undefined') before(bef);
|
||||||
|
else it('before', bef);
|
||||||
|
|
||||||
[wb1,wb2,wb3,wb4].map(function(wb) { return wb.Sheets[sheet]; }).forEach(function(ws, i) {
|
it('should detect visible sheets', function() {
|
||||||
assert.equal(ws.B1.c.length, 1,"must have 1 comment");
|
[/*wb1, wb2, wb3, wb4,*/ wb5].forEach(function(wb) {
|
||||||
assert.equal(ws.B1.c[0].a, "Yegor Kozlov","must have the same author");
|
assert(!wb.Workbook.Sheets[0].Hidden);
|
||||||
assert.equal(ws.B1.c[0].t.replace(/\r\n/g,"\n").replace(/\r/g,"\n"), "Yegor Kozlov:\nfirst cell", "must have the concatenated texts");
|
});
|
||||||
if(i > 0) return;
|
});
|
||||||
assert.equal(ws.B1.c[0].r, '<r><rPr><b/><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t>Yegor Kozlov:</t></r><r><rPr><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t xml:space="preserve">\r\nfirst cell</t></r>', "must have the rich text representation");
|
it('should detect all hidden sheets', function() {
|
||||||
assert.equal(ws.B1.c[0].h, '<span style="font-weight: bold;">Yegor Kozlov:</span><span style=""><br/>first cell</span>', "must have the html representation");
|
[/*wb1, wb2, wb3, wb4,*/ wb5].forEach(function(wb) {
|
||||||
|
assert(wb.Workbook.Sheets[1].Hidden);
|
||||||
|
assert(wb.Workbook.Sheets[2].Hidden);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should distinguish very hidden sheets', function() {
|
||||||
|
[/*wb1, wb2, wb3, wb4,*/ wb5].forEach(function(wb) {
|
||||||
|
assert.equal(wb.Workbook.Sheets[1].Hidden,1);
|
||||||
|
assert.equal(wb.Workbook.Sheets[2].Hidden,2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('comments', function() {
|
||||||
|
if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){
|
||||||
|
var X = require(modp);
|
||||||
|
var sheet = 'Sheet1';
|
||||||
|
var wb1=X.read(fs.readFileSync(paths.swcxlsx), {type:"binary"});
|
||||||
|
var wb2=X.read(fs.readFileSync(paths.swcxlsb), {type:"binary"});
|
||||||
|
var wb3=X.read(fs.readFileSync(paths.swcxls), {type:"binary"});
|
||||||
|
var wb4=X.read(fs.readFileSync(paths.swcxml), {type:"binary"});
|
||||||
|
|
||||||
|
[wb1,wb2,wb3,wb4].map(function(wb) { return wb.Sheets[sheet]; }).forEach(function(ws, i) {
|
||||||
|
assert.equal(ws.B1.c.length, 1,"must have 1 comment");
|
||||||
|
assert.equal(ws.B1.c[0].a, "Yegor Kozlov","must have the same author");
|
||||||
|
assert.equal(ws.B1.c[0].t.replace(/\r\n/g,"\n").replace(/\r/g,"\n"), "Yegor Kozlov:\nfirst cell", "must have the concatenated texts");
|
||||||
|
if(i > 0) return;
|
||||||
|
assert.equal(ws.B1.c[0].r, '<r><rPr><b/><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t>Yegor Kozlov:</t></r><r><rPr><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t xml:space="preserve">\r\nfirst cell</t></r>', "must have the rich text representation");
|
||||||
|
assert.equal(ws.B1.c[0].h, '<span style="font-weight: bold;">Yegor Kozlov:</span><span style=""><br/>first cell</span>', "must have the html representation");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -841,6 +879,24 @@ describe('roundtrip features', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('should preserve sheet visibility', function() { [
|
||||||
|
['xlml', paths.svxml],
|
||||||
|
['xlsx', paths.svxlsx],
|
||||||
|
['xlsb', paths.svxlsb]
|
||||||
|
].forEach(function(w) {
|
||||||
|
it(w[0], function() {
|
||||||
|
var wb1 = X.read(fs.readFileSync(w[1]), {type:"binary"});
|
||||||
|
var wb2 = X.read(X.write(wb1, {bookType:w[0], type:"binary"}), {type:"binary"});
|
||||||
|
var wbs1 = wb1.Workbook.Sheets;
|
||||||
|
var wbs2 = wb2.Workbook.Sheets;
|
||||||
|
assert.equal(wbs1.length, wbs2.length);
|
||||||
|
for(var i = 0; i < wbs1.length; ++i) {
|
||||||
|
assert.equal(wbs1[i].name, wbs2[i].name);
|
||||||
|
assert.equal(wbs1[i].Hidden, wbs2[i].Hidden);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function password_file(x){return x.match(/^password.*\.xls$/); }
|
function password_file(x){return x.match(/^password.*\.xls$/); }
|
||||||
|
File diff suppressed because one or more lines are too long
@ -39,6 +39,11 @@
|
|||||||
./test_files/column_width.xml
|
./test_files/column_width.xml
|
||||||
./test_files/column_width.xlsx
|
./test_files/column_width.xlsx
|
||||||
./test_files/column_width.xlsx
|
./test_files/column_width.xlsx
|
||||||
|
./test_files/sheet_visibility.xls
|
||||||
|
./test_files/sheet_visibility.xls
|
||||||
|
./test_files/sheet_visibility.xml
|
||||||
|
./test_files/sheet_visibility.xlsx
|
||||||
|
./test_files/sheet_visibility.xlsb
|
||||||
./test_files/apachepoi_SimpleWithComments.xls
|
./test_files/apachepoi_SimpleWithComments.xls
|
||||||
./test_files/2011/apachepoi_SimpleWithComments.xls.xml
|
./test_files/2011/apachepoi_SimpleWithComments.xls.xml
|
||||||
./test_files/apachepoi_SimpleWithComments.xlsx
|
./test_files/apachepoi_SimpleWithComments.xlsx
|
||||||
|
@ -80,6 +80,13 @@ console.log("JSON Data: "); console.log(XLSX.utils.sheet_to_json(ws, {header:1})
|
|||||||
console.log("Worksheet Model:")
|
console.log("Worksheet Model:")
|
||||||
console.log(ws);
|
console.log(ws);
|
||||||
|
|
||||||
|
/* TEST: hidden sheets */
|
||||||
|
|
||||||
|
wb.SheetNames.push("Hidden");
|
||||||
|
wb.Sheets["Hidden"] = XLSX.utils.aoa_to_sheet(["Hidden".split(""), [1,2,3]]);
|
||||||
|
wb.Workbook = {Sheets:[]};
|
||||||
|
wb.Workbook.Sheets[1] = {Hidden:1};
|
||||||
|
|
||||||
/* write file */
|
/* write file */
|
||||||
XLSX.writeFile(wb, 'sheetjs.xlsx', {bookSST:true});
|
XLSX.writeFile(wb, 'sheetjs.xlsx', {bookSST:true});
|
||||||
XLSX.writeFile(wb, 'sheetjs.xlsm');
|
XLSX.writeFile(wb, 'sheetjs.xlsm');
|
||||||
|
115
xlsx.flow.js
115
xlsx.flow.js
@ -1915,6 +1915,7 @@ function prep_blob(blob, pos/*:number*/) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parsenoop(blob, length/*:number*/) { blob.l += length; }
|
function parsenoop(blob, length/*:number*/) { blob.l += length; }
|
||||||
|
function parsenooplog(blob, length/*:number*/) { if(typeof console != 'undefined') console.log(blob.slice(blob.l, blob.l + length)); blob.l += length; }
|
||||||
|
|
||||||
function writenoop(blob, length/*:number*/) { blob.l += length; }
|
function writenoop(blob, length/*:number*/) { blob.l += length; }
|
||||||
|
|
||||||
@ -3070,8 +3071,8 @@ function parse_ext_props(data, p) {
|
|||||||
var v = parseVector(q.HeadingPairs);
|
var v = parseVector(q.HeadingPairs);
|
||||||
var parts = parseVector(q.TitlesOfParts).map(function(x) { return x.v; });
|
var parts = parseVector(q.TitlesOfParts).map(function(x) { return x.v; });
|
||||||
var idx = 0, len = 0;
|
var idx = 0, len = 0;
|
||||||
for(var i = 0; i !== v.length; ++i) {
|
for(var i = 0; i !== v.length; i+=2) {
|
||||||
len = +(v[++i].v);
|
len = +(v[i+1].v);
|
||||||
switch(v[i].v) {
|
switch(v[i].v) {
|
||||||
case "Worksheets":
|
case "Worksheets":
|
||||||
case "工作表":
|
case "工作表":
|
||||||
@ -3104,6 +3105,7 @@ function parse_ext_props(data, p) {
|
|||||||
idx += len;
|
idx += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9208,7 +9210,7 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
|||||||
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
|
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
|
||||||
}
|
}
|
||||||
if(r.length > 0) {
|
if(r.length > 0) {
|
||||||
var params = {r:rr}
|
var params = ({r:rr}/*:any*/);
|
||||||
if(rows && rows[R]) {
|
if(rows && rows[R]) {
|
||||||
var row = rows[R];
|
var row = rows[R];
|
||||||
if(row.hidden) params.hidden = 1;
|
if(row.hidden) params.hidden = 1;
|
||||||
@ -10086,7 +10088,7 @@ var WBViewDef = [
|
|||||||
|
|
||||||
/* 18.2.19 (CT_Sheet) Defaults */
|
/* 18.2.19 (CT_Sheet) Defaults */
|
||||||
var SheetDef = [
|
var SheetDef = [
|
||||||
['state', 'visible']
|
//['state', 'visible']
|
||||||
];
|
];
|
||||||
|
|
||||||
/* 18.2.2 (CT_CalcPr) Defaults */
|
/* 18.2.2 (CT_CalcPr) Defaults */
|
||||||
@ -10199,7 +10201,15 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
|
|||||||
/* 18.2.20 sheets CT_Sheets 1 */
|
/* 18.2.20 sheets CT_Sheets 1 */
|
||||||
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
||||||
/* 18.2.19 sheet CT_Sheet + */
|
/* 18.2.19 sheet CT_Sheet + */
|
||||||
case '<sheet': delete y[0]; y.name = unescapexml(utf8read(y.name)); wb.Sheets.push(y); break;
|
case '<sheet':
|
||||||
|
switch(y.state) {
|
||||||
|
case "hidden": y.Hidden = 1; break;
|
||||||
|
case "veryHidden": y.Hidden = 2; break;
|
||||||
|
default: y.Hidden = 0;
|
||||||
|
}
|
||||||
|
delete y.state;
|
||||||
|
y.name = unescapexml(utf8read(y.name));
|
||||||
|
delete y[0]; wb.Sheets.push(y); break;
|
||||||
case '</sheet>': break;
|
case '</sheet>': break;
|
||||||
|
|
||||||
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
||||||
@ -10309,8 +10319,17 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
|
|||||||
o[o.length] = WB_XML_ROOT;
|
o[o.length] = WB_XML_ROOT;
|
||||||
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb), codeName:"ThisWorkbook"}));
|
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb), codeName:"ThisWorkbook"}));
|
||||||
o[o.length] = "<sheets>";
|
o[o.length] = "<sheets>";
|
||||||
for(var i = 0; i != wb.SheetNames.length; ++i)
|
var sheets = wb.Workbook && wb.Workbook.Sheets || [];
|
||||||
o[o.length] = (writextag('sheet',null,{name:escapexml(wb.SheetNames[i].substr(0,31)), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
for(var i = 0; i != wb.SheetNames.length; ++i) {
|
||||||
|
var sht = ({name:escapexml(wb.SheetNames[i].substr(0,31))}/*:any*/);
|
||||||
|
sht.sheetId = ""+(i+1);
|
||||||
|
sht["r:id"] = "rId"+(i+1);
|
||||||
|
if(sheets[i]) switch(sheets[i].Hidden) {
|
||||||
|
case 1: sht.state = "hidden"; break;
|
||||||
|
case 2: sht.state = "veryHidden"; break;
|
||||||
|
}
|
||||||
|
o[o.length] = (writextag('sheet',null,sht));
|
||||||
|
}
|
||||||
o[o.length] = "</sheets>";
|
o[o.length] = "</sheets>";
|
||||||
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
||||||
return o.join("");
|
return o.join("");
|
||||||
@ -10318,7 +10337,7 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
|
|||||||
/* [MS-XLSB] 2.4.301 BrtBundleSh */
|
/* [MS-XLSB] 2.4.301 BrtBundleSh */
|
||||||
function parse_BrtBundleSh(data, length/*:number*/) {
|
function parse_BrtBundleSh(data, length/*:number*/) {
|
||||||
var z = {};
|
var z = {};
|
||||||
z.hsState = data.read_shift(4); //ST_SheetState
|
z.Hidden = data.read_shift(4); //hsState ST_SheetState
|
||||||
z.iTabID = data.read_shift(4);
|
z.iTabID = data.read_shift(4);
|
||||||
z.strRelID = parse_RelID(data,length-8);
|
z.strRelID = parse_RelID(data,length-8);
|
||||||
z.name = parse_XLWideString(data);
|
z.name = parse_XLWideString(data);
|
||||||
@ -10326,7 +10345,7 @@ function parse_BrtBundleSh(data, length/*:number*/) {
|
|||||||
}
|
}
|
||||||
function write_BrtBundleSh(data, o) {
|
function write_BrtBundleSh(data, o) {
|
||||||
if(!o) o = new_buf(127);
|
if(!o) o = new_buf(127);
|
||||||
o.write_shift(4, data.hsState);
|
o.write_shift(4, data.Hidden);
|
||||||
o.write_shift(4, data.iTabID);
|
o.write_shift(4, data.iTabID);
|
||||||
write_RelID(data.strRelID, o);
|
write_RelID(data.strRelID, o);
|
||||||
write_XLWideString(data.name.substr(0,31), o);
|
write_XLWideString(data.name.substr(0,31), o);
|
||||||
@ -10455,7 +10474,8 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
|
|||||||
function write_BUNDLESHS(ba, wb, opts) {
|
function write_BUNDLESHS(ba, wb, opts) {
|
||||||
write_record(ba, "BrtBeginBundleShs");
|
write_record(ba, "BrtBeginBundleShs");
|
||||||
for(var idx = 0; idx != wb.SheetNames.length; ++idx) {
|
for(var idx = 0; idx != wb.SheetNames.length; ++idx) {
|
||||||
var d = { hsState: 0, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] };
|
var viz = wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx] && wb.Workbook.Sheets[idx].Hidden || 0;
|
||||||
|
var d = { Hidden: viz, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] };
|
||||||
write_record(ba, "BrtBundleSh", write_BrtBundleSh(d));
|
write_record(ba, "BrtBundleSh", write_BrtBundleSh(d));
|
||||||
}
|
}
|
||||||
write_record(ba, "BrtEndBundleShs");
|
write_record(ba, "BrtEndBundleShs");
|
||||||
@ -10473,9 +10493,34 @@ function write_BrtFileVersion(data, o) {
|
|||||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.298 BrtBookView */
|
||||||
|
function write_BrtBookView(idx, o) {
|
||||||
|
if(!o) o = new_buf(29);
|
||||||
|
o.write_shift(-4, 0);
|
||||||
|
o.write_shift(-4, 460);
|
||||||
|
o.write_shift(4, 28800);
|
||||||
|
o.write_shift(4, 17600);
|
||||||
|
o.write_shift(4, 500);
|
||||||
|
o.write_shift(4, idx);
|
||||||
|
o.write_shift(4, idx);
|
||||||
|
var flags = 0x78;
|
||||||
|
o.write_shift(1, flags);
|
||||||
|
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||||
|
}
|
||||||
|
|
||||||
/* [MS-XLSB] 2.1.7.60 Workbook */
|
/* [MS-XLSB] 2.1.7.60 Workbook */
|
||||||
function write_BOOKVIEWS(ba, wb, opts) {
|
function write_BOOKVIEWS(ba, wb, opts) {
|
||||||
|
/* required if hidden tab appears before visible tab */
|
||||||
|
if(!wb.Workbook || !wb.Workbook.Sheets) return;
|
||||||
|
var sheets = wb.Workbook.Sheets;
|
||||||
|
var i = 0, vistab = -1, hidden = -1;
|
||||||
|
for(; i < sheets.length; ++i) {
|
||||||
|
if(!sheets[i] || !sheets[i].Hidden && vistab == -1) vistab = i;
|
||||||
|
else if(sheets[i].Hidden == 1 && hidden == -1) hidden = i;
|
||||||
|
}
|
||||||
|
if(hidden > vistab) return;
|
||||||
write_record(ba, "BrtBeginBookViews");
|
write_record(ba, "BrtBeginBookViews");
|
||||||
|
write_record(ba, "BrtBookView", write_BrtBookView(vistab));
|
||||||
/* 1*(BrtBookView *FRT) */
|
/* 1*(BrtBookView *FRT) */
|
||||||
write_record(ba, "BrtEndBookViews");
|
write_record(ba, "BrtEndBookViews");
|
||||||
}
|
}
|
||||||
@ -10509,7 +10554,7 @@ function write_wb_bin(wb, opts) {
|
|||||||
write_record(ba, "BrtWbProp", write_BrtWbProp());
|
write_record(ba, "BrtWbProp", write_BrtWbProp());
|
||||||
/* [ACABSPATH] */
|
/* [ACABSPATH] */
|
||||||
/* [[BrtBookProtectionIso] BrtBookProtection] */
|
/* [[BrtBookProtectionIso] BrtBookProtection] */
|
||||||
/* write_BOOKVIEWS(ba, wb, opts); */
|
write_BOOKVIEWS(ba, wb, opts);
|
||||||
write_BUNDLESHS(ba, wb, opts);
|
write_BUNDLESHS(ba, wb, opts);
|
||||||
/* [FNGROUP] */
|
/* [FNGROUP] */
|
||||||
/* [EXTERNALS] */
|
/* [EXTERNALS] */
|
||||||
@ -10790,6 +10835,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
|||||||
var cstys = [], csty, seencol = false;
|
var cstys = [], csty, seencol = false;
|
||||||
var arrayf = [];
|
var arrayf = [];
|
||||||
var rowinfo = [];
|
var rowinfo = [];
|
||||||
|
var Workbook = { Sheets:[] }, wsprops = {};
|
||||||
xlmlregex.lastIndex = 0;
|
xlmlregex.lastIndex = 0;
|
||||||
str = str.replace(/<!--([^\u2603]*?)-->/mg,"");
|
str = str.replace(/<!--([^\u2603]*?)-->/mg,"");
|
||||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||||
@ -10864,6 +10910,8 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
|||||||
mergecells = [];
|
mergecells = [];
|
||||||
arrayf = [];
|
arrayf = [];
|
||||||
rowinfo = [];
|
rowinfo = [];
|
||||||
|
wsprops = {name:sheetname, Hidden:0};
|
||||||
|
Workbook.Sheets.push(wsprops);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Table':
|
case 'Table':
|
||||||
@ -11088,8 +11136,15 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
|||||||
|
|
||||||
/* WorksheetOptions */
|
/* WorksheetOptions */
|
||||||
case 'WorksheetOptions': switch(Rn[3]) {
|
case 'WorksheetOptions': switch(Rn[3]) {
|
||||||
|
case 'Visible':
|
||||||
|
if(Rn[0].slice(-2) === "/>"){}
|
||||||
|
else if(Rn[1]==="/") switch(str.slice(pidx, Rn.index)) {
|
||||||
|
case "SheetHidden": wsprops.Hidden = 1; break;
|
||||||
|
case "SheetVeryHidden": wsprops.Hidden = 2; break;
|
||||||
|
}
|
||||||
|
else pidx = Rn.index + Rn[0].length;
|
||||||
|
break;
|
||||||
case 'Unsynced': break;
|
case 'Unsynced': break;
|
||||||
case 'Visible': break;
|
|
||||||
case 'Print': break;
|
case 'Print': break;
|
||||||
case 'Panes': break;
|
case 'Panes': break;
|
||||||
case 'Scale': break;
|
case 'Scale': break;
|
||||||
@ -11344,6 +11399,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
|||||||
var out = ({}/*:any*/);
|
var out = ({}/*:any*/);
|
||||||
if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
|
if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
|
||||||
out.SheetNames = sheetnames;
|
out.SheetNames = sheetnames;
|
||||||
|
out.Workbook = Workbook;
|
||||||
out.SSF = SSF.get_table();
|
out.SSF = SSF.get_table();
|
||||||
out.Props = Props;
|
out.Props = Props;
|
||||||
out.Custprops = Custprops;
|
out.Custprops = Custprops;
|
||||||
@ -11380,6 +11436,22 @@ function write_sty_xlml(wb, opts)/*:string*/ {
|
|||||||
/* Styles */
|
/* Styles */
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
/* WorksheetOptions */
|
||||||
|
function write_ws_xlml_wsopts(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
|
||||||
|
var o = [];
|
||||||
|
/* PageSetup */
|
||||||
|
if(wb && wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx]) {
|
||||||
|
/* Visible */
|
||||||
|
if(!!wb.Workbook.Sheets[idx].Hidden) o.push("<Visible>" + (wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden") + "</Visible>");
|
||||||
|
else {
|
||||||
|
/* Selected */
|
||||||
|
for(var i = 0; i < idx; ++i) if(wb.Workbook.Sheets[i] && !wb.Workbook.Sheets[i].Hidden) break;
|
||||||
|
if(i == idx) o.push("<Selected/>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(o.length == 0) return "";
|
||||||
|
return writextag("WorksheetOptions", o.join(""), {xmlns:XLMLNS.x});
|
||||||
|
}
|
||||||
/* TODO */
|
/* TODO */
|
||||||
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{
|
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr)/*:string*/{
|
||||||
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
||||||
@ -11465,7 +11537,10 @@ function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
|
|||||||
/* Table */
|
/* Table */
|
||||||
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||||
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
||||||
|
|
||||||
/* WorksheetOptions */
|
/* WorksheetOptions */
|
||||||
|
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
|
||||||
|
|
||||||
return o.join("");
|
return o.join("");
|
||||||
}
|
}
|
||||||
function write_xlml(wb, opts)/*:string*/ {
|
function write_xlml(wb, opts)/*:string*/ {
|
||||||
@ -11584,6 +11659,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
var cell_valid = true;
|
var cell_valid = true;
|
||||||
var XFs = []; /* XF records */
|
var XFs = []; /* XF records */
|
||||||
var palette = [];
|
var palette = [];
|
||||||
|
var Workbook = { Sheets:[] }, wsprops = {};
|
||||||
var get_rgb = function getrgb(icv) {
|
var get_rgb = function getrgb(icv) {
|
||||||
if(icv < 8) return XLSIcv[icv];
|
if(icv < 8) return XLSIcv[icv];
|
||||||
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
||||||
@ -11755,6 +11831,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if(objects.length > 0) out["!objects"] = objects;
|
if(objects.length > 0) out["!objects"] = objects;
|
||||||
if(colinfo.length > 0) out["!cols"] = colinfo;
|
if(colinfo.length > 0) out["!cols"] = colinfo;
|
||||||
if(rowinfo.length > 0) out["!rows"] = rowinfo;
|
if(rowinfo.length > 0) out["!rows"] = rowinfo;
|
||||||
|
Workbook.Sheets.push(wsprops);
|
||||||
}
|
}
|
||||||
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
|
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
|
||||||
out = {};
|
out = {};
|
||||||
@ -11771,6 +11848,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if(file_depth++) break;
|
if(file_depth++) break;
|
||||||
cell_valid = true;
|
cell_valid = true;
|
||||||
out = {};
|
out = {};
|
||||||
|
|
||||||
if(opts.biff < 5) {
|
if(opts.biff < 5) {
|
||||||
if(cur_sheet === "") cur_sheet = "Sheet1";
|
if(cur_sheet === "") cur_sheet = "Sheet1";
|
||||||
range = {s:{r:0,c:0},e:{r:0,c:0}};
|
range = {s:{r:0,c:0},e:{r:0,c:0}};
|
||||||
@ -11787,6 +11865,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
colinfo = []; rowinfo = [];
|
colinfo = []; rowinfo = [];
|
||||||
defwidth = defheight = 0;
|
defwidth = defheight = 0;
|
||||||
seencol = false;
|
seencol = false;
|
||||||
|
wsprops = {Hidden:(Directory[s]||{hs:0}).hs, name:cur_sheet };
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
|
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
|
||||||
@ -12191,6 +12270,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
if(opts.enc) wb.Encryption = opts.enc;
|
if(opts.enc) wb.Encryption = opts.enc;
|
||||||
wb.Metadata = {};
|
wb.Metadata = {};
|
||||||
if(country !== undefined) wb.Metadata.Country = country;
|
if(country !== undefined) wb.Metadata.Country = country;
|
||||||
|
wb.Workbook = Workbook;
|
||||||
return wb;
|
return wb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14340,14 +14420,15 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
|||||||
var i=0;
|
var i=0;
|
||||||
var sheetRels = ({}/*:any*/);
|
var sheetRels = ({}/*:any*/);
|
||||||
var path, relsPath;
|
var path, relsPath;
|
||||||
if(!props.Worksheets) {
|
|
||||||
|
//if(!props.Worksheets) {
|
||||||
var wbsheets = wb.Sheets;
|
var wbsheets = wb.Sheets;
|
||||||
props.Worksheets = wbsheets.length;
|
props.Worksheets = wbsheets.length;
|
||||||
props.SheetNames = [];
|
props.SheetNames = [];
|
||||||
for(var j = 0; j != wbsheets.length; ++j) {
|
for(var j = 0; j != wbsheets.length; ++j) {
|
||||||
props.SheetNames[j] = wbsheets[j].name;
|
props.SheetNames[j] = wbsheets[j].name;
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
|
|
||||||
var wbext = xlsb ? "bin" : "xml";
|
var wbext = xlsb ? "bin" : "xml";
|
||||||
var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
||||||
@ -14428,8 +14509,10 @@ function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
|
|
||||||
/*::if(!wb.Props) throw "unreachable"; */
|
/*::if(!wb.Props) throw "unreachable"; */
|
||||||
f = "docProps/app.xml";
|
f = "docProps/app.xml";
|
||||||
wb.Props.SheetNames = wb.SheetNames;
|
if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;
|
||||||
wb.Props.Worksheets = wb.SheetNames.length;
|
// $FlowIgnore
|
||||||
|
else wb.Props.SheetNames = wb.Workbook.Sheets.filter(function(x) { return x.Hidden != 2; }).map(function(x) { return x.name; });
|
||||||
|
wb.Props.Worksheets = wb.Props.SheetNames.length;
|
||||||
zip.file(f, write_ext_props(wb.Props, opts));
|
zip.file(f, write_ext_props(wb.Props, opts));
|
||||||
ct.extprops.push(f);
|
ct.extprops.push(f);
|
||||||
add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
|
add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
|
||||||
|
115
xlsx.js
115
xlsx.js
@ -1864,6 +1864,7 @@ function prep_blob(blob, pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parsenoop(blob, length) { blob.l += length; }
|
function parsenoop(blob, length) { blob.l += length; }
|
||||||
|
function parsenooplog(blob, length) { if(typeof console != 'undefined') console.log(blob.slice(blob.l, blob.l + length)); blob.l += length; }
|
||||||
|
|
||||||
function writenoop(blob, length) { blob.l += length; }
|
function writenoop(blob, length) { blob.l += length; }
|
||||||
|
|
||||||
@ -3018,8 +3019,8 @@ function parse_ext_props(data, p) {
|
|||||||
var v = parseVector(q.HeadingPairs);
|
var v = parseVector(q.HeadingPairs);
|
||||||
var parts = parseVector(q.TitlesOfParts).map(function(x) { return x.v; });
|
var parts = parseVector(q.TitlesOfParts).map(function(x) { return x.v; });
|
||||||
var idx = 0, len = 0;
|
var idx = 0, len = 0;
|
||||||
for(var i = 0; i !== v.length; ++i) {
|
for(var i = 0; i !== v.length; i+=2) {
|
||||||
len = +(v[++i].v);
|
len = +(v[i+1].v);
|
||||||
switch(v[i].v) {
|
switch(v[i].v) {
|
||||||
case "Worksheets":
|
case "Worksheets":
|
||||||
case "工作表":
|
case "工作表":
|
||||||
@ -3052,6 +3053,7 @@ function parse_ext_props(data, p) {
|
|||||||
idx += len;
|
idx += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9153,7 +9155,7 @@ function write_ws_xml_data(ws, opts, idx, wb, rels) {
|
|||||||
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
|
if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell);
|
||||||
}
|
}
|
||||||
if(r.length > 0) {
|
if(r.length > 0) {
|
||||||
var params = {r:rr}
|
var params = ({r:rr});
|
||||||
if(rows && rows[R]) {
|
if(rows && rows[R]) {
|
||||||
var row = rows[R];
|
var row = rows[R];
|
||||||
if(row.hidden) params.hidden = 1;
|
if(row.hidden) params.hidden = 1;
|
||||||
@ -10031,7 +10033,7 @@ var WBViewDef = [
|
|||||||
|
|
||||||
/* 18.2.19 (CT_Sheet) Defaults */
|
/* 18.2.19 (CT_Sheet) Defaults */
|
||||||
var SheetDef = [
|
var SheetDef = [
|
||||||
['state', 'visible']
|
//['state', 'visible']
|
||||||
];
|
];
|
||||||
|
|
||||||
/* 18.2.2 (CT_CalcPr) Defaults */
|
/* 18.2.2 (CT_CalcPr) Defaults */
|
||||||
@ -10144,7 +10146,15 @@ function parse_wb_xml(data, opts) {
|
|||||||
/* 18.2.20 sheets CT_Sheets 1 */
|
/* 18.2.20 sheets CT_Sheets 1 */
|
||||||
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
||||||
/* 18.2.19 sheet CT_Sheet + */
|
/* 18.2.19 sheet CT_Sheet + */
|
||||||
case '<sheet': delete y[0]; y.name = unescapexml(utf8read(y.name)); wb.Sheets.push(y); break;
|
case '<sheet':
|
||||||
|
switch(y.state) {
|
||||||
|
case "hidden": y.Hidden = 1; break;
|
||||||
|
case "veryHidden": y.Hidden = 2; break;
|
||||||
|
default: y.Hidden = 0;
|
||||||
|
}
|
||||||
|
delete y.state;
|
||||||
|
y.name = unescapexml(utf8read(y.name));
|
||||||
|
delete y[0]; wb.Sheets.push(y); break;
|
||||||
case '</sheet>': break;
|
case '</sheet>': break;
|
||||||
|
|
||||||
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
||||||
@ -10254,8 +10264,17 @@ function write_wb_xml(wb, opts) {
|
|||||||
o[o.length] = WB_XML_ROOT;
|
o[o.length] = WB_XML_ROOT;
|
||||||
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb), codeName:"ThisWorkbook"}));
|
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb), codeName:"ThisWorkbook"}));
|
||||||
o[o.length] = "<sheets>";
|
o[o.length] = "<sheets>";
|
||||||
for(var i = 0; i != wb.SheetNames.length; ++i)
|
var sheets = wb.Workbook && wb.Workbook.Sheets || [];
|
||||||
o[o.length] = (writextag('sheet',null,{name:escapexml(wb.SheetNames[i].substr(0,31)), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
for(var i = 0; i != wb.SheetNames.length; ++i) {
|
||||||
|
var sht = ({name:escapexml(wb.SheetNames[i].substr(0,31))});
|
||||||
|
sht.sheetId = ""+(i+1);
|
||||||
|
sht["r:id"] = "rId"+(i+1);
|
||||||
|
if(sheets[i]) switch(sheets[i].Hidden) {
|
||||||
|
case 1: sht.state = "hidden"; break;
|
||||||
|
case 2: sht.state = "veryHidden"; break;
|
||||||
|
}
|
||||||
|
o[o.length] = (writextag('sheet',null,sht));
|
||||||
|
}
|
||||||
o[o.length] = "</sheets>";
|
o[o.length] = "</sheets>";
|
||||||
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
||||||
return o.join("");
|
return o.join("");
|
||||||
@ -10263,7 +10282,7 @@ function write_wb_xml(wb, opts) {
|
|||||||
/* [MS-XLSB] 2.4.301 BrtBundleSh */
|
/* [MS-XLSB] 2.4.301 BrtBundleSh */
|
||||||
function parse_BrtBundleSh(data, length) {
|
function parse_BrtBundleSh(data, length) {
|
||||||
var z = {};
|
var z = {};
|
||||||
z.hsState = data.read_shift(4); //ST_SheetState
|
z.Hidden = data.read_shift(4); //hsState ST_SheetState
|
||||||
z.iTabID = data.read_shift(4);
|
z.iTabID = data.read_shift(4);
|
||||||
z.strRelID = parse_RelID(data,length-8);
|
z.strRelID = parse_RelID(data,length-8);
|
||||||
z.name = parse_XLWideString(data);
|
z.name = parse_XLWideString(data);
|
||||||
@ -10271,7 +10290,7 @@ function parse_BrtBundleSh(data, length) {
|
|||||||
}
|
}
|
||||||
function write_BrtBundleSh(data, o) {
|
function write_BrtBundleSh(data, o) {
|
||||||
if(!o) o = new_buf(127);
|
if(!o) o = new_buf(127);
|
||||||
o.write_shift(4, data.hsState);
|
o.write_shift(4, data.Hidden);
|
||||||
o.write_shift(4, data.iTabID);
|
o.write_shift(4, data.iTabID);
|
||||||
write_RelID(data.strRelID, o);
|
write_RelID(data.strRelID, o);
|
||||||
write_XLWideString(data.name.substr(0,31), o);
|
write_XLWideString(data.name.substr(0,31), o);
|
||||||
@ -10400,7 +10419,8 @@ function parse_wb_bin(data, opts) {
|
|||||||
function write_BUNDLESHS(ba, wb, opts) {
|
function write_BUNDLESHS(ba, wb, opts) {
|
||||||
write_record(ba, "BrtBeginBundleShs");
|
write_record(ba, "BrtBeginBundleShs");
|
||||||
for(var idx = 0; idx != wb.SheetNames.length; ++idx) {
|
for(var idx = 0; idx != wb.SheetNames.length; ++idx) {
|
||||||
var d = { hsState: 0, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] };
|
var viz = wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx] && wb.Workbook.Sheets[idx].Hidden || 0;
|
||||||
|
var d = { Hidden: viz, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] };
|
||||||
write_record(ba, "BrtBundleSh", write_BrtBundleSh(d));
|
write_record(ba, "BrtBundleSh", write_BrtBundleSh(d));
|
||||||
}
|
}
|
||||||
write_record(ba, "BrtEndBundleShs");
|
write_record(ba, "BrtEndBundleShs");
|
||||||
@ -10418,9 +10438,34 @@ function write_BrtFileVersion(data, o) {
|
|||||||
return o.length > o.l ? o.slice(0, o.l) : o;
|
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.298 BrtBookView */
|
||||||
|
function write_BrtBookView(idx, o) {
|
||||||
|
if(!o) o = new_buf(29);
|
||||||
|
o.write_shift(-4, 0);
|
||||||
|
o.write_shift(-4, 460);
|
||||||
|
o.write_shift(4, 28800);
|
||||||
|
o.write_shift(4, 17600);
|
||||||
|
o.write_shift(4, 500);
|
||||||
|
o.write_shift(4, idx);
|
||||||
|
o.write_shift(4, idx);
|
||||||
|
var flags = 0x78;
|
||||||
|
o.write_shift(1, flags);
|
||||||
|
return o.length > o.l ? o.slice(0, o.l) : o;
|
||||||
|
}
|
||||||
|
|
||||||
/* [MS-XLSB] 2.1.7.60 Workbook */
|
/* [MS-XLSB] 2.1.7.60 Workbook */
|
||||||
function write_BOOKVIEWS(ba, wb, opts) {
|
function write_BOOKVIEWS(ba, wb, opts) {
|
||||||
|
/* required if hidden tab appears before visible tab */
|
||||||
|
if(!wb.Workbook || !wb.Workbook.Sheets) return;
|
||||||
|
var sheets = wb.Workbook.Sheets;
|
||||||
|
var i = 0, vistab = -1, hidden = -1;
|
||||||
|
for(; i < sheets.length; ++i) {
|
||||||
|
if(!sheets[i] || !sheets[i].Hidden && vistab == -1) vistab = i;
|
||||||
|
else if(sheets[i].Hidden == 1 && hidden == -1) hidden = i;
|
||||||
|
}
|
||||||
|
if(hidden > vistab) return;
|
||||||
write_record(ba, "BrtBeginBookViews");
|
write_record(ba, "BrtBeginBookViews");
|
||||||
|
write_record(ba, "BrtBookView", write_BrtBookView(vistab));
|
||||||
/* 1*(BrtBookView *FRT) */
|
/* 1*(BrtBookView *FRT) */
|
||||||
write_record(ba, "BrtEndBookViews");
|
write_record(ba, "BrtEndBookViews");
|
||||||
}
|
}
|
||||||
@ -10454,7 +10499,7 @@ function write_wb_bin(wb, opts) {
|
|||||||
write_record(ba, "BrtWbProp", write_BrtWbProp());
|
write_record(ba, "BrtWbProp", write_BrtWbProp());
|
||||||
/* [ACABSPATH] */
|
/* [ACABSPATH] */
|
||||||
/* [[BrtBookProtectionIso] BrtBookProtection] */
|
/* [[BrtBookProtectionIso] BrtBookProtection] */
|
||||||
/* write_BOOKVIEWS(ba, wb, opts); */
|
write_BOOKVIEWS(ba, wb, opts);
|
||||||
write_BUNDLESHS(ba, wb, opts);
|
write_BUNDLESHS(ba, wb, opts);
|
||||||
/* [FNGROUP] */
|
/* [FNGROUP] */
|
||||||
/* [EXTERNALS] */
|
/* [EXTERNALS] */
|
||||||
@ -10733,6 +10778,7 @@ function parse_xlml_xml(d, opts) {
|
|||||||
var cstys = [], csty, seencol = false;
|
var cstys = [], csty, seencol = false;
|
||||||
var arrayf = [];
|
var arrayf = [];
|
||||||
var rowinfo = [];
|
var rowinfo = [];
|
||||||
|
var Workbook = { Sheets:[] }, wsprops = {};
|
||||||
xlmlregex.lastIndex = 0;
|
xlmlregex.lastIndex = 0;
|
||||||
str = str.replace(/<!--([^\u2603]*?)-->/mg,"");
|
str = str.replace(/<!--([^\u2603]*?)-->/mg,"");
|
||||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||||
@ -10806,6 +10852,8 @@ for(var cma = c; cma <= cc; ++cma) {
|
|||||||
mergecells = [];
|
mergecells = [];
|
||||||
arrayf = [];
|
arrayf = [];
|
||||||
rowinfo = [];
|
rowinfo = [];
|
||||||
|
wsprops = {name:sheetname, Hidden:0};
|
||||||
|
Workbook.Sheets.push(wsprops);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'Table':
|
case 'Table':
|
||||||
@ -11030,8 +11078,15 @@ for(var cma = c; cma <= cc; ++cma) {
|
|||||||
|
|
||||||
/* WorksheetOptions */
|
/* WorksheetOptions */
|
||||||
case 'WorksheetOptions': switch(Rn[3]) {
|
case 'WorksheetOptions': switch(Rn[3]) {
|
||||||
|
case 'Visible':
|
||||||
|
if(Rn[0].slice(-2) === "/>"){}
|
||||||
|
else if(Rn[1]==="/") switch(str.slice(pidx, Rn.index)) {
|
||||||
|
case "SheetHidden": wsprops.Hidden = 1; break;
|
||||||
|
case "SheetVeryHidden": wsprops.Hidden = 2; break;
|
||||||
|
}
|
||||||
|
else pidx = Rn.index + Rn[0].length;
|
||||||
|
break;
|
||||||
case 'Unsynced': break;
|
case 'Unsynced': break;
|
||||||
case 'Visible': break;
|
|
||||||
case 'Print': break;
|
case 'Print': break;
|
||||||
case 'Panes': break;
|
case 'Panes': break;
|
||||||
case 'Scale': break;
|
case 'Scale': break;
|
||||||
@ -11286,6 +11341,7 @@ for(var cma = c; cma <= cc; ++cma) {
|
|||||||
var out = ({});
|
var out = ({});
|
||||||
if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
|
if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
|
||||||
out.SheetNames = sheetnames;
|
out.SheetNames = sheetnames;
|
||||||
|
out.Workbook = Workbook;
|
||||||
out.SSF = SSF.get_table();
|
out.SSF = SSF.get_table();
|
||||||
out.Props = Props;
|
out.Props = Props;
|
||||||
out.Custprops = Custprops;
|
out.Custprops = Custprops;
|
||||||
@ -11321,6 +11377,22 @@ function write_sty_xlml(wb, opts) {
|
|||||||
/* Styles */
|
/* Styles */
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
/* WorksheetOptions */
|
||||||
|
function write_ws_xlml_wsopts(ws, opts, idx, wb) {
|
||||||
|
var o = [];
|
||||||
|
/* PageSetup */
|
||||||
|
if(wb && wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx]) {
|
||||||
|
/* Visible */
|
||||||
|
if(!!wb.Workbook.Sheets[idx].Hidden) o.push("<Visible>" + (wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden") + "</Visible>");
|
||||||
|
else {
|
||||||
|
/* Selected */
|
||||||
|
for(var i = 0; i < idx; ++i) if(wb.Workbook.Sheets[i] && !wb.Workbook.Sheets[i].Hidden) break;
|
||||||
|
if(i == idx) o.push("<Selected/>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(o.length == 0) return "";
|
||||||
|
return writextag("WorksheetOptions", o.join(""), {xmlns:XLMLNS.x});
|
||||||
|
}
|
||||||
/* TODO */
|
/* TODO */
|
||||||
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
|
function write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr){
|
||||||
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
if(!cell || cell.v == undefined && cell.f == undefined) return "<Cell></Cell>";
|
||||||
@ -11406,7 +11478,10 @@ function write_ws_xlml(idx, opts, wb) {
|
|||||||
/* Table */
|
/* Table */
|
||||||
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
var t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
|
||||||
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
if(t.length > 0) o.push("<Table>" + t + "</Table>");
|
||||||
|
|
||||||
/* WorksheetOptions */
|
/* WorksheetOptions */
|
||||||
|
o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
|
||||||
|
|
||||||
return o.join("");
|
return o.join("");
|
||||||
}
|
}
|
||||||
function write_xlml(wb, opts) {
|
function write_xlml(wb, opts) {
|
||||||
@ -11525,6 +11600,7 @@ function parse_workbook(blob, options) {
|
|||||||
var cell_valid = true;
|
var cell_valid = true;
|
||||||
var XFs = []; /* XF records */
|
var XFs = []; /* XF records */
|
||||||
var palette = [];
|
var palette = [];
|
||||||
|
var Workbook = { Sheets:[] }, wsprops = {};
|
||||||
var get_rgb = function getrgb(icv) {
|
var get_rgb = function getrgb(icv) {
|
||||||
if(icv < 8) return XLSIcv[icv];
|
if(icv < 8) return XLSIcv[icv];
|
||||||
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
if(icv < 64) return palette[icv-8] || XLSIcv[icv];
|
||||||
@ -11696,6 +11772,7 @@ function parse_workbook(blob, options) {
|
|||||||
if(objects.length > 0) out["!objects"] = objects;
|
if(objects.length > 0) out["!objects"] = objects;
|
||||||
if(colinfo.length > 0) out["!cols"] = colinfo;
|
if(colinfo.length > 0) out["!cols"] = colinfo;
|
||||||
if(rowinfo.length > 0) out["!rows"] = rowinfo;
|
if(rowinfo.length > 0) out["!rows"] = rowinfo;
|
||||||
|
Workbook.Sheets.push(wsprops);
|
||||||
}
|
}
|
||||||
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
|
if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
|
||||||
out = {};
|
out = {};
|
||||||
@ -11712,6 +11789,7 @@ function parse_workbook(blob, options) {
|
|||||||
if(file_depth++) break;
|
if(file_depth++) break;
|
||||||
cell_valid = true;
|
cell_valid = true;
|
||||||
out = {};
|
out = {};
|
||||||
|
|
||||||
if(opts.biff < 5) {
|
if(opts.biff < 5) {
|
||||||
if(cur_sheet === "") cur_sheet = "Sheet1";
|
if(cur_sheet === "") cur_sheet = "Sheet1";
|
||||||
range = {s:{r:0,c:0},e:{r:0,c:0}};
|
range = {s:{r:0,c:0},e:{r:0,c:0}};
|
||||||
@ -11728,6 +11806,7 @@ function parse_workbook(blob, options) {
|
|||||||
colinfo = []; rowinfo = [];
|
colinfo = []; rowinfo = [];
|
||||||
defwidth = defheight = 0;
|
defwidth = defheight = 0;
|
||||||
seencol = false;
|
seencol = false;
|
||||||
|
wsprops = {Hidden:(Directory[s]||{hs:0}).hs, name:cur_sheet };
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
|
case 'Number': case 'BIFF2NUM': case 'BIFF2INT': {
|
||||||
@ -12132,6 +12211,7 @@ function parse_workbook(blob, options) {
|
|||||||
if(opts.enc) wb.Encryption = opts.enc;
|
if(opts.enc) wb.Encryption = opts.enc;
|
||||||
wb.Metadata = {};
|
wb.Metadata = {};
|
||||||
if(country !== undefined) wb.Metadata.Country = country;
|
if(country !== undefined) wb.Metadata.Country = country;
|
||||||
|
wb.Workbook = Workbook;
|
||||||
return wb;
|
return wb;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14280,14 +14360,15 @@ function parse_zip(zip, opts) {
|
|||||||
var i=0;
|
var i=0;
|
||||||
var sheetRels = ({});
|
var sheetRels = ({});
|
||||||
var path, relsPath;
|
var path, relsPath;
|
||||||
if(!props.Worksheets) {
|
|
||||||
|
//if(!props.Worksheets) {
|
||||||
var wbsheets = wb.Sheets;
|
var wbsheets = wb.Sheets;
|
||||||
props.Worksheets = wbsheets.length;
|
props.Worksheets = wbsheets.length;
|
||||||
props.SheetNames = [];
|
props.SheetNames = [];
|
||||||
for(var j = 0; j != wbsheets.length; ++j) {
|
for(var j = 0; j != wbsheets.length; ++j) {
|
||||||
props.SheetNames[j] = wbsheets[j].name;
|
props.SheetNames[j] = wbsheets[j].name;
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
|
|
||||||
var wbext = xlsb ? "bin" : "xml";
|
var wbext = xlsb ? "bin" : "xml";
|
||||||
var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
||||||
@ -14366,8 +14447,10 @@ var zip = new jszip();
|
|||||||
add_rels(opts.rels, 2, f, RELS.CORE_PROPS);
|
add_rels(opts.rels, 2, f, RELS.CORE_PROPS);
|
||||||
|
|
||||||
f = "docProps/app.xml";
|
f = "docProps/app.xml";
|
||||||
wb.Props.SheetNames = wb.SheetNames;
|
if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;
|
||||||
wb.Props.Worksheets = wb.SheetNames.length;
|
// $FlowIgnore
|
||||||
|
else wb.Props.SheetNames = wb.Workbook.Sheets.filter(function(x) { return x.Hidden != 2; }).map(function(x) { return x.name; });
|
||||||
|
wb.Props.Worksheets = wb.Props.SheetNames.length;
|
||||||
zip.file(f, write_ext_props(wb.Props, opts));
|
zip.file(f, write_ext_props(wb.Props, opts));
|
||||||
ct.extprops.push(f);
|
ct.extprops.push(f);
|
||||||
add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
|
add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
|
||||||
|
Loading…
Reference in New Issue
Block a user