forked from sheetjs/sheetjs
XLS/XLSX/XLSB Row Outline Levels (closes #723)
note: @sheetjsdev rewrote implementation, original PR author used
This commit is contained in:
parent
859691b87b
commit
d28cc872c7
@ -1204,9 +1204,14 @@ type RowInfo = {
|
||||
/* row height is specified in one of the following ways: */
|
||||
hpx?: number; // height in screen pixels
|
||||
hpt?: number; // height in points
|
||||
|
||||
level?: number; // 0-indexed outline / group level
|
||||
};
|
||||
```
|
||||
|
||||
Note: Excel UI displays the base outline level as `1` and the max level as `8`.
|
||||
The `level` field stores the base outline as `0` and the max level as `7`.
|
||||
|
||||
<details>
|
||||
<summary><b>Implementation details</b> (click to show)</summary>
|
||||
|
||||
|
@ -224,6 +224,8 @@ function parse_Row(blob, length) {
|
||||
blob.l += 4; // reserved(2), unused(2)
|
||||
var flags = blob.read_shift(1); // various flags
|
||||
blob.l += 3; // reserved(8), ixfe(12), flags(4)
|
||||
if(flags & 0x07) z.level = flags & 0x07;
|
||||
// collapsed: flags & 0x10
|
||||
if(flags & 0x20) z.hidden = true;
|
||||
if(flags & 0x40) z.hpt = miyRw / 20;
|
||||
return z;
|
||||
|
@ -262,6 +262,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
||||
@ -391,7 +392,7 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
||||
if(_cell === undefined) continue;
|
||||
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb)) != null) r.push(cell);
|
||||
}
|
||||
if(r.length > 0) {
|
||||
if(r.length > 0 || rows && rows[R]) {
|
||||
var params = ({r:rr}/*:any*/);
|
||||
if(rows && rows[R]) {
|
||||
var row = rows[R];
|
||||
@ -400,10 +401,24 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
||||
if (row.hpx) height = px2pt(row.hpx);
|
||||
else if (row.hpt) height = row.hpt;
|
||||
if (height > -1) { params.ht = height; params.customHeight = 1; }
|
||||
if (row.level) { params.outlineLevel = row.level; }
|
||||
}
|
||||
o[o.length] = (writextag('row', r.join(""), params));
|
||||
}
|
||||
}
|
||||
if(rows) for(; R < rows.length; ++R) {
|
||||
if(rows && rows[R]) {
|
||||
var params = ({r:R+1}/*:any*/);
|
||||
var row = rows[R];
|
||||
if(row.hidden) params.hidden = 1;
|
||||
var height = -1;
|
||||
if (row.hpx) height = px2pt(row.hpx);
|
||||
else if (row.hpt) height = row.hpt;
|
||||
if (height > -1) { params.ht = height; params.customHeight = 1; }
|
||||
if (row.level) { params.outlineLevel = row.level; }
|
||||
o[o.length] = (writextag('row', "", params));
|
||||
}
|
||||
}
|
||||
return o.join("");
|
||||
}
|
||||
|
||||
@ -429,7 +444,11 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
o[o.length] = write_ws_xml_sheetviews(ws, opts, idx, wb);
|
||||
|
||||
/* TODO: store in WB, process styles */
|
||||
if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16', baseColWidth:opts.sheetFormat.baseColWidth||'10' }));
|
||||
if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {
|
||||
defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16',
|
||||
baseColWidth:opts.sheetFormat.baseColWidth||'10',
|
||||
outlineLevelRow:opts.sheetFormat.outlineLevelRow||'7'
|
||||
}));
|
||||
|
||||
if(ws['!cols'] != null && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
|
||||
|
||||
|
@ -9,6 +9,7 @@ function parse_BrtRowHdr(data, length) {
|
||||
data.l += 1; // TODO: top/bot padding
|
||||
var flags = data.read_shift(1);
|
||||
data.l = tgt;
|
||||
if(flags & 0x07) z.level = flags & 0x07;
|
||||
if(flags & 0x10) z.hidden = true;
|
||||
if(flags & 0x20) z.hpt = miyRw / 20;
|
||||
return z;
|
||||
@ -28,6 +29,7 @@ function write_BrtRowHdr(R/*:number*/, range, ws) {
|
||||
o.write_shift(1, 0); /* top/bot padding */
|
||||
|
||||
var flags = 0x0;
|
||||
if(row.level) flags |= row.level;
|
||||
if(row.hidden) flags |= 0x10;
|
||||
if(row.hpx || row.hpt) flags |= 0x20;
|
||||
o.write_shift(1, flags);
|
||||
@ -62,7 +64,7 @@ function write_BrtRowHdr(R/*:number*/, range, ws) {
|
||||
}
|
||||
function write_row_header(ba, ws, range, R) {
|
||||
var o = write_BrtRowHdr(R, range, ws);
|
||||
if(o.length > 17) write_record(ba, 'BrtRowHdr', o);
|
||||
if(o.length > 17 || (ws['!rows']||[])[R]) write_record(ba, 'BrtRowHdr', o);
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.812 BrtWsDim */
|
||||
@ -426,7 +428,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
if(opts.sheetRows && opts.sheetRows <= row.r) end=true;
|
||||
rr = encode_row(R = row.r);
|
||||
opts['!row'] = row.r;
|
||||
if(val.hidden || val.hpt) {
|
||||
if(val.hidden || val.hpt || val.level != null) {
|
||||
if(val.hpt) val.hpx = pt2px(val.hpt);
|
||||
rowinfo[val.r] = val;
|
||||
}
|
||||
@ -684,12 +686,14 @@ function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbo
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
|
||||
write_record(ba, 'BrtBeginSheetData');
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
var cap = range.e.r;
|
||||
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
|
||||
for(var R = range.s.r; R <= cap; ++R) {
|
||||
rr = encode_row(R);
|
||||
/* [ACCELLTABLE] */
|
||||
/* BrtRowHdr */
|
||||
write_row_header(ba, ws, range, R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
/* *16384CELL */
|
||||
if(R === range.s.r) cols[C] = encode_col(C);
|
||||
ref = cols[C] + rr;
|
||||
|
@ -521,6 +521,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
} break;
|
||||
case 'Row': {
|
||||
var rowobj = {};
|
||||
if(val.level != null) { rowinfo[val.r] = rowobj; rowobj.level = val.level; }
|
||||
if(val.hidden) { rowinfo[val.r] = rowobj; rowobj.hidden = true; }
|
||||
if(val.hpt) {
|
||||
rowinfo[val.r] = rowobj;
|
||||
|
@ -289,6 +289,9 @@ var parse_content_xml = (function() {
|
||||
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
/* TODO: outline levels */
|
||||
case 'table-row-group': break; // 9.1.9 <table:table-row-group>
|
||||
case 'table-column-group': break; // 9.1.10 <table:table-column-group>
|
||||
|
||||
case 'null-date': break; // 9.4.2 <table:null-date> TODO: date1904
|
||||
|
||||
|
@ -75,9 +75,14 @@ type RowInfo = {
|
||||
/* row height is specified in one of the following ways: */
|
||||
hpx?: number; // height in screen pixels
|
||||
hpt?: number; // height in points
|
||||
|
||||
level?: number; // 0-indexed outline / group level
|
||||
};
|
||||
```
|
||||
|
||||
Note: Excel UI displays the base outline level as `1` and the max level as `8`.
|
||||
The `level` field stores the base outline as `0` and the max level as `7`.
|
||||
|
||||
<details>
|
||||
<summary><b>Implementation details</b> (click to show)</summary>
|
||||
|
||||
|
@ -1105,9 +1105,14 @@ type RowInfo = {
|
||||
/* row height is specified in one of the following ways: */
|
||||
hpx?: number; // height in screen pixels
|
||||
hpt?: number; // height in points
|
||||
|
||||
level?: number; // 0-indexed outline / group level
|
||||
};
|
||||
```
|
||||
|
||||
Note: Excel UI displays the base outline level as `1` and the max level as `8`.
|
||||
The `level` field stores the base outline as `0` and the max level as `7`.
|
||||
|
||||
|
||||
Excel internally stores row heights in points. The default resolution is 72 DPI
|
||||
or 96 PPI, so the pixel and point size should agree. For different resolutions
|
||||
|
33
test.js
33
test.js
@ -97,6 +97,12 @@ var paths = {
|
||||
nfxlsx: dir + 'number_format.xlsm',
|
||||
nfxlsb: dir + 'number_format.xlsb',
|
||||
|
||||
olxls: dir + 'outline.xls',
|
||||
olxls5: dir + 'outline.biff5',
|
||||
olxlsx: dir + 'outline.xlsx',
|
||||
olxlsb: dir + 'outline.xlsb',
|
||||
olods: dir + 'outline.ods',
|
||||
|
||||
pmxls: dir + 'page_margins_2016.xls',
|
||||
pmxls5: dir + 'page_margins_2016_5.xls',
|
||||
pmxml: dir + 'page_margins_2016.xml',
|
||||
@ -901,6 +907,7 @@ describe('parse features', function() {
|
||||
|
||||
describe('row properties', function() {
|
||||
var wb1, wb2, wb3, wb4, wb5, wb6;
|
||||
var ol1, ol2, ol3, ol4, ol5;
|
||||
var bef = (function() {
|
||||
X = require(modp);
|
||||
wb1 = X.readFile(paths.rhxlsx, {cellStyles:true});
|
||||
@ -909,6 +916,11 @@ describe('parse features', function() {
|
||||
wb4 = X.readFile(paths.rhxls5, {cellStyles:true});
|
||||
wb5 = X.readFile(paths.rhxml, {cellStyles:true});
|
||||
wb6 = X.readFile(paths.rhslk, {cellStyles:true});
|
||||
ol1 = X.readFile(paths.olxlsx, {cellStyles:true});
|
||||
ol2 = X.readFile(paths.olxlsb, {cellStyles:true});
|
||||
ol3 = X.readFile(paths.olxls, {cellStyles:true});
|
||||
ol4 = X.readFile(paths.olxls5, {cellStyles:true});
|
||||
ol5 = X.readFile(paths.olods, {cellStyles:true});
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
else it('before', bef);
|
||||
@ -930,6 +942,22 @@ describe('parse features', function() {
|
||||
assert.equal(x[3].hpx, 100);
|
||||
});
|
||||
});
|
||||
it('should have correct outline levels', function() {
|
||||
/* TODO: ODS */
|
||||
[ol1, ol2, ol3, ol4/*, ol5*/].map(function(x) { return x.Sheets.Sheet1; }).forEach(function(ws) {
|
||||
var rows = ws['!rows'];
|
||||
for(var i = 0; i < 29; ++i) {
|
||||
var cell = get_cell(ws, "A" + X.utils.encode_row(i));
|
||||
var lvl = (rows[i]||{}).level||0;
|
||||
if(!cell || cell.t == 's') assert.equal(lvl, 0);
|
||||
else if(cell.t == 'n') {
|
||||
if(cell.v == 0) assert.equal(lvl, 0);
|
||||
else assert.equal(lvl, cell.v);
|
||||
}
|
||||
}
|
||||
assert.equal(rows[29].level, 7);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('merge cells',function() {
|
||||
@ -1400,18 +1428,21 @@ describe('roundtrip features', function() {
|
||||
}); });
|
||||
});
|
||||
|
||||
/* TODO: ODS and BIFF5/8 */
|
||||
describe('should preserve row properties', function() { [
|
||||
'xlml', /*'biff2', */ 'xlsx', 'xlsb', 'slk'
|
||||
].forEach(function(w) { it(w, function() {
|
||||
var ws1 = X.utils.aoa_to_sheet([["hpx12"],["hpt24"],["hpx48"],["hidden"]]);
|
||||
ws1['!rows'] = [{hpx:12},{hpt:24},{hpx:48},{hidden:true}];
|
||||
for(var i = 0; i <= 7; ++i) ws1['!rows'].push({level:i});
|
||||
var wb1 = {SheetNames:["Sheet1"], Sheets:{Sheet1:ws1}};
|
||||
var wb2 = X.read(X.write(wb1, {bookType:w, type:"buffer"}), {type:"buffer", cellStyles:true});
|
||||
var wb2 = X.read(X.write(wb1, {bookType:w, type:"buffer", cellStyles:true}), {type:"buffer", cellStyles:true});
|
||||
var ws2 = wb2.Sheets.Sheet1;
|
||||
assert.equal(ws2['!rows'][0].hpx, 12);
|
||||
assert.equal(ws2['!rows'][1].hpt, 24);
|
||||
assert.equal(ws2['!rows'][2].hpx, 48);
|
||||
assert.equal(ws2['!rows'][3].hidden, true);
|
||||
if(w == 'xlsb' || w == 'xlsx') for(i = 0; i <= 7; ++i) assert.equal((ws2['!rows'][4+i]||{}).level||0, i);
|
||||
}); });
|
||||
});
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 249b005fddf7cea0b2c2d1aff5a2414e47e70c0e
|
||||
Subproject commit d0f58a9e4b0519a513a1e44d1b28109fd4a8e13e
|
@ -25,7 +25,7 @@ var wsrows = [
|
||||
{hpt: 12}, // "points"
|
||||
{hpx: 16}, // "pixels"
|
||||
,
|
||||
{hpx: 24},
|
||||
{hpx: 24, level:3},
|
||||
{hidden: true}, // hide row
|
||||
{hidden: false}
|
||||
];
|
||||
|
45
xlsx.flow.js
45
xlsx.flow.js
@ -4292,6 +4292,8 @@ function parse_Row(blob, length) {
|
||||
blob.l += 4; // reserved(2), unused(2)
|
||||
var flags = blob.read_shift(1); // various flags
|
||||
blob.l += 3; // reserved(8), ixfe(12), flags(4)
|
||||
if(flags & 0x07) z.level = flags & 0x07;
|
||||
// collapsed: flags & 0x10
|
||||
if(flags & 0x20) z.hidden = true;
|
||||
if(flags & 0x40) z.hpt = miyRw / 20;
|
||||
return z;
|
||||
@ -5730,7 +5732,8 @@ var PRN = (function() {
|
||||
function finish_cell() {
|
||||
var s = str.slice(start, end);
|
||||
var cell = ({}/*:any*/);
|
||||
if(s.charCodeAt(0) == 0x3D) { cell.t = 'n'; cell.f = s.substr(1); }
|
||||
if(o.raw) { cell.t = 's'; cell.v = s; }
|
||||
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; }
|
||||
@ -5824,7 +5827,6 @@ function read_wb_ID(d, opts) {
|
||||
return PRN.to_workbook(d, opts);
|
||||
}
|
||||
}
|
||||
|
||||
var WK_ = (function() {
|
||||
function lotushopper(data, cb/*:RecordHopperCB*/, opts/*:any*/) {
|
||||
if(!data) return;
|
||||
@ -10999,6 +11001,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
||||
@ -11128,7 +11131,7 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
||||
if(_cell === undefined) continue;
|
||||
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb)) != null) r.push(cell);
|
||||
}
|
||||
if(r.length > 0) {
|
||||
if(r.length > 0 || rows && rows[R]) {
|
||||
var params = ({r:rr}/*:any*/);
|
||||
if(rows && rows[R]) {
|
||||
var row = rows[R];
|
||||
@ -11137,10 +11140,24 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook
|
||||
if (row.hpx) height = px2pt(row.hpx);
|
||||
else if (row.hpt) height = row.hpt;
|
||||
if (height > -1) { params.ht = height; params.customHeight = 1; }
|
||||
if (row.level) { params.outlineLevel = row.level; }
|
||||
}
|
||||
o[o.length] = (writextag('row', r.join(""), params));
|
||||
}
|
||||
}
|
||||
if(rows) for(; R < rows.length; ++R) {
|
||||
if(rows && rows[R]) {
|
||||
var params = ({r:R+1}/*:any*/);
|
||||
var row = rows[R];
|
||||
if(row.hidden) params.hidden = 1;
|
||||
var height = -1;
|
||||
if (row.hpx) height = px2pt(row.hpx);
|
||||
else if (row.hpt) height = row.hpt;
|
||||
if (height > -1) { params.ht = height; params.customHeight = 1; }
|
||||
if (row.level) { params.outlineLevel = row.level; }
|
||||
o[o.length] = (writextag('row', "", params));
|
||||
}
|
||||
}
|
||||
return o.join("");
|
||||
}
|
||||
|
||||
@ -11166,7 +11183,11 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
o[o.length] = write_ws_xml_sheetviews(ws, opts, idx, wb);
|
||||
|
||||
/* TODO: store in WB, process styles */
|
||||
if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16', baseColWidth:opts.sheetFormat.baseColWidth||'10' }));
|
||||
if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {
|
||||
defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16',
|
||||
baseColWidth:opts.sheetFormat.baseColWidth||'10',
|
||||
outlineLevelRow:opts.sheetFormat.outlineLevelRow||'7'
|
||||
}));
|
||||
|
||||
if(ws['!cols'] != null && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
|
||||
|
||||
@ -11260,6 +11281,7 @@ function parse_BrtRowHdr(data, length) {
|
||||
data.l += 1; // TODO: top/bot padding
|
||||
var flags = data.read_shift(1);
|
||||
data.l = tgt;
|
||||
if(flags & 0x07) z.level = flags & 0x07;
|
||||
if(flags & 0x10) z.hidden = true;
|
||||
if(flags & 0x20) z.hpt = miyRw / 20;
|
||||
return z;
|
||||
@ -11279,6 +11301,7 @@ function write_BrtRowHdr(R/*:number*/, range, ws) {
|
||||
o.write_shift(1, 0); /* top/bot padding */
|
||||
|
||||
var flags = 0x0;
|
||||
if(row.level) flags |= row.level;
|
||||
if(row.hidden) flags |= 0x10;
|
||||
if(row.hpx || row.hpt) flags |= 0x20;
|
||||
o.write_shift(1, flags);
|
||||
@ -11313,7 +11336,7 @@ function write_BrtRowHdr(R/*:number*/, range, ws) {
|
||||
}
|
||||
function write_row_header(ba, ws, range, R) {
|
||||
var o = write_BrtRowHdr(R, range, ws);
|
||||
if(o.length > 17) write_record(ba, 'BrtRowHdr', o);
|
||||
if(o.length > 17 || (ws['!rows']||[])[R]) write_record(ba, 'BrtRowHdr', o);
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.812 BrtWsDim */
|
||||
@ -11677,7 +11700,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ {
|
||||
if(opts.sheetRows && opts.sheetRows <= row.r) end=true;
|
||||
rr = encode_row(R = row.r);
|
||||
opts['!row'] = row.r;
|
||||
if(val.hidden || val.hpt) {
|
||||
if(val.hidden || val.hpt || val.level != null) {
|
||||
if(val.hpt) val.hpx = pt2px(val.hpt);
|
||||
rowinfo[val.r] = val;
|
||||
}
|
||||
@ -11935,12 +11958,14 @@ function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbo
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
|
||||
write_record(ba, 'BrtBeginSheetData');
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
var cap = range.e.r;
|
||||
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
|
||||
for(var R = range.s.r; R <= cap; ++R) {
|
||||
rr = encode_row(R);
|
||||
/* [ACCELLTABLE] */
|
||||
/* BrtRowHdr */
|
||||
write_row_header(ba, ws, range, R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
/* *16384CELL */
|
||||
if(R === range.s.r) cols[C] = encode_col(C);
|
||||
ref = cols[C] + rr;
|
||||
@ -14524,6 +14549,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
} break;
|
||||
case 'Row': {
|
||||
var rowobj = {};
|
||||
if(val.level != null) { rowinfo[val.r] = rowobj; rowobj.level = val.level; }
|
||||
if(val.hidden) { rowinfo[val.r] = rowobj; rowobj.hidden = true; }
|
||||
if(val.hpt) {
|
||||
rowinfo[val.r] = rowobj;
|
||||
@ -16644,6 +16670,9 @@ var parse_content_xml = (function() {
|
||||
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
/* TODO: outline levels */
|
||||
case 'table-row-group': break; // 9.1.9 <table:table-row-group>
|
||||
case 'table-column-group': break; // 9.1.10 <table:table-column-group>
|
||||
|
||||
case 'null-date': break; // 9.4.2 <table:null-date> TODO: date1904
|
||||
|
||||
|
45
xlsx.js
45
xlsx.js
@ -4230,6 +4230,8 @@ function parse_Row(blob, length) {
|
||||
blob.l += 4; // reserved(2), unused(2)
|
||||
var flags = blob.read_shift(1); // various flags
|
||||
blob.l += 3; // reserved(8), ixfe(12), flags(4)
|
||||
if(flags & 0x07) z.level = flags & 0x07;
|
||||
// collapsed: flags & 0x10
|
||||
if(flags & 0x20) z.hidden = true;
|
||||
if(flags & 0x40) z.hpt = miyRw / 20;
|
||||
return z;
|
||||
@ -5668,7 +5670,8 @@ var PRN = (function() {
|
||||
function finish_cell() {
|
||||
var s = str.slice(start, end);
|
||||
var cell = ({});
|
||||
if(s.charCodeAt(0) == 0x3D) { cell.t = 'n'; cell.f = s.substr(1); }
|
||||
if(o.raw) { cell.t = 's'; cell.v = s; }
|
||||
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; }
|
||||
@ -5762,7 +5765,6 @@ function read_wb_ID(d, opts) {
|
||||
return PRN.to_workbook(d, opts);
|
||||
}
|
||||
}
|
||||
|
||||
var WK_ = (function() {
|
||||
function lotushopper(data, cb, opts) {
|
||||
if(!data) return;
|
||||
@ -10933,6 +10935,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
||||
rowobj = {}; rowrite = false;
|
||||
if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
|
||||
if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
|
||||
if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
|
||||
if(rowrite) rows[tagr-1] = rowobj;
|
||||
}
|
||||
|
||||
@ -11062,7 +11065,7 @@ function write_ws_xml_data(ws, opts, idx, wb, rels) {
|
||||
if(_cell === undefined) continue;
|
||||
if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb)) != null) r.push(cell);
|
||||
}
|
||||
if(r.length > 0) {
|
||||
if(r.length > 0 || rows && rows[R]) {
|
||||
var params = ({r:rr});
|
||||
if(rows && rows[R]) {
|
||||
var row = rows[R];
|
||||
@ -11071,10 +11074,24 @@ function write_ws_xml_data(ws, opts, idx, wb, rels) {
|
||||
if (row.hpx) height = px2pt(row.hpx);
|
||||
else if (row.hpt) height = row.hpt;
|
||||
if (height > -1) { params.ht = height; params.customHeight = 1; }
|
||||
if (row.level) { params.outlineLevel = row.level; }
|
||||
}
|
||||
o[o.length] = (writextag('row', r.join(""), params));
|
||||
}
|
||||
}
|
||||
if(rows) for(; R < rows.length; ++R) {
|
||||
if(rows && rows[R]) {
|
||||
var params = ({r:R+1});
|
||||
var row = rows[R];
|
||||
if(row.hidden) params.hidden = 1;
|
||||
var height = -1;
|
||||
if (row.hpx) height = px2pt(row.hpx);
|
||||
else if (row.hpt) height = row.hpt;
|
||||
if (height > -1) { params.ht = height; params.customHeight = 1; }
|
||||
if (row.level) { params.outlineLevel = row.level; }
|
||||
o[o.length] = (writextag('row', "", params));
|
||||
}
|
||||
}
|
||||
return o.join("");
|
||||
}
|
||||
|
||||
@ -11100,7 +11117,11 @@ function write_ws_xml(idx, opts, wb, rels) {
|
||||
o[o.length] = write_ws_xml_sheetviews(ws, opts, idx, wb);
|
||||
|
||||
/* TODO: store in WB, process styles */
|
||||
if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16', baseColWidth:opts.sheetFormat.baseColWidth||'10' }));
|
||||
if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {
|
||||
defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16',
|
||||
baseColWidth:opts.sheetFormat.baseColWidth||'10',
|
||||
outlineLevelRow:opts.sheetFormat.outlineLevelRow||'7'
|
||||
}));
|
||||
|
||||
if(ws['!cols'] != null && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
|
||||
|
||||
@ -11194,6 +11215,7 @@ function parse_BrtRowHdr(data, length) {
|
||||
data.l += 1; // TODO: top/bot padding
|
||||
var flags = data.read_shift(1);
|
||||
data.l = tgt;
|
||||
if(flags & 0x07) z.level = flags & 0x07;
|
||||
if(flags & 0x10) z.hidden = true;
|
||||
if(flags & 0x20) z.hpt = miyRw / 20;
|
||||
return z;
|
||||
@ -11213,6 +11235,7 @@ function write_BrtRowHdr(R, range, ws) {
|
||||
o.write_shift(1, 0); /* top/bot padding */
|
||||
|
||||
var flags = 0x0;
|
||||
if(row.level) flags |= row.level;
|
||||
if(row.hidden) flags |= 0x10;
|
||||
if(row.hpx || row.hpt) flags |= 0x20;
|
||||
o.write_shift(1, flags);
|
||||
@ -11247,7 +11270,7 @@ function write_BrtRowHdr(R, range, ws) {
|
||||
}
|
||||
function write_row_header(ba, ws, range, R) {
|
||||
var o = write_BrtRowHdr(R, range, ws);
|
||||
if(o.length > 17) write_record(ba, 'BrtRowHdr', o);
|
||||
if(o.length > 17 || (ws['!rows']||[])[R]) write_record(ba, 'BrtRowHdr', o);
|
||||
}
|
||||
|
||||
/* [MS-XLSB] 2.4.812 BrtWsDim */
|
||||
@ -11610,7 +11633,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) {
|
||||
if(opts.sheetRows && opts.sheetRows <= row.r) end=true;
|
||||
rr = encode_row(R = row.r);
|
||||
opts['!row'] = row.r;
|
||||
if(val.hidden || val.hpt) {
|
||||
if(val.hidden || val.hpt || val.level != null) {
|
||||
if(val.hpt) val.hpx = pt2px(val.hpt);
|
||||
rowinfo[val.r] = val;
|
||||
}
|
||||
@ -11868,12 +11891,14 @@ function write_CELLTABLE(ba, ws, idx, opts, wb) {
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
|
||||
write_record(ba, 'BrtBeginSheetData');
|
||||
var dense = Array.isArray(ws);
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
var cap = range.e.r;
|
||||
if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
|
||||
for(var R = range.s.r; R <= cap; ++R) {
|
||||
rr = encode_row(R);
|
||||
/* [ACCELLTABLE] */
|
||||
/* BrtRowHdr */
|
||||
write_row_header(ba, ws, range, R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
/* *16384CELL */
|
||||
if(R === range.s.r) cols[C] = encode_col(C);
|
||||
ref = cols[C] + rr;
|
||||
@ -14450,6 +14475,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
||||
} break;
|
||||
case 'Row': {
|
||||
var rowobj = {};
|
||||
if(val.level != null) { rowinfo[val.r] = rowobj; rowobj.level = val.level; }
|
||||
if(val.hidden) { rowinfo[val.r] = rowobj; rowobj.hidden = true; }
|
||||
if(val.hpt) {
|
||||
rowinfo[val.r] = rowobj;
|
||||
@ -16570,6 +16596,9 @@ var parse_content_xml = (function() {
|
||||
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
/* TODO: outline levels */
|
||||
case 'table-row-group': break; // 9.1.9 <table:table-row-group>
|
||||
case 'table-column-group': break; // 9.1.10 <table:table-column-group>
|
||||
|
||||
case 'null-date': break; // 9.4.2 <table:null-date> TODO: date1904
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user