SYLK process 1904 dates (fixes #1545 h/t @Slayess)

This commit is contained in:
SheetJS 2022-04-27 04:26:35 -04:00
parent eee39946e3
commit 87e826f299
9 changed files with 186 additions and 84 deletions

@ -407,6 +407,7 @@ var SYLK = /*#__PURE__*/(function() {
var next_cell_format/*:string|null*/ = null;
var sht = {}, rowinfo/*:Array<RowInfo>*/ = [], colinfo/*:Array<ColInfo>*/ = [], cw/*:Array<string>*/ = [];
var Mval = 0, j;
var wb = { Workbook: { WBProps: {} } };
if(+opts.codepage >= 0) set_cp(+opts.codepage);
for (; ri !== records.length; ++ri) {
Mval = 0;
@ -417,7 +418,14 @@ var SYLK = /*#__PURE__*/(function() {
case 'ID': break; /* header */
case 'E': break; /* EOF */
case 'B': break; /* dimensions */
case 'O': break; /* options? */
case 'O': /* workbook options */
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'V': {
var d1904 = parseInt(record[rj].slice(1), 10);
// NOTE: it is technically an error if d1904 >= 5 or < 0
if(d1904 >= 1 && d1904 <= 4) wb.Workbook.WBProps.date1904 = true;
} break;
} break;
case 'W': break; /* window? */
case 'P':
if(record[1].charAt(0) == 'P')
@ -427,9 +435,9 @@ var SYLK = /*#__PURE__*/(function() {
var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'A': break; // TODO: comment
case 'X': C = parseInt(record[rj].slice(1))-1; C_seen_X = true; break;
case 'X': C = parseInt(record[rj].slice(1), 10)-1; C_seen_X = true; break;
case 'Y':
R = parseInt(record[rj].slice(1))-1; if(!C_seen_X) C = 0;
R = parseInt(record[rj].slice(1), 10)-1; if(!C_seen_X) C = 0;
for(j = arr.length; j <= R; ++j) arr[j] = [];
break;
case 'K':
@ -439,7 +447,7 @@ var SYLK = /*#__PURE__*/(function() {
else if(val === 'FALSE') val = false;
else if(!isNaN(fuzzynum(val))) {
val = fuzzynum(val);
if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(val);
if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(wb.Workbook.WBProps.date1904 ? val + 1462 : val);
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
@ -456,8 +464,8 @@ var SYLK = /*#__PURE__*/(function() {
arr[R][C] = [arr[R][C], "S5S"];
break;
case 'G': break; // unknown
case 'R': _R = parseInt(record[rj].slice(1))-1; break;
case 'C': _C = parseInt(record[rj].slice(1))-1; break;
case 'R': _R = parseInt(record[rj].slice(1), 10)-1; break;
case 'C': _C = parseInt(record[rj].slice(1), 10)-1; break;
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
}
if(C_seen_K) {
@ -475,16 +483,16 @@ var SYLK = /*#__PURE__*/(function() {
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; ++F_seen; break;
case 'X': C = parseInt(record[rj].slice(1), 10)-1; ++F_seen; break;
case 'Y':
R = parseInt(record[rj].slice(1))-1; /*C = 0;*/
R = parseInt(record[rj].slice(1), 10)-1; /*C = 0;*/
for(j = arr.length; j <= R; ++j) arr[j] = [];
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'M': Mval = parseInt(record[rj].slice(1), 10) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
next_cell_format = formats[parseInt(record[rj].slice(1), 10)];
break;
case 'S': break; /* cell style */
case 'D': break; /* column */
@ -496,11 +504,11 @@ var SYLK = /*#__PURE__*/(function() {
colinfo[j-1] = Mval === 0 ? {hidden:true}: {wch:Mval}; process_col(colinfo[j-1]);
} break;
case 'C': /* default column format */
C = parseInt(record[rj].slice(1))-1;
C = parseInt(record[rj].slice(1), 10)-1;
if(!colinfo[C]) colinfo[C] = {};
break;
case 'R': /* row properties */
R = parseInt(record[rj].slice(1))-1;
R = parseInt(record[rj].slice(1), 10)-1;
if(!rowinfo[R]) rowinfo[R] = {};
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
else if(Mval === 0) rowinfo[R].hidden = true;
@ -514,19 +522,19 @@ var SYLK = /*#__PURE__*/(function() {
if(rowinfo.length > 0) sht['!rows'] = rowinfo;
if(colinfo.length > 0) sht['!cols'] = colinfo;
if(opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
return [arr, sht];
return [arr, sht, wb];
}
function sylk_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
function sylk_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ {
var aoasht = sylk_to_aoa(d, opts);
var aoa = aoasht[0], ws = aoasht[1];
var aoa = aoasht[0], ws = aoasht[1], wb = aoasht[2];
var o = aoa_to_sheet(aoa, opts);
keys(ws).forEach(function(k) { o[k] = ws[k]; });
return o;
var outwb = sheet_to_workbook(o, opts);
keys(wb).forEach(function(k) { outwb[k] = wb[k]; });
return outwb;
}
function sylk_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(sylk_to_sheet(d, opts), opts); }
function write_ws_cell_sylk(cell/*:Cell*/, ws/*:Worksheet*/, R/*:number*/, C/*:number*//*::, opts*/)/*:string*/ {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
@ -565,7 +573,7 @@ var SYLK = /*#__PURE__*/(function() {
}
function sheet_to_sylk(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
var preamble/*:Array<string>*/ = ["ID;PWXL;N;E"], o/*:Array<string>*/ = [];
var preamble/*:Array<string>*/ = ["ID;PSheetJS;N;E"], o/*:Array<string>*/ = [];
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
var dense = Array.isArray(ws);
var RS = "\r\n";
@ -589,7 +597,6 @@ var SYLK = /*#__PURE__*/(function() {
return {
to_workbook: sylk_to_workbook,
to_sheet: sylk_to_sheet,
from_sheet: sheet_to_sylk
};
})();

@ -895,7 +895,7 @@ var WK_ = /*#__PURE__*/(function() {
type = p.read_shift(1);
sname = cnt == 0 ? "" : p.read_shift(cnt, 'cstr');
}
if(!sname) sname = XLSX.utils.encode_col(sidx);
if(!sname) sname = encode_col(sidx);
/* TODO: backfill empty sheets */
} break;
case 0x0602: { /* EOS */

13
test.js

@ -2183,6 +2183,19 @@ describe('sylk', function() {
}
} : null);
});
describe('date system', function() {
function make_slk(d1904) { return "ID;PSheetJS\nP;Pd\\/m\\/yy\nP;Pd\\/m\\/yyyy\n" + (d1904 != null ? "O;D;V" + d1904 : "") + "\nF;P0;FG0G;X1;Y1\nC;K1\nE"; }
it('should default to 1900', function() {
assert.equal(get_cell(X.read(make_slk(), {type: "binary"}).Sheets.Sheet1, "A1").v, 1);
assert(get_cell(X.read(make_slk(), {type: "binary", cellDates: true}).Sheets.Sheet1, "A1").v.getFullYear() < 1902);
assert.equal(get_cell(X.read(make_slk(5), {type: "binary"}).Sheets.Sheet1, "A1").v, 1);
assert(get_cell(X.read(make_slk(5), {type: "binary", cellDates: true}).Sheets.Sheet1, "A1").v.getFullYear() < 1902);
});
it('should use 1904 when specified', function() {
assert(get_cell(X.read(make_slk(1), {type: "binary", cellDates: true}).Sheets.Sheet1, "A1").v.getFullYear() > 1902);
assert(get_cell(X.read(make_slk(4), {type: "binary", cellDates: true}).Sheets.Sheet1, "A1").v.getFullYear() > 1902);
});
});
});
(typeof Uint8Array !== "undefined" ? describe : describe.skip)('numbers', function() {

13
test.ts

@ -2115,6 +2115,19 @@ Deno.test('sylk', async function(t) {
}
});
});
await t.step('date system', async function(t){
function make_slk(d1904?: number) { return "ID;PSheetJS\nP;Pd\\/m\\/yy\nP;Pd\\/m\\/yyyy\n" + (d1904 != null ? "O;D;V" + d1904 : "") + "\nF;P0;FG0G;X1;Y1\nC;K1\nE"; }
await t.step('should default to 1900', async function(t) {
assert.equal(get_cell(X.read(make_slk(), {type: "binary"}).Sheets["Sheet1"], "A1").v, 1);
assert.assert(get_cell(X.read(make_slk(), {type: "binary", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() < 1902);
assert.equal(get_cell(X.read(make_slk(5), {type: "binary"}).Sheets["Sheet1"], "A1").v, 1);
assert.assert(get_cell(X.read(make_slk(5), {type: "binary", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() < 1902);
});
await t.step('should use 1904 when specified', async function(t) {
assert.assert(get_cell(X.read(make_slk(1), {type: "binary", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() > 1902);
assert.assert(get_cell(X.read(make_slk(4), {type: "binary", cellDates: true}).Sheets["Sheet1"], "A1").v.getFullYear() > 1902);
});
});
});
Deno.test('numbers', async function(t) {

13
tests/core.js generated

@ -2183,6 +2183,19 @@ describe('sylk', function() {
}
} : null);
});
describe('date system', function() {
function make_slk(d1904) { return "ID;PSheetJS\nP;Pd\\/m\\/yy\nP;Pd\\/m\\/yyyy\n" + (d1904 != null ? "O;D;V" + d1904 : "") + "\nF;P0;FG0G;X1;Y1\nC;K1\nE"; }
it('should default to 1900', function() {
assert.equal(get_cell(X.read(make_slk(), {type: "binary"}).Sheets.Sheet1, "A1").v, 1);
assert(get_cell(X.read(make_slk(), {type: "binary", cellDates: true}).Sheets.Sheet1, "A1").v.getFullYear() < 1902);
assert.equal(get_cell(X.read(make_slk(5), {type: "binary"}).Sheets.Sheet1, "A1").v, 1);
assert(get_cell(X.read(make_slk(5), {type: "binary", cellDates: true}).Sheets.Sheet1, "A1").v.getFullYear() < 1902);
});
it('should use 1904 when specified', function() {
assert(get_cell(X.read(make_slk(1), {type: "binary", cellDates: true}).Sheets.Sheet1, "A1").v.getFullYear() > 1902);
assert(get_cell(X.read(make_slk(4), {type: "binary", cellDates: true}).Sheets.Sheet1, "A1").v.getFullYear() > 1902);
});
});
});
(typeof Uint8Array !== "undefined" ? describe : describe.skip)('numbers', function() {

35
tests/fixtures.js generated

File diff suppressed because one or more lines are too long

@ -7958,6 +7958,7 @@ var SYLK = /*#__PURE__*/(function() {
var next_cell_format/*:string|null*/ = null;
var sht = {}, rowinfo/*:Array<RowInfo>*/ = [], colinfo/*:Array<ColInfo>*/ = [], cw/*:Array<string>*/ = [];
var Mval = 0, j;
var wb = { Workbook: { WBProps: {} } };
if(+opts.codepage >= 0) set_cp(+opts.codepage);
for (; ri !== records.length; ++ri) {
Mval = 0;
@ -7968,7 +7969,14 @@ var SYLK = /*#__PURE__*/(function() {
case 'ID': break; /* header */
case 'E': break; /* EOF */
case 'B': break; /* dimensions */
case 'O': break; /* options? */
case 'O': /* workbook options */
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'V': {
var d1904 = parseInt(record[rj].slice(1), 10);
// NOTE: it is technically an error if d1904 >= 5 or < 0
if(d1904 >= 1 && d1904 <= 4) wb.Workbook.WBProps.date1904 = true;
} break;
} break;
case 'W': break; /* window? */
case 'P':
if(record[1].charAt(0) == 'P')
@ -7978,9 +7986,9 @@ var SYLK = /*#__PURE__*/(function() {
var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'A': break; // TODO: comment
case 'X': C = parseInt(record[rj].slice(1))-1; C_seen_X = true; break;
case 'X': C = parseInt(record[rj].slice(1), 10)-1; C_seen_X = true; break;
case 'Y':
R = parseInt(record[rj].slice(1))-1; if(!C_seen_X) C = 0;
R = parseInt(record[rj].slice(1), 10)-1; if(!C_seen_X) C = 0;
for(j = arr.length; j <= R; ++j) arr[j] = [];
break;
case 'K':
@ -7990,7 +7998,7 @@ var SYLK = /*#__PURE__*/(function() {
else if(val === 'FALSE') val = false;
else if(!isNaN(fuzzynum(val))) {
val = fuzzynum(val);
if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(val);
if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(wb.Workbook.WBProps.date1904 ? val + 1462 : val);
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
@ -8007,8 +8015,8 @@ var SYLK = /*#__PURE__*/(function() {
arr[R][C] = [arr[R][C], "S5S"];
break;
case 'G': break; // unknown
case 'R': _R = parseInt(record[rj].slice(1))-1; break;
case 'C': _C = parseInt(record[rj].slice(1))-1; break;
case 'R': _R = parseInt(record[rj].slice(1), 10)-1; break;
case 'C': _C = parseInt(record[rj].slice(1), 10)-1; break;
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
}
if(C_seen_K) {
@ -8026,16 +8034,16 @@ var SYLK = /*#__PURE__*/(function() {
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; ++F_seen; break;
case 'X': C = parseInt(record[rj].slice(1), 10)-1; ++F_seen; break;
case 'Y':
R = parseInt(record[rj].slice(1))-1; /*C = 0;*/
R = parseInt(record[rj].slice(1), 10)-1; /*C = 0;*/
for(j = arr.length; j <= R; ++j) arr[j] = [];
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'M': Mval = parseInt(record[rj].slice(1), 10) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
next_cell_format = formats[parseInt(record[rj].slice(1), 10)];
break;
case 'S': break; /* cell style */
case 'D': break; /* column */
@ -8047,11 +8055,11 @@ var SYLK = /*#__PURE__*/(function() {
colinfo[j-1] = Mval === 0 ? {hidden:true}: {wch:Mval}; process_col(colinfo[j-1]);
} break;
case 'C': /* default column format */
C = parseInt(record[rj].slice(1))-1;
C = parseInt(record[rj].slice(1), 10)-1;
if(!colinfo[C]) colinfo[C] = {};
break;
case 'R': /* row properties */
R = parseInt(record[rj].slice(1))-1;
R = parseInt(record[rj].slice(1), 10)-1;
if(!rowinfo[R]) rowinfo[R] = {};
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
else if(Mval === 0) rowinfo[R].hidden = true;
@ -8065,19 +8073,19 @@ var SYLK = /*#__PURE__*/(function() {
if(rowinfo.length > 0) sht['!rows'] = rowinfo;
if(colinfo.length > 0) sht['!cols'] = colinfo;
if(opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
return [arr, sht];
return [arr, sht, wb];
}
function sylk_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
function sylk_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ {
var aoasht = sylk_to_aoa(d, opts);
var aoa = aoasht[0], ws = aoasht[1];
var aoa = aoasht[0], ws = aoasht[1], wb = aoasht[2];
var o = aoa_to_sheet(aoa, opts);
keys(ws).forEach(function(k) { o[k] = ws[k]; });
return o;
var outwb = sheet_to_workbook(o, opts);
keys(wb).forEach(function(k) { outwb[k] = wb[k]; });
return outwb;
}
function sylk_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(sylk_to_sheet(d, opts), opts); }
function write_ws_cell_sylk(cell/*:Cell*/, ws/*:Worksheet*/, R/*:number*/, C/*:number*//*::, opts*/)/*:string*/ {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
@ -8116,7 +8124,7 @@ var SYLK = /*#__PURE__*/(function() {
}
function sheet_to_sylk(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
var preamble/*:Array<string>*/ = ["ID;PWXL;N;E"], o/*:Array<string>*/ = [];
var preamble/*:Array<string>*/ = ["ID;PSheetJS;N;E"], o/*:Array<string>*/ = [];
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
var dense = Array.isArray(ws);
var RS = "\r\n";
@ -8140,7 +8148,6 @@ var SYLK = /*#__PURE__*/(function() {
return {
to_workbook: sylk_to_workbook,
to_sheet: sylk_to_sheet,
from_sheet: sheet_to_sylk
};
})();
@ -9474,7 +9481,7 @@ var WK_ = /*#__PURE__*/(function() {
type = p.read_shift(1);
sname = cnt == 0 ? "" : p.read_shift(cnt, 'cstr');
}
if(!sname) sname = XLSX.utils.encode_col(sidx);
if(!sname) sname = encode_col(sidx);
/* TODO: backfill empty sheets */
} break;
case 0x0602: { /* EOS */

49
xlsx.js generated

@ -7868,6 +7868,7 @@ var SYLK = (function() {
var next_cell_format = null;
var sht = {}, rowinfo = [], colinfo = [], cw = [];
var Mval = 0, j;
var wb = { Workbook: { WBProps: {} } };
if(+opts.codepage >= 0) set_cp(+opts.codepage);
for (; ri !== records.length; ++ri) {
Mval = 0;
@ -7878,7 +7879,14 @@ var SYLK = (function() {
case 'ID': break; /* header */
case 'E': break; /* EOF */
case 'B': break; /* dimensions */
case 'O': break; /* options? */
case 'O': /* workbook options */
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'V': {
var d1904 = parseInt(record[rj].slice(1), 10);
// NOTE: it is technically an error if d1904 >= 5 or < 0
if(d1904 >= 1 && d1904 <= 4) wb.Workbook.WBProps.date1904 = true;
} break;
} break;
case 'W': break; /* window? */
case 'P':
if(record[1].charAt(0) == 'P')
@ -7888,9 +7896,9 @@ var SYLK = (function() {
var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'A': break; // TODO: comment
case 'X': C = parseInt(record[rj].slice(1))-1; C_seen_X = true; break;
case 'X': C = parseInt(record[rj].slice(1), 10)-1; C_seen_X = true; break;
case 'Y':
R = parseInt(record[rj].slice(1))-1; if(!C_seen_X) C = 0;
R = parseInt(record[rj].slice(1), 10)-1; if(!C_seen_X) C = 0;
for(j = arr.length; j <= R; ++j) arr[j] = [];
break;
case 'K':
@ -7900,7 +7908,7 @@ var SYLK = (function() {
else if(val === 'FALSE') val = false;
else if(!isNaN(fuzzynum(val))) {
val = fuzzynum(val);
if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(val);
if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(wb.Workbook.WBProps.date1904 ? val + 1462 : val);
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
@ -7917,8 +7925,8 @@ var SYLK = (function() {
arr[R][C] = [arr[R][C], "S5S"];
break;
case 'G': break; // unknown
case 'R': _R = parseInt(record[rj].slice(1))-1; break;
case 'C': _C = parseInt(record[rj].slice(1))-1; break;
case 'R': _R = parseInt(record[rj].slice(1), 10)-1; break;
case 'C': _C = parseInt(record[rj].slice(1), 10)-1; break;
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
}
if(C_seen_K) {
@ -7936,16 +7944,16 @@ var SYLK = (function() {
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; ++F_seen; break;
case 'X': C = parseInt(record[rj].slice(1), 10)-1; ++F_seen; break;
case 'Y':
R = parseInt(record[rj].slice(1))-1; /*C = 0;*/
R = parseInt(record[rj].slice(1), 10)-1; /*C = 0;*/
for(j = arr.length; j <= R; ++j) arr[j] = [];
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'M': Mval = parseInt(record[rj].slice(1), 10) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
next_cell_format = formats[parseInt(record[rj].slice(1), 10)];
break;
case 'S': break; /* cell style */
case 'D': break; /* column */
@ -7957,11 +7965,11 @@ var SYLK = (function() {
colinfo[j-1] = Mval === 0 ? {hidden:true}: {wch:Mval}; process_col(colinfo[j-1]);
} break;
case 'C': /* default column format */
C = parseInt(record[rj].slice(1))-1;
C = parseInt(record[rj].slice(1), 10)-1;
if(!colinfo[C]) colinfo[C] = {};
break;
case 'R': /* row properties */
R = parseInt(record[rj].slice(1))-1;
R = parseInt(record[rj].slice(1), 10)-1;
if(!rowinfo[R]) rowinfo[R] = {};
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
else if(Mval === 0) rowinfo[R].hidden = true;
@ -7975,19 +7983,19 @@ var SYLK = (function() {
if(rowinfo.length > 0) sht['!rows'] = rowinfo;
if(colinfo.length > 0) sht['!cols'] = colinfo;
if(opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
return [arr, sht];
return [arr, sht, wb];
}
function sylk_to_sheet(d, opts) {
function sylk_to_workbook(d, opts) {
var aoasht = sylk_to_aoa(d, opts);
var aoa = aoasht[0], ws = aoasht[1];
var aoa = aoasht[0], ws = aoasht[1], wb = aoasht[2];
var o = aoa_to_sheet(aoa, opts);
keys(ws).forEach(function(k) { o[k] = ws[k]; });
return o;
var outwb = sheet_to_workbook(o, opts);
keys(wb).forEach(function(k) { outwb[k] = wb[k]; });
return outwb;
}
function sylk_to_workbook(d, opts) { return sheet_to_workbook(sylk_to_sheet(d, opts), opts); }
function write_ws_cell_sylk(cell, ws, R, C) {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
@ -8026,7 +8034,7 @@ var SYLK = (function() {
}
function sheet_to_sylk(ws, opts) {
var preamble = ["ID;PWXL;N;E"], o = [];
var preamble = ["ID;PSheetJS;N;E"], o = [];
var r = safe_decode_range(ws['!ref']), cell;
var dense = Array.isArray(ws);
var RS = "\r\n";
@ -8050,7 +8058,6 @@ var SYLK = (function() {
return {
to_workbook: sylk_to_workbook,
to_sheet: sylk_to_sheet,
from_sheet: sheet_to_sylk
};
})();
@ -9384,7 +9391,7 @@ var WK_ = (function() {
type = p.read_shift(1);
sname = cnt == 0 ? "" : p.read_shift(cnt, 'cstr');
}
if(!sname) sname = XLSX.utils.encode_col(sidx);
if(!sname) sname = encode_col(sidx);
/* TODO: backfill empty sheets */
} break;
case 0x0602: { /* EOS */

49
xlsx.mjs generated

@ -7946,6 +7946,7 @@ var SYLK = /*#__PURE__*/(function() {
var next_cell_format/*:string|null*/ = null;
var sht = {}, rowinfo/*:Array<RowInfo>*/ = [], colinfo/*:Array<ColInfo>*/ = [], cw/*:Array<string>*/ = [];
var Mval = 0, j;
var wb = { Workbook: { WBProps: {} } };
if(+opts.codepage >= 0) set_cp(+opts.codepage);
for (; ri !== records.length; ++ri) {
Mval = 0;
@ -7956,7 +7957,14 @@ var SYLK = /*#__PURE__*/(function() {
case 'ID': break; /* header */
case 'E': break; /* EOF */
case 'B': break; /* dimensions */
case 'O': break; /* options? */
case 'O': /* workbook options */
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'V': {
var d1904 = parseInt(record[rj].slice(1), 10);
// NOTE: it is technically an error if d1904 >= 5 or < 0
if(d1904 >= 1 && d1904 <= 4) wb.Workbook.WBProps.date1904 = true;
} break;
} break;
case 'W': break; /* window? */
case 'P':
if(record[1].charAt(0) == 'P')
@ -7966,9 +7974,9 @@ var SYLK = /*#__PURE__*/(function() {
var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'A': break; // TODO: comment
case 'X': C = parseInt(record[rj].slice(1))-1; C_seen_X = true; break;
case 'X': C = parseInt(record[rj].slice(1), 10)-1; C_seen_X = true; break;
case 'Y':
R = parseInt(record[rj].slice(1))-1; if(!C_seen_X) C = 0;
R = parseInt(record[rj].slice(1), 10)-1; if(!C_seen_X) C = 0;
for(j = arr.length; j <= R; ++j) arr[j] = [];
break;
case 'K':
@ -7978,7 +7986,7 @@ var SYLK = /*#__PURE__*/(function() {
else if(val === 'FALSE') val = false;
else if(!isNaN(fuzzynum(val))) {
val = fuzzynum(val);
if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(val);
if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(wb.Workbook.WBProps.date1904 ? val + 1462 : val);
} else if(!isNaN(fuzzydate(val).getDate())) {
val = parseDate(val);
}
@ -7995,8 +8003,8 @@ var SYLK = /*#__PURE__*/(function() {
arr[R][C] = [arr[R][C], "S5S"];
break;
case 'G': break; // unknown
case 'R': _R = parseInt(record[rj].slice(1))-1; break;
case 'C': _C = parseInt(record[rj].slice(1))-1; break;
case 'R': _R = parseInt(record[rj].slice(1), 10)-1; break;
case 'C': _C = parseInt(record[rj].slice(1), 10)-1; break;
default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
}
if(C_seen_K) {
@ -8014,16 +8022,16 @@ var SYLK = /*#__PURE__*/(function() {
case 'F':
var F_seen = 0;
for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
case 'X': C = parseInt(record[rj].slice(1))-1; ++F_seen; break;
case 'X': C = parseInt(record[rj].slice(1), 10)-1; ++F_seen; break;
case 'Y':
R = parseInt(record[rj].slice(1))-1; /*C = 0;*/
R = parseInt(record[rj].slice(1), 10)-1; /*C = 0;*/
for(j = arr.length; j <= R; ++j) arr[j] = [];
break;
case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
case 'M': Mval = parseInt(record[rj].slice(1), 10) / 20; break;
case 'F': break; /* ??? */
case 'G': break; /* hide grid */
case 'P':
next_cell_format = formats[parseInt(record[rj].slice(1))];
next_cell_format = formats[parseInt(record[rj].slice(1), 10)];
break;
case 'S': break; /* cell style */
case 'D': break; /* column */
@ -8035,11 +8043,11 @@ var SYLK = /*#__PURE__*/(function() {
colinfo[j-1] = Mval === 0 ? {hidden:true}: {wch:Mval}; process_col(colinfo[j-1]);
} break;
case 'C': /* default column format */
C = parseInt(record[rj].slice(1))-1;
C = parseInt(record[rj].slice(1), 10)-1;
if(!colinfo[C]) colinfo[C] = {};
break;
case 'R': /* row properties */
R = parseInt(record[rj].slice(1))-1;
R = parseInt(record[rj].slice(1), 10)-1;
if(!rowinfo[R]) rowinfo[R] = {};
if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
else if(Mval === 0) rowinfo[R].hidden = true;
@ -8053,19 +8061,19 @@ var SYLK = /*#__PURE__*/(function() {
if(rowinfo.length > 0) sht['!rows'] = rowinfo;
if(colinfo.length > 0) sht['!cols'] = colinfo;
if(opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
return [arr, sht];
return [arr, sht, wb];
}
function sylk_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
function sylk_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ {
var aoasht = sylk_to_aoa(d, opts);
var aoa = aoasht[0], ws = aoasht[1];
var aoa = aoasht[0], ws = aoasht[1], wb = aoasht[2];
var o = aoa_to_sheet(aoa, opts);
keys(ws).forEach(function(k) { o[k] = ws[k]; });
return o;
var outwb = sheet_to_workbook(o, opts);
keys(wb).forEach(function(k) { outwb[k] = wb[k]; });
return outwb;
}
function sylk_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(sylk_to_sheet(d, opts), opts); }
function write_ws_cell_sylk(cell/*:Cell*/, ws/*:Worksheet*/, R/*:number*/, C/*:number*//*::, opts*/)/*:string*/ {
var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
switch(cell.t) {
@ -8104,7 +8112,7 @@ var SYLK = /*#__PURE__*/(function() {
}
function sheet_to_sylk(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
var preamble/*:Array<string>*/ = ["ID;PWXL;N;E"], o/*:Array<string>*/ = [];
var preamble/*:Array<string>*/ = ["ID;PSheetJS;N;E"], o/*:Array<string>*/ = [];
var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
var dense = Array.isArray(ws);
var RS = "\r\n";
@ -8128,7 +8136,6 @@ var SYLK = /*#__PURE__*/(function() {
return {
to_workbook: sylk_to_workbook,
to_sheet: sylk_to_sheet,
from_sheet: sheet_to_sylk
};
})();
@ -9462,7 +9469,7 @@ var WK_ = /*#__PURE__*/(function() {
type = p.read_shift(1);
sname = cnt == 0 ? "" : p.read_shift(cnt, 'cstr');
}
if(!sname) sname = XLSX.utils.encode_col(sidx);
if(!sname) sname = encode_col(sidx);
/* TODO: backfill empty sheets */
} break;
case 0x0602: { /* EOS */