NUMBERS write to max column (ALL)
This commit is contained in:
parent
9ca1243448
commit
19e0f8f358
@ -4031,6 +4031,7 @@ range limits will be silently truncated:
|
||||
|:------------------------------------------|:-----------|---------:|---------:|
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | XFD1048576 | 16384 | 1048576 |
|
||||
| Numbers 12.0 (NUMBERS) | ALL1000000 | 1000 | 1000000 |
|
||||
| Excel 97-2004 (XLS BIFF8) | IV65536 | 256 | 65536 |
|
||||
| Excel 5.0/95 (XLS BIFF5) | IV16384 | 256 | 16384 |
|
||||
| Excel 4.0 (XLS BIFF4) | IV16384 | 256 | 16384 |
|
||||
|
@ -133,7 +133,7 @@ return CRC32;
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = /*#__PURE__*/(function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '1.2.1';
|
||||
exports.version = '1.2.2';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -433,7 +433,7 @@ function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/,
|
||||
if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
|
||||
fat_addrs.push(q);
|
||||
}
|
||||
sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
|
||||
if(cnt >= 1) sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -609,7 +609,9 @@ function rebuild_cfb(cfb/*:CFBContainer*/, f/*:?boolean*/)/*:void*/ {
|
||||
for(i = 0; i < data.length; ++i) {
|
||||
var dad = dirname(data[i][0]);
|
||||
s = fullPaths[dad];
|
||||
if(!s) {
|
||||
while(!s) {
|
||||
while(dirname(dad) && !fullPaths[dirname(dad)]) dad = dirname(dad);
|
||||
|
||||
data.push([dad, ({
|
||||
name: filename(dad).replace("/",""),
|
||||
type: 1,
|
||||
@ -617,8 +619,12 @@ function rebuild_cfb(cfb/*:CFBContainer*/, f/*:?boolean*/)/*:void*/ {
|
||||
ct: now, mt: now,
|
||||
content: null
|
||||
}/*:any*/)]);
|
||||
|
||||
// Add name to set
|
||||
fullPaths[dad] = true;
|
||||
|
||||
dad = dirname(data[i][0]);
|
||||
s = fullPaths[dad];
|
||||
}
|
||||
}
|
||||
|
||||
@ -666,7 +672,6 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|strin
|
||||
for(var i = 0; i < cfb.FileIndex.length; ++i) {
|
||||
var file = cfb.FileIndex[i];
|
||||
if(!file.content) continue;
|
||||
/*:: if(file.content == null) throw new Error("unreachable"); */
|
||||
var flen = file.content.length;
|
||||
if(flen > 0){
|
||||
if(flen < 0x1000) mini_size += (flen + 0x3F) >> 6;
|
||||
@ -757,6 +762,10 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|strin
|
||||
file = cfb.FileIndex[i];
|
||||
if(i === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;
|
||||
var _nm/*:string*/ = (i === 0 && _opts.root) || file.name;
|
||||
if(_nm.length > 32) {
|
||||
console.error("Name " + _nm + " will be truncated to " + _nm.slice(0,32));
|
||||
_nm = _nm.slice(0, 32);
|
||||
}
|
||||
flen = 2*(_nm.length+1);
|
||||
o.write_shift(64, _nm, "utf16le");
|
||||
o.write_shift(2, flen);
|
||||
@ -1395,6 +1404,7 @@ function parse_zip(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/
|
||||
parse_local_file(blob, csz, usz, o, EF);
|
||||
blob.l = L;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
@ -419,10 +419,6 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
{
|
||||
if (ridx > -1)
|
||||
ret = { t: "s", v: rsst[ridx] };
|
||||
else if (sidx > -1)
|
||||
ret = { t: "s", v: sst[sidx] };
|
||||
else if (!isNaN(ieee))
|
||||
ret = { t: "n", v: ieee };
|
||||
else
|
||||
throw new Error("Unsupported cell type ".concat(buf.slice(0, 4)));
|
||||
}
|
||||
@ -815,24 +811,32 @@ function parse_numbers_iwa(cfb) {
|
||||
throw new Error("Cannot find Document root");
|
||||
return parse_TN_DocumentArchive(M, docroot);
|
||||
}
|
||||
function write_tile_row(tri, data, SST) {
|
||||
var _a, _b, _c, _d;
|
||||
function write_tile_row(tri, data, SST, wide) {
|
||||
var _a, _b;
|
||||
if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0]))
|
||||
throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if (wide_offsets)
|
||||
throw "Math only works with normal offsets";
|
||||
var cnt = 0;
|
||||
if (tri[7][0].data.length < 2 * data.length) {
|
||||
var new_7 = new Uint8Array(2 * data.length);
|
||||
new_7.set(tri[7][0].data);
|
||||
tri[7][0].data = new_7;
|
||||
}
|
||||
if (tri[4][0].data.length < 2 * data.length) {
|
||||
var new_4 = new Uint8Array(2 * data.length);
|
||||
new_4.set(tri[4][0].data);
|
||||
tri[4][0].data = new_4;
|
||||
}
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage = [];
|
||||
var width = wide ? 4 : 1;
|
||||
for (var C = 0; C < data.length; ++C) {
|
||||
if (data[C] == null) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535);
|
||||
continue;
|
||||
}
|
||||
dv.setUint16(C * 2, last_offset, true);
|
||||
_dv.setUint16(C * 2, _last_offset, true);
|
||||
dv.setUint16(C * 2, last_offset / width, true);
|
||||
_dv.setUint16(C * 2, _last_offset / width, true);
|
||||
var celload, _celload;
|
||||
switch (typeof data[C]) {
|
||||
case "string":
|
||||
@ -852,17 +856,21 @@ function write_tile_row(tri, data, SST) {
|
||||
}
|
||||
cell_storage.push(celload);
|
||||
last_offset += celload.length;
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
{
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
tri[5][0].data = write_varint49(5);
|
||||
for (; C < tri[7][0].data.length / 2; ++C) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
tri[8] = [{ type: 0, data: write_varint49(wide ? 1 : 0) }];
|
||||
return cnt;
|
||||
}
|
||||
function write_iwam(type, payload) {
|
||||
@ -871,7 +879,9 @@ function write_iwam(type, payload) {
|
||||
data: payload
|
||||
};
|
||||
}
|
||||
var USE_WIDE_ROWS = true;
|
||||
function write_numbers_iwa(wb, opts) {
|
||||
var _a;
|
||||
if (!opts || !opts.numbers)
|
||||
throw new Error("Must pass a `numbers` option -- check the README");
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
@ -880,13 +890,13 @@ function write_numbers_iwa(wb, opts) {
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
var trunc = false;
|
||||
if (range.e.c > 9) {
|
||||
if (range.e.c > 999) {
|
||||
trunc = true;
|
||||
range.e.c = 9;
|
||||
range.e.c = 999;
|
||||
}
|
||||
if (range.e.r > 49) {
|
||||
if (range.e.r > 254) {
|
||||
trunc = true;
|
||||
range.e.r = 49;
|
||||
range.e.r = 254;
|
||||
}
|
||||
if (trunc)
|
||||
console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
|
||||
@ -1044,12 +1054,13 @@ function write_numbers_iwa(wb, opts) {
|
||||
if (_x[0].id != row_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
if ((_a = base_bucket == null ? void 0 : base_bucket[2]) == null ? void 0 : _a[0])
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
@ -1126,7 +1137,7 @@ function write_numbers_iwa(wb, opts) {
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
tile[3] = [{ type: 0, data: write_varint49(USE_WIDE_ROWS ? 1 : 0) }];
|
||||
var tl = parse_shallow(t.data);
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
@ -1148,14 +1159,17 @@ function write_numbers_iwa(wb, opts) {
|
||||
var cnt = 0;
|
||||
for (var R2 = 0; R2 <= range.e.r; ++R2) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST, USE_WIDE_ROWS);
|
||||
tilerow[1][0].data = write_varint49(R2);
|
||||
tiledata[5].push({ data: write_shallow(tilerow), type: 2 });
|
||||
}
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(range.e.c + 1) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(cnt) }];
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(0) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(0) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(0) }];
|
||||
tiledata[4] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[6] = [{ type: 0, data: write_varint49(5) }];
|
||||
tiledata[7] = [{ type: 0, data: write_varint49(1) }];
|
||||
tiledata[8] = [{ type: 0, data: write_varint49(USE_WIDE_ROWS ? 1 : 0) }];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
tentry.content = compress_iwa_file(write_iwa_file(tx));
|
||||
|
@ -1,15 +1,8 @@
|
||||
function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
if(opts.bookType == "ods") return write_ods(wb, opts);
|
||||
if(opts.bookType == "numbers") return write_numbers_iwa(wb, opts);
|
||||
if(opts.bookType == "xlsb") return write_zip_xlsxb(wb, opts);
|
||||
return write_zip_xlsx(wb, opts);
|
||||
}
|
||||
|
||||
/* XLSX and XLSB writing are very similar. Originally they were unified in one
|
||||
export function. This is horrible for tree shaking in the common case (most
|
||||
applications need to export files in one format) so this function supports
|
||||
both formats while write_zip_xlsx only handles XLSX */
|
||||
function write_zip_xlsxb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
function write_zip_xlsb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
_shapeid = 1024;
|
||||
if(wb && !wb.SSF) {
|
||||
wb.SSF = dup(table_fmt);
|
||||
|
@ -9,6 +9,15 @@ function write_cfb_ctr(cfb/*:CFBContainer*/, o/*:WriteOpts*/)/*:any*/ {
|
||||
return CFB.write(cfb, o);
|
||||
}
|
||||
|
||||
function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||
switch(opts.bookType) {
|
||||
case "ods": return write_ods(wb, opts);
|
||||
case "numbers": return write_numbers_iwa(wb, opts);
|
||||
case "xlsb": return write_zip_xlsb(wb, opts);
|
||||
default: return write_zip_xlsx(wb, opts);
|
||||
}
|
||||
}
|
||||
|
||||
/*:: declare var encrypt_agile:any; */
|
||||
function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
|
||||
var o = dup(opts||{});
|
||||
|
2
dist/xlsx.zahl.js
generated
vendored
2
dist/xlsx.zahl.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.zahl.mjs
generated
vendored
2
dist/xlsx.zahl.mjs
generated
vendored
File diff suppressed because one or more lines are too long
@ -42,6 +42,7 @@ range limits will be silently truncated:
|
||||
|:------------------------------------------|:-----------|---------:|---------:|
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | XFD1048576 | 16384 | 1048576 |
|
||||
| Numbers 12.0 (NUMBERS) | ALL1000000 | 1000 | 1000000 |
|
||||
| Excel 97-2004 (XLS BIFF8) | IV65536 | 256 | 65536 |
|
||||
| Excel 5.0/95 (XLS BIFF5) | IV16384 | 256 | 16384 |
|
||||
| Excel 4.0 (XLS BIFF4) | IV16384 | 256 | 16384 |
|
||||
|
@ -1031,7 +1031,7 @@ generating a worksheet object. By default, it will generate a header row and
|
||||
one row per object in the array. The optional `opts` argument has settings to
|
||||
control the column order and header output.
|
||||
|
||||
["Array of Objects Input"](#array-of-arrays-input) describes the function and
|
||||
["Array of Objects Input"](#array-of-objects-input) describes the function and
|
||||
the optional `opts` argument in more detail.
|
||||
|
||||
**Examples**
|
||||
@ -3803,6 +3803,7 @@ range limits will be silently truncated:
|
||||
|:------------------------------------------|:-----------|---------:|---------:|
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | XFD1048576 | 16384 | 1048576 |
|
||||
| Numbers 12.0 (NUMBERS) | ALL1000000 | 1000 | 1000000 |
|
||||
| Excel 97-2004 (XLS BIFF8) | IV65536 | 256 | 65536 |
|
||||
| Excel 5.0/95 (XLS BIFF5) | IV16384 | 256 | 16384 |
|
||||
| Excel 4.0 (XLS BIFF4) | IV16384 | 256 | 16384 |
|
||||
|
@ -419,10 +419,6 @@ function parse_old_storage(buf, sst, rsst, v) {
|
||||
{
|
||||
if (ridx > -1)
|
||||
ret = { t: "s", v: rsst[ridx] };
|
||||
else if (sidx > -1)
|
||||
ret = { t: "s", v: sst[sidx] };
|
||||
else if (!isNaN(ieee))
|
||||
ret = { t: "n", v: ieee };
|
||||
else
|
||||
throw new Error("Unsupported cell type ".concat(buf.slice(0, 4)));
|
||||
}
|
||||
@ -815,24 +811,32 @@ function parse_numbers_iwa(cfb) {
|
||||
throw new Error("Cannot find Document root");
|
||||
return parse_TN_DocumentArchive(M, docroot);
|
||||
}
|
||||
function write_tile_row(tri, data, SST) {
|
||||
var _a, _b, _c, _d;
|
||||
function write_tile_row(tri, data, SST, wide) {
|
||||
var _a, _b;
|
||||
if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0]))
|
||||
throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if (wide_offsets)
|
||||
throw "Math only works with normal offsets";
|
||||
var cnt = 0;
|
||||
if (tri[7][0].data.length < 2 * data.length) {
|
||||
var new_7 = new Uint8Array(2 * data.length);
|
||||
new_7.set(tri[7][0].data);
|
||||
tri[7][0].data = new_7;
|
||||
}
|
||||
if (tri[4][0].data.length < 2 * data.length) {
|
||||
var new_4 = new Uint8Array(2 * data.length);
|
||||
new_4.set(tri[4][0].data);
|
||||
tri[4][0].data = new_4;
|
||||
}
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage = [];
|
||||
var width = wide ? 4 : 1;
|
||||
for (var C = 0; C < data.length; ++C) {
|
||||
if (data[C] == null) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535);
|
||||
continue;
|
||||
}
|
||||
dv.setUint16(C * 2, last_offset, true);
|
||||
_dv.setUint16(C * 2, _last_offset, true);
|
||||
dv.setUint16(C * 2, last_offset / width, true);
|
||||
_dv.setUint16(C * 2, _last_offset / width, true);
|
||||
var celload, _celload;
|
||||
switch (typeof data[C]) {
|
||||
case "string":
|
||||
@ -852,17 +856,21 @@ function write_tile_row(tri, data, SST) {
|
||||
}
|
||||
cell_storage.push(celload);
|
||||
last_offset += celload.length;
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
{
|
||||
_cell_storage.push(_celload);
|
||||
_last_offset += _celload.length;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
tri[5][0].data = write_varint49(5);
|
||||
for (; C < tri[7][0].data.length / 2; ++C) {
|
||||
dv.setUint16(C * 2, 65535, true);
|
||||
_dv.setUint16(C * 2, 65535, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
tri[8] = [{ type: 0, data: write_varint49(wide ? 1 : 0) }];
|
||||
return cnt;
|
||||
}
|
||||
function write_iwam(type, payload) {
|
||||
@ -871,7 +879,9 @@ function write_iwam(type, payload) {
|
||||
data: payload
|
||||
};
|
||||
}
|
||||
var USE_WIDE_ROWS = true;
|
||||
function write_numbers_iwa(wb, opts) {
|
||||
var _a;
|
||||
if (!opts || !opts.numbers)
|
||||
throw new Error("Must pass a `numbers` option -- check the README");
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
@ -880,13 +890,13 @@ function write_numbers_iwa(wb, opts) {
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
var trunc = false;
|
||||
if (range.e.c > 9) {
|
||||
if (range.e.c > 999) {
|
||||
trunc = true;
|
||||
range.e.c = 9;
|
||||
range.e.c = 999;
|
||||
}
|
||||
if (range.e.r > 49) {
|
||||
if (range.e.r > 254) {
|
||||
trunc = true;
|
||||
range.e.r = 49;
|
||||
range.e.r = 254;
|
||||
}
|
||||
if (trunc)
|
||||
console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
|
||||
@ -1044,12 +1054,13 @@ function write_numbers_iwa(wb, opts) {
|
||||
if (_x[0].id != row_header_ref)
|
||||
throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
if ((_a = base_bucket == null ? void 0 : base_bucket[2]) == null ? void 0 : _a[0])
|
||||
for (R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
|
||||
}
|
||||
_x[0].messages[0].data = write_shallow(base_bucket);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x));
|
||||
@ -1126,7 +1137,7 @@ function write_numbers_iwa(wb, opts) {
|
||||
var tile = parse_shallow(store[3][0].data);
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
tile[3] = [{ type: 0, data: write_varint49(USE_WIDE_ROWS ? 1 : 0) }];
|
||||
var tl = parse_shallow(t.data);
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
@ -1148,14 +1159,17 @@ function write_numbers_iwa(wb, opts) {
|
||||
var cnt = 0;
|
||||
for (var R2 = 0; R2 <= range.e.r; ++R2) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST);
|
||||
cnt += write_tile_row(tilerow, data[R2], SST, USE_WIDE_ROWS);
|
||||
tilerow[1][0].data = write_varint49(R2);
|
||||
tiledata[5].push({ data: write_shallow(tilerow), type: 2 });
|
||||
}
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(range.e.c + 1) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(cnt) }];
|
||||
tiledata[1] = [{ type: 0, data: write_varint49(0) }];
|
||||
tiledata[2] = [{ type: 0, data: write_varint49(0) }];
|
||||
tiledata[3] = [{ type: 0, data: write_varint49(0) }];
|
||||
tiledata[4] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
|
||||
tiledata[6] = [{ type: 0, data: write_varint49(5) }];
|
||||
tiledata[7] = [{ type: 0, data: write_varint49(1) }];
|
||||
tiledata[8] = [{ type: 0, data: write_varint49(USE_WIDE_ROWS ? 1 : 0) }];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
tentry.content = compress_iwa_file(write_iwa_file(tx));
|
||||
|
@ -86,6 +86,7 @@ function parse_varint49(buf: Uint8Array, ptr?: Ptr): number {
|
||||
if(ptr) ptr[0] = l;
|
||||
return usz;
|
||||
}
|
||||
/** Write a varint up to 7 bytes / 49 bits */
|
||||
function write_varint49(v: number): Uint8Array {
|
||||
var usz = new Uint8Array(7);
|
||||
usz[0] = (v & 0x7F);
|
||||
@ -215,6 +216,7 @@ function parse_iwa_file(buf: Uint8Array): IWAArchiveInfo[] {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
/** Generate an IWA file from a parsed structure */
|
||||
function write_iwa_file(ias: IWAArchiveInfo[]): Uint8Array {
|
||||
var bufs: Uint8Array[] = [];
|
||||
ias.forEach(ia => {
|
||||
@ -357,10 +359,8 @@ function parse_old_storage(buf: Uint8Array, sst: string[], rsst: string[], v: 0|
|
||||
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
|
||||
case 7: ret = { t: "n", v: ieee / 86400 }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
|
||||
case 8: ret = { t: "e", v: 0}; break; // "formula error" TODO: enumerate and map errors to csf equivalents
|
||||
case 9: { // "automatic"?
|
||||
case 9: { // "rich text"
|
||||
if(ridx > -1) ret = { t: "s", v: rsst[ridx] };
|
||||
else if(sidx > -1) ret = { t: "s", v: sst[sidx] };
|
||||
else if(!isNaN(ieee)) ret = { t: "n", v: ieee };
|
||||
else throw new Error(`Unsupported cell type ${buf.slice(0,4)}`);
|
||||
} break;
|
||||
default: throw new Error(`Unsupported cell type ${buf.slice(0,4)}`);
|
||||
@ -395,7 +395,7 @@ function parse_new_storage(buf: Uint8Array, sst: string[], rsst: string[]): Cell
|
||||
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
|
||||
case 7: ret = { t: "n", v: ieee / 86400 }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
|
||||
case 8: ret = { t: "e", v: 0}; break; // "formula error" TODO: enumerate and map errors to csf equivalents
|
||||
case 9: { // "automatic"?
|
||||
case 9: { // "rich text"
|
||||
if(ridx > -1) ret = { t: "s", v: rsst[ridx] };
|
||||
else throw new Error(`Unsupported cell type ${buf[1]} : ${flags & 0x1F} : ${buf.slice(0,4)}`);
|
||||
} break;
|
||||
@ -406,6 +406,8 @@ function parse_new_storage(buf: Uint8Array, sst: string[], rsst: string[]): Cell
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Write a cell "new storage" (version 5) */
|
||||
function write_new_storage(cell: CellObject, sst: string[]): Uint8Array {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 5;
|
||||
@ -420,6 +422,7 @@ function write_new_storage(cell: CellObject, sst: string[]): Uint8Array {
|
||||
dv.setUint32(8, flags, true);
|
||||
return out.slice(0, l);
|
||||
}
|
||||
/** Write a cell "old storage" (version 3) */
|
||||
function write_old_storage(cell: CellObject, sst: string[]): Uint8Array {
|
||||
var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
|
||||
out[0] = 3;
|
||||
@ -449,11 +452,12 @@ function parse_cell_storage(buf: Uint8Array, sst: string[], rsst: string[]): Cel
|
||||
// var pb = parse_shallow(root.data);
|
||||
//}
|
||||
|
||||
/** .TSP.Reference */
|
||||
/** Parse .TSP.Reference */
|
||||
function parse_TSP_Reference(buf: Uint8Array): number {
|
||||
var pb = parse_shallow(buf);
|
||||
return parse_varint49(pb[1][0].data);
|
||||
}
|
||||
/** Write .TSP.Reference */
|
||||
function write_TSP_Reference(idx: number): Uint8Array {
|
||||
return write_shallow([
|
||||
[],
|
||||
@ -464,7 +468,7 @@ function write_TSP_Reference(idx: number): Uint8Array {
|
||||
|
||||
type MessageSpace = {[id: number]: IWAMessage[]};
|
||||
|
||||
/** .TST.TableDataList */
|
||||
/** Parse .TST.TableDataList */
|
||||
function parse_TST_TableDataList(M: MessageSpace, root: IWAMessage): string[] {
|
||||
var pb = parse_shallow(root.data);
|
||||
// .TST.TableDataList.ListType
|
||||
@ -503,7 +507,7 @@ interface TileRowInfo {
|
||||
/** Cell Storage */
|
||||
cells?: Uint8Array[];
|
||||
}
|
||||
/** .TSP.TileRowInfo */
|
||||
/** Parse .TSP.TileRowInfo */
|
||||
function parse_TST_TileRowInfo(u8: Uint8Array, type: TileStorageType): TileRowInfo {
|
||||
var pb = parse_shallow(u8);
|
||||
var R = varint_to_i32(pb[1][0].data) >>> 0;
|
||||
@ -537,7 +541,7 @@ interface TileInfo {
|
||||
data: Uint8Array[][];
|
||||
nrows: number;
|
||||
}
|
||||
/** .TST.Tile */
|
||||
/** Parse .TST.Tile */
|
||||
function parse_TST_Tile(M: MessageSpace, root: IWAMessage): TileInfo {
|
||||
var pb = parse_shallow(root.data);
|
||||
// ESBuild issue 2136
|
||||
@ -558,7 +562,7 @@ function parse_TST_Tile(M: MessageSpace, root: IWAMessage): TileInfo {
|
||||
};
|
||||
}
|
||||
|
||||
/** .TST.TableModelArchive (6001) */
|
||||
/** Parse .TST.TableModelArchive (6001) */
|
||||
function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: WorkSheet) {
|
||||
var pb = parse_shallow(root.data);
|
||||
var range: Range = { s: {r:0, c:0}, e: {r:0, c:0} };
|
||||
@ -612,7 +616,7 @@ function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: Work
|
||||
}
|
||||
}
|
||||
|
||||
/** .TST.TableInfoArchive (6000) */
|
||||
/** Parse .TST.TableInfoArchive (6000) */
|
||||
function parse_TST_TableInfoArchive(M: MessageSpace, root: IWAMessage): WorkSheet {
|
||||
var pb = parse_shallow(root.data);
|
||||
var out: WorkSheet = { "!ref": "A1" };
|
||||
@ -627,7 +631,7 @@ interface NSheet {
|
||||
name: string;
|
||||
sheets: WorkSheet[];
|
||||
}
|
||||
/** .TN.SheetArchive (2) */
|
||||
/** Parse .TN.SheetArchive (2) */
|
||||
function parse_TN_SheetArchive(M: MessageSpace, root: IWAMessage): NSheet {
|
||||
var pb = parse_shallow(root.data);
|
||||
var out: NSheet = {
|
||||
@ -644,7 +648,7 @@ function parse_TN_SheetArchive(M: MessageSpace, root: IWAMessage): NSheet {
|
||||
return out;
|
||||
}
|
||||
|
||||
/** .TN.DocumentArchive */
|
||||
/** Parse .TN.DocumentArchive */
|
||||
function parse_TN_DocumentArchive(M: MessageSpace, root: IWAMessage): WorkBook {
|
||||
var out = book_new();
|
||||
var pb = parse_shallow(root.data);
|
||||
@ -711,49 +715,65 @@ interface DependentInfo {
|
||||
location: string;
|
||||
type: number;
|
||||
}
|
||||
|
||||
function write_tile_row(tri: ProtoMessage, data: any[], SST: string[]): number {
|
||||
/** Write .TST.TileRowInfo */
|
||||
function write_tile_row(tri: ProtoMessage, data: any[], SST: string[], wide: boolean): number {
|
||||
if(!tri[6]?.[0] || !tri[7]?.[0]) throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = tri[8]?.[0]?.data && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if(wide_offsets) throw "Math only works with normal offsets";
|
||||
//var wide_offsets = tri[8]?.[0]?.data && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
var cnt = 0;
|
||||
if(tri[7][0].data.length < 2 * data.length) {
|
||||
var new_7 = new Uint8Array(2 * data.length);
|
||||
new_7.set(tri[7][0].data);
|
||||
tri[7][0].data = new_7;
|
||||
}
|
||||
//if(wide) {
|
||||
// tri[3] = [{type: 2, data: new Uint8Array([240, 159, 164, 160]) }];
|
||||
// tri[4] = [{type: 2, data: new Uint8Array([240, 159, 164, 160]) }];
|
||||
/* } else*/ if(tri[4][0].data.length < 2 * data.length) {
|
||||
var new_4 = new Uint8Array(2 * data.length);
|
||||
new_4.set(tri[4][0].data);
|
||||
tri[4][0].data = new_4;
|
||||
}
|
||||
var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage: Uint8Array[] = [];
|
||||
var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage: Uint8Array[] = [];
|
||||
var width = wide ? 4 : 1;
|
||||
for(var C = 0; C < data.length; ++C) {
|
||||
if(data[C] == null) { dv.setUint16(C*2, 0xFFFF, true); _dv.setUint16(C*2, 0xFFFF); continue; }
|
||||
dv.setUint16(C*2, last_offset, true);
|
||||
_dv.setUint16(C*2, _last_offset, true);
|
||||
dv.setUint16(C*2, last_offset / width, true);
|
||||
/*if(!wide)*/ _dv.setUint16(C*2, _last_offset / width, true);
|
||||
var celload: Uint8Array, _celload: Uint8Array;
|
||||
switch(typeof data[C]) {
|
||||
case "string":
|
||||
celload = write_new_storage({t: "s", v: data[C]}, SST);
|
||||
_celload = write_old_storage({t: "s", v: data[C]}, SST);
|
||||
/*if(!wide)*/ _celload = write_old_storage({t: "s", v: data[C]}, SST);
|
||||
break;
|
||||
case "number":
|
||||
celload = write_new_storage({t: "n", v: data[C]}, SST);
|
||||
_celload = write_old_storage({t: "n", v: data[C]}, SST);
|
||||
/*if(!wide)*/ _celload = write_old_storage({t: "n", v: data[C]}, SST);
|
||||
break;
|
||||
case "boolean":
|
||||
celload = write_new_storage({t: "b", v: data[C]}, SST);
|
||||
_celload = write_old_storage({t: "b", v: data[C]}, SST);
|
||||
/*if(!wide)*/ _celload = write_old_storage({t: "b", v: data[C]}, SST);
|
||||
break;
|
||||
default: throw new Error("Unsupported value " + data[C]);
|
||||
}
|
||||
cell_storage.push(celload); last_offset += celload.length;
|
||||
_cell_storage.push(_celload); _last_offset += _celload.length;
|
||||
/*if(!wide)*/ { _cell_storage.push(_celload); _last_offset += _celload.length; }
|
||||
++cnt;
|
||||
}
|
||||
tri[2][0].data = write_varint49(cnt);
|
||||
tri[5][0].data = write_varint49(5);
|
||||
|
||||
for(; C < tri[7][0].data.length/2; ++C) {
|
||||
dv.setUint16(C*2, 0xFFFF, true);
|
||||
_dv.setUint16(C*2, 0xFFFF, true);
|
||||
/*if(!wide)*/ _dv.setUint16(C*2, 0xFFFF, true);
|
||||
}
|
||||
tri[6][0].data = u8concat(cell_storage);
|
||||
tri[3][0].data = u8concat(_cell_storage);
|
||||
/*if(!wide)*/ tri[3][0].data = u8concat(_cell_storage);
|
||||
tri[8] = [{type: 0, data: write_varint49(wide ? 1 : 0)}];
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/** Write IWA Message */
|
||||
function write_iwam(type: number, payload: Uint8Array): IWAMessage {
|
||||
return {
|
||||
meta: [ [], [ { type: 0, data: write_varint49(type) } ] ],
|
||||
@ -761,17 +781,23 @@ function write_iwam(type: number, payload: Uint8Array): IWAMessage {
|
||||
};
|
||||
}
|
||||
|
||||
var USE_WIDE_ROWS = true;
|
||||
/** Write NUMBERS workbook */
|
||||
function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
if(!opts || !opts.numbers) throw new Error("Must pass a `numbers` option -- check the README");
|
||||
|
||||
/* TODO: support multiple worksheets, larger ranges, more data types, etc */
|
||||
var ws = wb.Sheets[wb.SheetNames[0]];
|
||||
if(wb.SheetNames.length > 1) console.error("The Numbers writer currently writes only the first table");
|
||||
var range = decode_range(ws["!ref"]);
|
||||
range.s.r = range.s.c = 0;
|
||||
|
||||
/* Actual NUMBERS 12.0 limit ALL1000000 */
|
||||
var trunc = false;
|
||||
if(range.e.c > 9) { trunc = true; range.e.c = 9; }
|
||||
if(range.e.r > 49) { trunc = true; range.e.r = 49; }
|
||||
if(range.e.c > 999) { trunc = true; range.e.c = 999; }
|
||||
if(range.e.r > 254 /* 1000000 */) { trunc = true; range.e.r = 254 /* 1000000 */; }
|
||||
if(trunc) console.error(`The Numbers writer is currently limited to ${encode_range(range)}`);
|
||||
|
||||
var data = sheet_to_json<any>(ws, { range, header: 1 });
|
||||
var SST = ["~Sh33tJ5~"];
|
||||
data.forEach(row => row.forEach(cell => { if(typeof cell == "string") SST.push(cell); }))
|
||||
@ -779,6 +805,7 @@ function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
var dependents: {[x:number]: DependentInfo} = {};
|
||||
var indices: number[] = [];
|
||||
|
||||
/* read template and build packet metadata */
|
||||
var cfb: CFB$Container = CFB.read(opts.numbers, { type: "base64" });
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
@ -797,9 +824,11 @@ function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
});
|
||||
});
|
||||
|
||||
/* precompute a varint for each id */
|
||||
indices.sort((x,y) => x-y);
|
||||
var indices_varint: Array<[number, Uint8Array]> = indices.filter(x => x > 1).map(x => [x, write_varint49(x)] );
|
||||
|
||||
/* build dependent tree */
|
||||
cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).forEach(row => {
|
||||
var fi = row[0], fp = row[1];
|
||||
if(!fi.name.match(/\.iwa/)) return;
|
||||
@ -882,6 +911,7 @@ function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
if(_x[j].id == cruidsref) break;
|
||||
}
|
||||
if(_x[j].id != cruidsref) throw "Bad ColumnRowUIDMapArchive";
|
||||
/* .TST.ColumnRowUIDMapArchive */
|
||||
var cruids = parse_shallow(_x[j].messages[0].data);
|
||||
cruids[1] = []; cruids[2] = [], cruids[3] = [];
|
||||
for(var C = 0; C <= range.e.c; ++C) {
|
||||
@ -904,7 +934,7 @@ function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
_x[j].messages[0].data = write_shallow(cruids);
|
||||
}
|
||||
oldbucket.content = compress_iwa_file(write_iwa_file(_x)); oldbucket.size = oldbucket.content.length;
|
||||
delete pb[46];
|
||||
delete pb[46]; // forces Numbers to refresh cell table
|
||||
|
||||
var store = parse_shallow(pb[4][0].data);
|
||||
{
|
||||
@ -916,7 +946,7 @@ function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
{
|
||||
if(_x[0].id != row_header_ref) throw "Bad HeaderStorageBucket";
|
||||
var base_bucket = parse_shallow(_x[0].messages[0].data);
|
||||
for(R = 0; R < data.length; ++R) {
|
||||
if(base_bucket?.[2]?.[0]) for(R = 0; R < data.length; ++R) {
|
||||
var _bucket = parse_shallow(base_bucket[2][0].data);
|
||||
_bucket[1][0].data = write_varint49(R);
|
||||
_bucket[4][0].data = write_varint49(data[R].length);
|
||||
@ -994,7 +1024,7 @@ function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
var tile = parse_shallow(store[3][0].data); // TileStorage
|
||||
{
|
||||
var t = tile[1][0];
|
||||
delete tile[2];
|
||||
tile[3] = [{type: 0, data: write_varint49(USE_WIDE_ROWS ? 1 : 0)}];
|
||||
var tl = parse_shallow(t.data); // first Tile
|
||||
{
|
||||
var tileref = parse_TSP_Reference(tl[2][0].data);
|
||||
@ -1016,14 +1046,17 @@ function write_numbers_iwa(wb: WorkBook, opts: any): CFB$Container {
|
||||
var cnt = 0;
|
||||
for(var R = 0; R <= range.e.r; ++R) {
|
||||
var tilerow = parse_shallow(rowload);
|
||||
cnt += write_tile_row(tilerow, data[R], SST);
|
||||
cnt += write_tile_row(tilerow, data[R], SST, USE_WIDE_ROWS);
|
||||
tilerow[1][0].data = write_varint49(R);
|
||||
tiledata[5].push({data: write_shallow(tilerow), type: 2});
|
||||
}
|
||||
tiledata[1] = [{type: 0, data: write_varint49(range.e.c + 1)}];
|
||||
tiledata[2] = [{type: 0, data: write_varint49(range.e.r + 1)}];
|
||||
tiledata[3] = [{type: 0, data: write_varint49(cnt)}];
|
||||
tiledata[1] = [{type: 0, data: write_varint49(0 /*range.e.c + 1*/)}];
|
||||
tiledata[2] = [{type: 0, data: write_varint49(0 /*range.e.r + 1*/)}];
|
||||
tiledata[3] = [{type: 0, data: write_varint49(0 /*cnt*/)}];
|
||||
tiledata[4] = [{type: 0, data: write_varint49(range.e.r + 1)}];
|
||||
tiledata[6] = [{type: 0, data: write_varint49(5)}];
|
||||
tiledata[7] = [{type: 0, data: write_varint49(1)}];
|
||||
tiledata[8] = [{type: 0, data: write_varint49(USE_WIDE_ROWS ? 1 : 0)}];
|
||||
}
|
||||
tileroot.messages[0].data = write_shallow(tiledata);
|
||||
|
||||
|
@ -186,8 +186,8 @@ shake();
|
||||
|
||||
function mutate_row(tri: ReturnType<typeof parse_shallow>) {
|
||||
if(!tri[6]?.[0] || !tri[7]?.[0]) throw "Mutation only works on post-BNC storages!";
|
||||
var wide_offsets = tri[8]?.[0]?.data && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
if(wide_offsets) throw "Math only works with normal offsets";
|
||||
var wide_offsets = tri[8]?.[0]?.data && varint_to_i32(tri[8][0].data) > 0 || false;
|
||||
var width = wide_offsets ? 4 : 1;
|
||||
var dv = u8_to_dataview(tri[7][0].data);
|
||||
var old_sz = 0, sz = 0;
|
||||
for(var i = 0; i < tri[7][0].data.length / 2; ++i) {
|
||||
@ -198,14 +198,14 @@ function mutate_row(tri: ReturnType<typeof parse_shallow>) {
|
||||
if(!old_sz) old_sz = sz = tri[6][0].data.length;
|
||||
var start = 0,
|
||||
preamble = tri[6][0].data.slice(0, start),
|
||||
intramble = tri[6][0].data.slice(start, old_sz),
|
||||
postamble = tri[6][0].data.slice(old_sz);
|
||||
intramble = tri[6][0].data.slice(start, old_sz * width),
|
||||
postamble = tri[6][0].data.slice(old_sz * width);
|
||||
var sst = []; sst[69] = "SheetJS";
|
||||
//intramble = write_new_storage({t:"n", v:12345}, sst);
|
||||
//intramble = write_new_storage({t:"b", v:false}, sst);
|
||||
intramble = write_new_storage({t:"s", v:"SheetJS"}, sst);
|
||||
tri[6][0].data = u8concat([preamble, intramble, postamble]);
|
||||
var delta = intramble.length - old_sz;
|
||||
var delta = intramble.length / width - old_sz;
|
||||
for(var i = 0; i < tri[7][0].data.length / 2; ++i) {
|
||||
sz = dv.getUint16(i*2, true);
|
||||
if(sz < 65535 && sz > start) dv.setUint16(i*2, sz + delta, true);
|
||||
@ -332,9 +332,9 @@ cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).
|
||||
var x = parse_iwa_file(decompress_iwa_file(fi.content as Uint8Array));
|
||||
|
||||
if(fi.name.match(/^Metadata.iwa$/)) {
|
||||
x.forEach((w: IWAArchiveInfo) => {
|
||||
var type = varint_to_i32(w.messages[0].meta[1][0].data);
|
||||
if(type != 11006) return;
|
||||
x.forEach((w: IWAArchiveInfo) => {
|
||||
var type = varint_to_i32(w.messages[0].meta[1][0].data);
|
||||
if(type != 11006) return;
|
||||
var package_metadata = parse_shallow(w.messages[0].data);
|
||||
[3,11].forEach(x => {
|
||||
if(!package_metadata[x]) return;
|
||||
@ -353,8 +353,8 @@ cfb.FileIndex.map((fi, idx): [CFB$Entry, string] => ([fi, cfb.FullPaths[idx]])).
|
||||
});
|
||||
[2, 4, 6, 8, 9].forEach(j => delete package_metadata[j]);
|
||||
w.messages[0].data = write_shallow(package_metadata);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var y = write_iwa_file(x);
|
||||
var raw3 = compress_iwa_file(y);
|
||||
@ -628,4 +628,4 @@ function trim(x: IWAArchiveInfo[], fi: CFB$Entry) {
|
||||
}
|
||||
w.messages[0].data = write_shallow(dmeta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
@ -34,10 +34,10 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"adler-32": "~1.3.0",
|
||||
"cfb": "~1.2.1",
|
||||
"adler-32": "~1.3.1",
|
||||
"cfb": "~1.2.2",
|
||||
"codepage": "~1.15.0",
|
||||
"crc-32": "~1.2.1",
|
||||
"crc-32": "~1.2.2",
|
||||
"ssf": "~0.11.2",
|
||||
"wmf": "~1.0.1",
|
||||
"word": "~0.3.0"
|
||||
|
10
test.js
10
test.js
@ -2195,6 +2195,16 @@ describe('sylk', function() {
|
||||
assert.equal(get_cell(ws, "B11").v, true);
|
||||
assert.equal(get_cell(ws, "B13").v, 50);
|
||||
});
|
||||
it('should cap cols at 1000 (ALL)', function() {
|
||||
var aoa = [[1], [], []]; aoa[1][999] = 2; aoa[2][1000] = 3;
|
||||
var ws1 = X.utils.aoa_to_sheet(aoa);
|
||||
var wb1 = X.utils.book_new(); X.utils.book_append_sheet(wb1, ws1, "Sheet1");
|
||||
var wb2 = X.read(X.write(wb1,{bookType:"numbers",type:'binary',numbers:XLSX_ZAHL}),{type:'binary'});
|
||||
var ws2 = wb2.Sheets.Sheet1;
|
||||
assert.equal(ws2["!ref"], "A1:ALL3");
|
||||
assert.equal(get_cell(ws2, "A1").v, 1);
|
||||
assert.equal(get_cell(ws2, "ALL2").v, 2);
|
||||
});
|
||||
});
|
||||
|
||||
if(fs.existsSync(dir + 'dbf/d11.dbf')) describe('dbf', function() {
|
||||
|
10
test.mjs
generated
10
test.mjs
generated
@ -2179,6 +2179,16 @@ describe('sylk', function() {
|
||||
assert.equal(get_cell(ws, "B11").v, true);
|
||||
assert.equal(get_cell(ws, "B13").v, 50);
|
||||
});
|
||||
it('should cap cols at 1000 (ALL)', function() {
|
||||
var aoa = [[1], [], []]; aoa[1][999] = 2; aoa[2][1000] = 3;
|
||||
var ws1 = X.utils.aoa_to_sheet(aoa);
|
||||
var wb1 = X.utils.book_new(); X.utils.book_append_sheet(wb1, ws1, "Sheet1");
|
||||
var wb2 = X.read(X.write(wb1,{bookType:"numbers",type:'binary',numbers:XLSX_ZAHL}),{type:'binary'});
|
||||
var ws2 = wb2.Sheets.Sheet1;
|
||||
assert.equal(ws2["!ref"], "A1:ALL3");
|
||||
assert.equal(get_cell(ws2, "A1").v, 1);
|
||||
assert.equal(get_cell(ws2, "ALL2").v, 2);
|
||||
});
|
||||
});
|
||||
|
||||
if(fs.existsSync(dir + 'dbf/d11.dbf')) describe('dbf', function() {
|
||||
|
10
test.ts
10
test.ts
@ -2127,6 +2127,16 @@ Deno.test('numbers', async function(t) {
|
||||
assert.equal(get_cell(ws, "B11").v, true);
|
||||
assert.equal(get_cell(ws, "B13").v, 50);
|
||||
});
|
||||
await t.step('should cap cols at 1000 (ALL)', async function(t) {
|
||||
var aoa = [[1], [], []]; aoa[1][999] = 2; aoa[2][1000] = 3;
|
||||
var ws1 = X.utils.aoa_to_sheet(aoa);
|
||||
var wb1 = X.utils.book_new(); X.utils.book_append_sheet(wb1, ws1, "Sheet1");
|
||||
var wb2 = X.read(X.write(wb1,{bookType:"numbers",type:'binary',numbers:XLSX_ZAHL}),{type:'binary'});
|
||||
var ws2 = wb2.Sheets.Sheet1;
|
||||
assert.equal(ws2["!ref"], "A1:ALL3");
|
||||
assert.equal(get_cell(ws2, "A1").v, 1);
|
||||
assert.equal(get_cell(ws2, "ALL2").v, 2);
|
||||
});
|
||||
});
|
||||
|
||||
if(fs.existsSync(dir + 'dbf/d11.dbf')) Deno.test('dbf', async function(t) {
|
||||
|
10
tests/core.js
generated
10
tests/core.js
generated
@ -2195,6 +2195,16 @@ describe('sylk', function() {
|
||||
assert.equal(get_cell(ws, "B11").v, true);
|
||||
assert.equal(get_cell(ws, "B13").v, 50);
|
||||
});
|
||||
it('should cap cols at 1000 (ALL)', function() {
|
||||
var aoa = [[1], [], []]; aoa[1][999] = 2; aoa[2][1000] = 3;
|
||||
var ws1 = X.utils.aoa_to_sheet(aoa);
|
||||
var wb1 = X.utils.book_new(); X.utils.book_append_sheet(wb1, ws1, "Sheet1");
|
||||
var wb2 = X.read(X.write(wb1,{bookType:"numbers",type:'binary',numbers:XLSX_ZAHL}),{type:'binary'});
|
||||
var ws2 = wb2.Sheets.Sheet1;
|
||||
assert.equal(ws2["!ref"], "A1:ALL3");
|
||||
assert.equal(get_cell(ws2, "A1").v, 1);
|
||||
assert.equal(get_cell(ws2, "ALL2").v, 2);
|
||||
});
|
||||
});
|
||||
|
||||
if(fs.existsSync(dir + 'dbf/d11.dbf')) describe('dbf', function() {
|
||||
|
2
types/index.d.ts
vendored
2
types/index.d.ts
vendored
@ -578,7 +578,7 @@ export type ExcelDataType = 'b' | 'n' | 'e' | 's' | 'd' | 'z';
|
||||
* Type of generated workbook
|
||||
* @default 'xlsx'
|
||||
*/
|
||||
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'xla' | 'biff8' | 'biff5' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'slk' | 'html' | 'dif' | 'rtf' | 'prn' | 'eth' | 'dbf';
|
||||
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'xla' | 'biff8' | 'biff5' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'slk' | 'html' | 'dif' | 'rtf' | 'prn' | 'eth' | 'dbf' | 'numbers';
|
||||
|
||||
/** Comment element */
|
||||
export interface Comment {
|
||||
|
141
xlsx.flow.js
141
xlsx.flow.js
@ -988,7 +988,7 @@ function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
|
||||
case 'A': case 'a': case '上':
|
||||
var q={t:c, v:c};
|
||||
if(dt==null) dt=SSF_parse_date_code(v, opts);
|
||||
if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
|
||||
if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? fmt.charAt(i+2) : c; q.t = 'T'; hr='h';i+=3;}
|
||||
else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
|
||||
else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; }
|
||||
else { q.t = "t"; ++i; }
|
||||
@ -1320,6 +1320,15 @@ function dateNF_fix(str/*:string*/, dateNF/*:string*/, match/*:Array<string>*/)/
|
||||
return datestr + "T" + timestr;
|
||||
}
|
||||
|
||||
/* table of bad formats written by third-party tools */
|
||||
var bad_formats = {
|
||||
"d.m": "d\\.m" // Issue #2571 Google Sheets writes invalid format 'd.m', correct format is 'd"."m' or 'd\\.m'
|
||||
};
|
||||
|
||||
function SSF__load(fmt, idx) {
|
||||
return SSF_load(bad_formats[fmt] || fmt, idx);
|
||||
}
|
||||
|
||||
/*::
|
||||
declare var ReadShift:any;
|
||||
declare var CheckField:any;
|
||||
@ -1455,7 +1464,7 @@ return CRC32;
|
||||
/* [MS-CFB] v20171201 */
|
||||
var CFB = /*#__PURE__*/(function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '1.2.1';
|
||||
exports.version = '1.2.2';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
@ -1755,7 +1764,7 @@ function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/,
|
||||
if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
|
||||
fat_addrs.push(q);
|
||||
}
|
||||
sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
|
||||
if(cnt >= 1) sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1931,7 +1940,9 @@ function rebuild_cfb(cfb/*:CFBContainer*/, f/*:?boolean*/)/*:void*/ {
|
||||
for(i = 0; i < data.length; ++i) {
|
||||
var dad = dirname(data[i][0]);
|
||||
s = fullPaths[dad];
|
||||
if(!s) {
|
||||
while(!s) {
|
||||
while(dirname(dad) && !fullPaths[dirname(dad)]) dad = dirname(dad);
|
||||
|
||||
data.push([dad, ({
|
||||
name: filename(dad).replace("/",""),
|
||||
type: 1,
|
||||
@ -1939,8 +1950,12 @@ function rebuild_cfb(cfb/*:CFBContainer*/, f/*:?boolean*/)/*:void*/ {
|
||||
ct: now, mt: now,
|
||||
content: null
|
||||
}/*:any*/)]);
|
||||
|
||||
// Add name to set
|
||||
fullPaths[dad] = true;
|
||||
|
||||
dad = dirname(data[i][0]);
|
||||
s = fullPaths[dad];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1988,7 +2003,6 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|strin
|
||||
for(var i = 0; i < cfb.FileIndex.length; ++i) {
|
||||
var file = cfb.FileIndex[i];
|
||||
if(!file.content) continue;
|
||||
/*:: if(file.content == null) throw new Error("unreachable"); */
|
||||
var flen = file.content.length;
|
||||
if(flen > 0){
|
||||
if(flen < 0x1000) mini_size += (flen + 0x3F) >> 6;
|
||||
@ -2079,6 +2093,10 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|strin
|
||||
file = cfb.FileIndex[i];
|
||||
if(i === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;
|
||||
var _nm/*:string*/ = (i === 0 && _opts.root) || file.name;
|
||||
if(_nm.length > 32) {
|
||||
console.error("Name " + _nm + " will be truncated to " + _nm.slice(0,32));
|
||||
_nm = _nm.slice(0, 32);
|
||||
}
|
||||
flen = 2*(_nm.length+1);
|
||||
o.write_shift(64, _nm, "utf16le");
|
||||
o.write_shift(2, flen);
|
||||
@ -2717,6 +2735,7 @@ function parse_zip(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/
|
||||
parse_local_file(blob, csz, usz, o, EF);
|
||||
blob.l = L;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -10449,7 +10468,7 @@ function parse_numFmts(t, styles, opts) {
|
||||
for(j = 0x188; j > 0x3c; --j) if(styles.NumberFmt[j] == null) break;
|
||||
styles.NumberFmt[j] = f;
|
||||
}
|
||||
SSF_load(f,j);
|
||||
SSF__load(f,j);
|
||||
}
|
||||
} break;
|
||||
case '</numFmt>': break;
|
||||
@ -10816,7 +10835,7 @@ function parse_sty_bin(data, themes, opts) {
|
||||
recordhopper(data, function hopper_sty(val, R, RT) {
|
||||
switch(RT) {
|
||||
case 0x002C: /* BrtFmt */
|
||||
styles.NumberFmt[val[0]] = val[1]; SSF_load(val[1], val[0]);
|
||||
styles.NumberFmt[val[0]] = val[1]; SSF__load(val[1], val[0]);
|
||||