Skip to content

Commit

Permalink
version bump 0.11.10: binary miscellany
Browse files Browse the repository at this point in the history
- XLSX empty numeric cells stubbed (fixes SheetJS#891 h/t @mgoku)
- XLS sheet type identification
- XLS/XLSB/XLSM CodeName exposure (fixes SheetJS#361 h/t @TennisVisuals)
- CFB re-exported
  • Loading branch information
SheetJSDev committed Nov 20, 2017
1 parent 7c7f4a6 commit 547fba5
Show file tree
Hide file tree
Showing 39 changed files with 882 additions and 610 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1083,6 +1083,7 @@ may not enforce this constraint.

| Key | Description |
|:----------------|:----------------------------------------------------|
| `CodeName` | [VBA Project Workbook Code Name](#vba-and-macros) |
| `date1904` | epoch: 0/false for 1900 system, 1/true for 1904 |
| `filterPrivacy` | Warn or strip personally identifying info on save |

Expand Down Expand Up @@ -1443,6 +1444,19 @@ supported in `XLSM`, `XLSB`, and `BIFF8 XLS` formats. The supported format
writers automatically insert the data blobs if it is present in the workbook and
associate with the worksheet names.

<details>
<summary><b>Custom Code Names</b> (click to show)</summary>

The workbook code name is stored in `wb.Workbook.WBProps.CodeName`. By default,
Excel will write `ThisWorkbook` or a translated phrase like `DieseArbeitsmappe`.
Worksheet and Chartsheet code names are in the worksheet properties object at
`wb.Workbook.Sheets[i].CodeName`. Macrosheets and Dialogsheets are ignored.

The readers and writers preserve the code names, but they have to be manually
set when adding a VBA blob to a different workbook.

</details>

<details>
<summary><b>Macrosheets</b> (click to show)</summary>

Expand Down
4 changes: 4 additions & 0 deletions bin/xlsx.njs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ if(program.all) {
opts.sheetStubs = true;
opts.cellDates = true;
wopts.cellStyles = true;
wopts.bookVBA = true;
}
if(program.sparse) opts.dense = false; else opts.dense = true;

Expand Down Expand Up @@ -194,6 +195,7 @@ if(!program.quiet && !program.book) console.error(target_sheet);
].forEach(function(m) { if(program[m[0]] || isfmt(m[1])) {
wopts.bookType = m[0];
if(program.book) {
/*:: if(wb == null) throw new Error("Unreachable"); */
wb.SheetNames.forEach(function(n, i) {
wopts.sheet = n;
X.writeFile(wb, (program.output || sheetname || filename || "") + m[1] + "." + i, wopts);
Expand All @@ -205,7 +207,9 @@ if(!program.quiet && !program.book) console.error(target_sheet);
function outit(o, fn) { if(fn) fs.writeFileSync(fn, o); else console.log(o); }

function doit(cb) {
/*:: if(!wb) throw new Error("unreachable"); */
if(program.book) wb.SheetNames.forEach(function(n, i) {
/*:: if(!wb) throw new Error("unreachable"); */
outit(cb(wb.Sheets[n]), (program.output || sheetname || filename) + "." + i);
});
else outit(cb(ws), program.output);
Expand Down
2 changes: 1 addition & 1 deletion bits/01_version.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
XLSX.version = '0.11.9';
XLSX.version = '0.11.10';
20 changes: 10 additions & 10 deletions bits/04_base64.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ var Base64 = (function make_b64(){
return {
encode: function(input/*:string*/)/*:string*/ {
var o = "";
var c1, c2, c3, e1, e2, e3, e4;
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
for(var i = 0; i < input.length; ) {
c1 = input.charCodeAt(i++);
c2 = input.charCodeAt(i++);
c3 = input.charCodeAt(i++);
e1 = c1 >> 2;
e2 = (c1 & 3) << 4 | c2 >> 4;
e3 = (c2 & 15) << 2 | c3 >> 6;
e2 = ((c1 & 3) << 4) | (c2 >> 4);
e3 = ((c2 & 15) << 2) | (c3 >> 6);
e4 = c3 & 63;
if (isNaN(c2)) { e3 = e4 = 64; }
else if (isNaN(c3)) { e4 = 64; }
Expand All @@ -20,20 +20,20 @@ var Base64 = (function make_b64(){
},
decode: function b64_decode(input/*:string*/)/*:string*/ {
var o = "";
var c1, c2, c3;
var e1, e2, e3, e4;
var c1=0, c2=0, c3=0;
var e1=0, e2=0, e3=0, e4=0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
for(var i = 0; i < input.length;) {
e1 = map.indexOf(input.charAt(i++));
e2 = map.indexOf(input.charAt(i++));
e3 = map.indexOf(input.charAt(i++));
e4 = map.indexOf(input.charAt(i++));
c1 = e1 << 2 | e2 >> 4;
c2 = (e2 & 15) << 4 | e3 >> 2;
c3 = (e3 & 3) << 6 | e4;
c1 = (e1 << 2) | (e2 >> 4);
c2 = ((e2 & 15) << 4) | (e3 >> 2);
c3 = ((e3 & 3) << 6) | e4;
o += String.fromCharCode(c1);
if (e3 != 64) { o += String.fromCharCode(c2); }
if (e4 != 64) { o += String.fromCharCode(c3); }
if (e3 !== 64) { o += String.fromCharCode(c2); }
if (e4 !== 64) { o += String.fromCharCode(c3); }
}
return o;
}
Expand Down
6 changes: 6 additions & 0 deletions bits/39_xlsbiff.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ function write_WriteAccess(s/*:string*/, opts) {
return o;
}

/* 2.4.351 */
function parse_WsBool(blob, length, opts) {
var flags = opts && opts.biff == 8 || length == 2 ? blob.read_shift(2) : (blob.l += length, 0);
return { fDialog: flags & 0x10 };
}

/* 2.4.28 */
function parse_BoundSheet8(blob, length, opts) {
var pos = blob.read_shift(4);
Expand Down
157 changes: 80 additions & 77 deletions bits/41_lotus.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var WK_ = (function() {
var R = Enum[RT] || Enum[0xFF];
var length = data.read_shift(2);
var tgt = data.l + length;
var d = R.f(data, length, opts);
var d = (R.f||parsenoop)(data, length, opts);
data.l = tgt;
if(cb(d, R.n, RT)) return;
}
Expand Down Expand Up @@ -79,7 +79,10 @@ var WK_ = (function() {
sidx = val[3]; n = "Sheet" + (sidx + 1);
snames.push(n);
}
s[encode_cell(val[0])] = val[1];
if(o.dense) {
if(!s[val[0].r]) s[val[0].r] = [];
s[val[0].r][val[0].c] = val[1];
} else s[encode_cell(val[0])] = val[1];
if(refguess.e.c < val[0].c) refguess.e.c = val[0].c;
if(refguess.e.r < val[0].r) refguess.e.r = val[0].r;
break;
Expand Down Expand Up @@ -227,95 +230,95 @@ var WK_ = (function() {

var WK1Enum = {
/*::[*/0x0000/*::]*/: { n:"BOF", f:parseuint16 },
/*::[*/0x0001/*::]*/: { n:"EOF", f:parsenoop },
/*::[*/0x0002/*::]*/: { n:"CALCMODE", f:parsenoop },
/*::[*/0x0003/*::]*/: { n:"CALCORDER", f:parsenoop },
/*::[*/0x0004/*::]*/: { n:"SPLIT", f:parsenoop },
/*::[*/0x0005/*::]*/: { n:"SYNC", f:parsenoop },
/*::[*/0x0001/*::]*/: { n:"EOF" },
/*::[*/0x0002/*::]*/: { n:"CALCMODE" },
/*::[*/0x0003/*::]*/: { n:"CALCORDER" },
/*::[*/0x0004/*::]*/: { n:"SPLIT" },
/*::[*/0x0005/*::]*/: { n:"SYNC" },
/*::[*/0x0006/*::]*/: { n:"RANGE", f:parse_RANGE },
/*::[*/0x0007/*::]*/: { n:"WINDOW1", f:parsenoop },
/*::[*/0x0008/*::]*/: { n:"COLW1", f:parsenoop },
/*::[*/0x0009/*::]*/: { n:"WINTWO", f:parsenoop },
/*::[*/0x000A/*::]*/: { n:"COLW2", f:parsenoop },
/*::[*/0x000B/*::]*/: { n:"NAME", f:parsenoop },
/*::[*/0x000C/*::]*/: { n:"BLANK", f:parsenoop },
/*::[*/0x0007/*::]*/: { n:"WINDOW1" },
/*::[*/0x0008/*::]*/: { n:"COLW1" },
/*::[*/0x0009/*::]*/: { n:"WINTWO" },
/*::[*/0x000A/*::]*/: { n:"COLW2" },
/*::[*/0x000B/*::]*/: { n:"NAME" },
/*::[*/0x000C/*::]*/: { n:"BLANK" },
/*::[*/0x000D/*::]*/: { n:"INTEGER", f:parse_INTEGER },
/*::[*/0x000E/*::]*/: { n:"NUMBER", f:parse_NUMBER },
/*::[*/0x000F/*::]*/: { n:"LABEL", f:parse_LABEL },
/*::[*/0x0010/*::]*/: { n:"FORMULA", f:parse_FORMULA },
/*::[*/0x0018/*::]*/: { n:"TABLE", f:parsenoop },
/*::[*/0x0019/*::]*/: { n:"ORANGE", f:parsenoop },
/*::[*/0x001A/*::]*/: { n:"PRANGE", f:parsenoop },
/*::[*/0x001B/*::]*/: { n:"SRANGE", f:parsenoop },
/*::[*/0x001C/*::]*/: { n:"FRANGE", f:parsenoop },
/*::[*/0x001D/*::]*/: { n:"KRANGE1", f:parsenoop },
/*::[*/0x0020/*::]*/: { n:"HRANGE", f:parsenoop },
/*::[*/0x0023/*::]*/: { n:"KRANGE2", f:parsenoop },
/*::[*/0x0024/*::]*/: { n:"PROTEC", f:parsenoop },
/*::[*/0x0025/*::]*/: { n:"FOOTER", f:parsenoop },
/*::[*/0x0026/*::]*/: { n:"HEADER", f:parsenoop },
/*::[*/0x0027/*::]*/: { n:"SETUP", f:parsenoop },
/*::[*/0x0028/*::]*/: { n:"MARGINS", f:parsenoop },
/*::[*/0x0029/*::]*/: { n:"LABELFMT", f:parsenoop },
/*::[*/0x002A/*::]*/: { n:"TITLES", f:parsenoop },
/*::[*/0x002B/*::]*/: { n:"SHEETJS", f:parsenoop },
/*::[*/0x002D/*::]*/: { n:"GRAPH", f:parsenoop },
/*::[*/0x002E/*::]*/: { n:"NGRAPH", f:parsenoop },
/*::[*/0x002F/*::]*/: { n:"CALCCOUNT", f:parsenoop },
/*::[*/0x0030/*::]*/: { n:"UNFORMATTED", f:parsenoop },
/*::[*/0x0031/*::]*/: { n:"CURSORW12", f:parsenoop },
/*::[*/0x0032/*::]*/: { n:"WINDOW", f:parsenoop },
/*::[*/0x0018/*::]*/: { n:"TABLE" },
/*::[*/0x0019/*::]*/: { n:"ORANGE" },
/*::[*/0x001A/*::]*/: { n:"PRANGE" },
/*::[*/0x001B/*::]*/: { n:"SRANGE" },
/*::[*/0x001C/*::]*/: { n:"FRANGE" },
/*::[*/0x001D/*::]*/: { n:"KRANGE1" },
/*::[*/0x0020/*::]*/: { n:"HRANGE" },
/*::[*/0x0023/*::]*/: { n:"KRANGE2" },
/*::[*/0x0024/*::]*/: { n:"PROTEC" },
/*::[*/0x0025/*::]*/: { n:"FOOTER" },
/*::[*/0x0026/*::]*/: { n:"HEADER" },
/*::[*/0x0027/*::]*/: { n:"SETUP" },
/*::[*/0x0028/*::]*/: { n:"MARGINS" },
/*::[*/0x0029/*::]*/: { n:"LABELFMT" },
/*::[*/0x002A/*::]*/: { n:"TITLES" },
/*::[*/0x002B/*::]*/: { n:"SHEETJS" },
/*::[*/0x002D/*::]*/: { n:"GRAPH" },
/*::[*/0x002E/*::]*/: { n:"NGRAPH" },
/*::[*/0x002F/*::]*/: { n:"CALCCOUNT" },
/*::[*/0x0030/*::]*/: { n:"UNFORMATTED" },
/*::[*/0x0031/*::]*/: { n:"CURSORW12" },
/*::[*/0x0032/*::]*/: { n:"WINDOW" },
/*::[*/0x0033/*::]*/: { n:"STRING", f:parse_LABEL },
/*::[*/0x0037/*::]*/: { n:"PASSWORD", f:parsenoop },
/*::[*/0x0038/*::]*/: { n:"LOCKED", f:parsenoop },
/*::[*/0x003C/*::]*/: { n:"QUERY", f:parsenoop },
/*::[*/0x003D/*::]*/: { n:"QUERYNAME", f:parsenoop },
/*::[*/0x003E/*::]*/: { n:"PRINT", f:parsenoop },
/*::[*/0x003F/*::]*/: { n:"PRINTNAME", f:parsenoop },
/*::[*/0x0040/*::]*/: { n:"GRAPH2", f:parsenoop },
/*::[*/0x0041/*::]*/: { n:"GRAPHNAME", f:parsenoop },
/*::[*/0x0042/*::]*/: { n:"ZOOM", f:parsenoop },
/*::[*/0x0043/*::]*/: { n:"SYMSPLIT", f:parsenoop },
/*::[*/0x0044/*::]*/: { n:"NSROWS", f:parsenoop },
/*::[*/0x0045/*::]*/: { n:"NSCOLS", f:parsenoop },
/*::[*/0x0046/*::]*/: { n:"RULER", f:parsenoop },
/*::[*/0x0047/*::]*/: { n:"NNAME", f:parsenoop },
/*::[*/0x0048/*::]*/: { n:"ACOMM", f:parsenoop },
/*::[*/0x0049/*::]*/: { n:"AMACRO", f:parsenoop },
/*::[*/0x004A/*::]*/: { n:"PARSE", f:parsenoop },
/*::[*/0x0037/*::]*/: { n:"PASSWORD" },
/*::[*/0x0038/*::]*/: { n:"LOCKED" },
/*::[*/0x003C/*::]*/: { n:"QUERY" },
/*::[*/0x003D/*::]*/: { n:"QUERYNAME" },
/*::[*/0x003E/*::]*/: { n:"PRINT" },
/*::[*/0x003F/*::]*/: { n:"PRINTNAME" },
/*::[*/0x0040/*::]*/: { n:"GRAPH2" },
/*::[*/0x0041/*::]*/: { n:"GRAPHNAME" },
/*::[*/0x0042/*::]*/: { n:"ZOOM" },
/*::[*/0x0043/*::]*/: { n:"SYMSPLIT" },
/*::[*/0x0044/*::]*/: { n:"NSROWS" },
/*::[*/0x0045/*::]*/: { n:"NSCOLS" },
/*::[*/0x0046/*::]*/: { n:"RULER" },
/*::[*/0x0047/*::]*/: { n:"NNAME" },
/*::[*/0x0048/*::]*/: { n:"ACOMM" },
/*::[*/0x0049/*::]*/: { n:"AMACRO" },
/*::[*/0x004A/*::]*/: { n:"PARSE" },
/*::[*/0x00FF/*::]*/: { n:"", f:parsenoop }
};

var WK3Enum = {
/*::[*/0x0000/*::]*/: { n:"BOF", f:parsenoop },
/*::[*/0x0001/*::]*/: { n:"EOF", f:parsenoop },
/*::[*/0x0003/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0004/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0005/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0006/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0007/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0009/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x000a/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x000b/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x000c/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x000e/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x000f/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0010/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0011/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0012/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0013/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0015/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0000/*::]*/: { n:"BOF" },
/*::[*/0x0001/*::]*/: { n:"EOF" },
/*::[*/0x0003/*::]*/: { n:"??" },
/*::[*/0x0004/*::]*/: { n:"??" },
/*::[*/0x0005/*::]*/: { n:"??" },
/*::[*/0x0006/*::]*/: { n:"??" },
/*::[*/0x0007/*::]*/: { n:"??" },
/*::[*/0x0009/*::]*/: { n:"??" },
/*::[*/0x000a/*::]*/: { n:"??" },
/*::[*/0x000b/*::]*/: { n:"??" },
/*::[*/0x000c/*::]*/: { n:"??" },
/*::[*/0x000e/*::]*/: { n:"??" },
/*::[*/0x000f/*::]*/: { n:"??" },
/*::[*/0x0010/*::]*/: { n:"??" },
/*::[*/0x0011/*::]*/: { n:"??" },
/*::[*/0x0012/*::]*/: { n:"??" },
/*::[*/0x0013/*::]*/: { n:"??" },
/*::[*/0x0015/*::]*/: { n:"??" },
/*::[*/0x0016/*::]*/: { n:"LABEL16", f:parse_LABEL_16},
/*::[*/0x0017/*::]*/: { n:"NUMBER17", f:parse_NUMBER_17 },
/*::[*/0x0018/*::]*/: { n:"NUMBER18", f:parse_NUMBER_18 },
/*::[*/0x0019/*::]*/: { n:"FORMULA19", f:parse_FORMULA_19},
/*::[*/0x001a/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x001b/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x001c/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x001d/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x001e/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x001f/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x0021/*::]*/: { n:"??", f:parsenoop },
/*::[*/0x001a/*::]*/: { n:"??" },
/*::[*/0x001b/*::]*/: { n:"??" },
/*::[*/0x001c/*::]*/: { n:"??" },
/*::[*/0x001d/*::]*/: { n:"??" },
/*::[*/0x001e/*::]*/: { n:"??" },
/*::[*/0x001f/*::]*/: { n:"??" },
/*::[*/0x0021/*::]*/: { n:"??" },
/*::[*/0x0025/*::]*/: { n:"NUMBER25", f:parse_NUMBER_25 },
/*::[*/0x0027/*::]*/: { n:"NUMBER27", f:parse_NUMBER_27 },
/*::[*/0x0028/*::]*/: { n:"FORMULA28", f:parse_FORMULA_28 },
Expand Down
2 changes: 1 addition & 1 deletion bits/45_rtf.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var RTF = (function() {

function rtf_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
var o = opts || {};
var ws/*:Worksheet*/ = ({}/*:any*/);
var ws/*:Worksheet*/ = o.dense ? ([]/*:any*/) : ({}/*:any*/);
var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:0}}/*:any*/);

// TODO: parse
Expand Down
3 changes: 2 additions & 1 deletion bits/48_stybin.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,10 @@ function write_BrtFill(fill, o) {

/* [MS-XLSB] 2.4.816 BrtXF */
function parse_BrtXF(data, length/*:number*/) {
var tgt = data.l + length;
var ixfeParent = data.read_shift(2);
var ifmt = data.read_shift(2);
parsenoop(data, length-4);
data.l = tgt;
return {ixfe:ixfeParent, numFmtId:ifmt };
}
function write_BrtXF(data, ixfeP, o) {
Expand Down
8 changes: 4 additions & 4 deletions bits/60_macrovba.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ RELS.DS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/d
RELS.MS = "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet";

/* macro and dialog sheet stubs */
function parse_ds_bin(data/*:any*/, opts, rels, wb, themes, styles)/*:Worksheet*/ { return {'!type':'dialog'}; }
function parse_ds_xml(data/*:any*/, opts, rels, wb, themes, styles)/*:Worksheet*/ { return {'!type':'dialog'}; }
function parse_ms_bin(data/*:any*/, opts, rels, wb, themes, styles)/*:Worksheet*/ { return {'!type':'macro'}; }
function parse_ms_xml(data/*:any*/, opts, rels, wb, themes, styles)/*:Worksheet*/ { return {'!type':'macro'}; }
function parse_ds_bin(data/*:any*/, opts, idx/*:number*/, rels, wb, themes, styles)/*:Worksheet*/ { return {'!type':'dialog'}; }
function parse_ds_xml(data/*:any*/, opts, idx/*:number*/, rels, wb, themes, styles)/*:Worksheet*/ { return {'!type':'dialog'}; }
function parse_ms_bin(data/*:any*/, opts, idx/*:number*/, rels, wb, themes, styles)/*:Worksheet*/ { return {'!type':'macro'}; }
function parse_ms_xml(data/*:any*/, opts, idx/*:number*/, rels, wb, themes, styles)/*:Worksheet*/ { return {'!type':'macro'}; }
3 changes: 1 addition & 2 deletions bits/62_fxls.js
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,6 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
break;
case 'PtgArea3d': /* 2.5.198.28 TODO */
type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; r = f[1][2];
//sname = (supbooks && supbooks[1] ? supbooks[1][ixti+1] : "**MISSING**");
sname = get_ixti(supbooks, ixti, opts);
stack.push(sname + "!" + encode_range_xls((r/*:any*/), opts));
break;
Expand Down Expand Up @@ -923,7 +922,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
stack.push('#REF!'); break;

case 'PtgExp': /* 2.5.198.58 TODO */
c = {c:f[1][1],r:f[1][0]};
c = {c:(f[1][1]/*:any*/),r:(f[1][0]/*:any*/)};
var q = ({c: cell.c, r:cell.r}/*:any*/);
if(supbooks.sharedf[encode_cell(c)]) {
var parsedf = (supbooks.sharedf[encode_cell(c)]);
Expand Down
Loading

0 comments on commit 547fba5

Please sign in to comment.