forked from sheetjs/sheetjs
version bump 0.12.11: file format range limits
This commit is contained in:
parent
75c49ddbe8
commit
eb5fc87be4
@ -1,5 +1,6 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "10"
|
||||
- "9"
|
||||
- "8"
|
||||
- "7"
|
||||
|
@ -4,6 +4,10 @@ This log is intended to keep track of backwards-incompatible changes, including
|
||||
but not limited to API changes and file location changes. Minor behavioral
|
||||
changes may not be included if they are not expected to break existing code.
|
||||
|
||||
## 0.12.11 (2018-04-27)
|
||||
|
||||
* XLS/XLSX/XLSB range truncation (errors in `WTF` mode)
|
||||
|
||||
## 0.12.4 (2018-03-04)
|
||||
|
||||
* `JSZip` renamed to `JSZipSync`
|
||||
|
14
README.md
14
README.md
@ -2286,6 +2286,20 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Rich Text Format tables (RTF) | | :o: |
|
||||
| Ethercalc Record Format (ETH) | :o: | :o: |
|
||||
|
||||
Features not supported by a given file format will not be written. Formats with
|
||||
range limits will be silently truncated:
|
||||
|
||||
| Format | Last Cell | Max Cols | Max Rows |
|
||||
|:------------------------------------------|:-----------|---------:|---------:|
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 97-2004 (XLS BIFF8) | IV65536 | 256 | 65536 |
|
||||
| Excel 5.0/95 (XLS BIFF5) | IV16384 | 256 | 16384 |
|
||||
| Excel 2.0/2.1 (XLS BIFF2) | IV16384 | 256 | 16384 |
|
||||
|
||||
Excel 2003 SpreadsheetML range limits are governed by the version of Excel and
|
||||
are not enforced by the writer.
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
<details>
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.12.10';
|
||||
XLSX.version = '0.12.11';
|
||||
|
@ -99,3 +99,10 @@ function safe_format(p/*:Cell*/, fmtid/*:number*/, fillid/*:?number*/, opts, the
|
||||
}
|
||||
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
|
||||
}
|
||||
|
||||
function check_ws(ws/*:Worksheet*/, sname/*:string*/, i/*:number*/) {
|
||||
if(ws && ws['!ref']) {
|
||||
var range = safe_decode_range(ws['!ref']);
|
||||
if(range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +469,14 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
|
||||
var ws = wb.Sheets[s];
|
||||
if(ws == null) ws = {};
|
||||
var ref = ws['!ref']; if(ref == null) ref = 'A1';
|
||||
var ref = ws['!ref'] || 'A1';
|
||||
var range = safe_decode_range(ref);
|
||||
if(range.e.c > 0x3FFF || range.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + ref + " exceeds format limit A1:XFD1048576");
|
||||
range.e.c = Math.min(range.e.c, 0x3FFF);
|
||||
range.e.r = Math.min(range.e.c, 0xFFFFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
if(!rels) rels = {};
|
||||
ws['!comments'] = [];
|
||||
ws['!drawing'] = [];
|
||||
|
@ -809,6 +809,11 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) {
|
||||
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
|
||||
var c/*:string*/ = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
|
||||
var r = safe_decode_range(ws['!ref'] || "A1");
|
||||
if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:XFD1048576");
|
||||
r.e.c = Math.min(r.e.c, 0x3FFF);
|
||||
r.e.r = Math.min(r.e.c, 0xFFFFF);
|
||||
}
|
||||
ws['!links'] = [];
|
||||
/* passed back to write_zip and removed there */
|
||||
ws['!comments'] = [];
|
||||
|
@ -139,5 +139,6 @@ function check_wb(wb) {
|
||||
if(!wb.SheetNames.length) throw new Error("Workbook is empty");
|
||||
var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
|
||||
check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
|
||||
/* TODO: validate workbook */
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
|
||||
/* 18.2.1 bookViews CT_BookViews ? */
|
||||
case '<bookViews': case '<bookViews>': case '</bookViews>': break;
|
||||
/* 18.2.30 workbookView CT_BookView + */
|
||||
case '<workbookView': delete y[0]; wb.WBView.push(y); break;
|
||||
case '<workbookView': case '<workbookView/>': delete y[0]; wb.WBView.push(y); break;
|
||||
case '</workbookView>': break;
|
||||
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
|
@ -55,6 +55,12 @@ function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:n
|
||||
function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/*::, wb:Workbook*/) {
|
||||
var dense = Array.isArray(ws);
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
||||
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, 0x3FFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
rr = encode_row(R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
@ -159,9 +165,16 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
var _WB/*:WBWBProps*/ = ((wb||{}).Workbook||{}/*:any*/);
|
||||
var _sheet/*:WBWSProp*/ = ((_WB.Sheets||[])[idx]||{}/*:any*/);
|
||||
var dense = Array.isArray(ws);
|
||||
var b8 = opts.biff == 8;
|
||||
var ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
||||
var range = safe_decode_range(ws['!ref'] || "A1");
|
||||
var b8 = opts.biff == 8;
|
||||
var MAX_ROWS = b8 ? 65536 : 16384;
|
||||
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
|
||||
}
|
||||
|
||||
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "CalcMode", writeuint16(1));
|
||||
|
@ -9,7 +9,8 @@ function get_data(req, res, type) {
|
||||
var work = new Worker('worker.js');
|
||||
work.onmessage = function(e) {
|
||||
if(e.data.err) console.log(e.data.err);
|
||||
return res(e.data.data);
|
||||
var buf = new Buffer(e.data.data, "binary");
|
||||
return res(buf);
|
||||
};
|
||||
work.postMessage({action:"write", type:type, data:data});
|
||||
}
|
||||
|
28
dist/xlsx.core.min.js
generated
vendored
28
dist/xlsx.core.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
generated
vendored
2
dist/xlsx.core.min.map
generated
vendored
File diff suppressed because one or more lines are too long
42
dist/xlsx.extendscript.js
generated
vendored
42
dist/xlsx.extendscript.js
generated
vendored
@ -9147,7 +9147,7 @@ module.exports = ZStream;
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.12.10';
|
||||
XLSX.version = '0.12.11';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -13248,7 +13248,6 @@ function write_cust_props(cp) {
|
||||
if(!cp) return o.join("");
|
||||
var pid = 1;
|
||||
keys(cp).forEach(function custprop(k) { ++pid;
|
||||
// $FlowIgnore
|
||||
o[o.length] = (writextag('property', write_vt(cp[k]), {
|
||||
'fmtid': '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}',
|
||||
'pid': pid,
|
||||
@ -20971,6 +20970,13 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
|
||||
}
|
||||
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
|
||||
}
|
||||
|
||||
function check_ws(ws, sname, i) {
|
||||
if(ws && ws['!ref']) {
|
||||
var range = safe_decode_range(ws['!ref']);
|
||||
if(range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
|
||||
}
|
||||
}
|
||||
function parse_ws_xml_dim(ws, s) {
|
||||
var d = safe_decode_range(s);
|
||||
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
|
||||
@ -21442,7 +21448,14 @@ function write_ws_xml(idx, opts, wb, rels) {
|
||||
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
|
||||
var ws = wb.Sheets[s];
|
||||
if(ws == null) ws = {};
|
||||
var ref = ws['!ref']; if(ref == null) ref = 'A1';
|
||||
var ref = ws['!ref'] || 'A1';
|
||||
var range = safe_decode_range(ref);
|
||||
if(range.e.c > 0x3FFF || range.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + ref + " exceeds format limit A1:XFD1048576");
|
||||
range.e.c = Math.min(range.e.c, 0x3FFF);
|
||||
range.e.r = Math.min(range.e.c, 0xFFFFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
if(!rels) rels = {};
|
||||
ws['!comments'] = [];
|
||||
ws['!drawing'] = [];
|
||||
@ -22360,6 +22373,11 @@ function write_ws_bin(idx, opts, wb, rels) {
|
||||
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
|
||||
var c = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
|
||||
var r = safe_decode_range(ws['!ref'] || "A1");
|
||||
if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:XFD1048576");
|
||||
r.e.c = Math.min(r.e.c, 0x3FFF);
|
||||
r.e.r = Math.min(r.e.c, 0xFFFFF);
|
||||
}
|
||||
ws['!links'] = [];
|
||||
/* passed back to write_zip and removed there */
|
||||
ws['!comments'] = [];
|
||||
@ -22693,6 +22711,7 @@ function check_wb(wb) {
|
||||
if(!wb.SheetNames.length) throw new Error("Workbook is empty");
|
||||
var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
|
||||
check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
|
||||
/* TODO: validate workbook */
|
||||
}
|
||||
/* 18.2 Workbook */
|
||||
@ -22743,7 +22762,7 @@ function parse_wb_xml(data, opts) {
|
||||
/* 18.2.1 bookViews CT_BookViews ? */
|
||||
case '<bookViews': case '<bookViews>': case '</bookViews>': break;
|
||||
/* 18.2.30 workbookView CT_BookView + */
|
||||
case '<workbookView': delete y[0]; wb.WBView.push(y); break;
|
||||
case '<workbookView': case '<workbookView/>': delete y[0]; wb.WBView.push(y); break;
|
||||
case '</workbookView>': break;
|
||||
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
@ -26689,6 +26708,12 @@ function write_ws_biff2_cell(ba, cell, R, C) {
|
||||
function write_ws_biff2(ba, ws, idx, opts) {
|
||||
var dense = Array.isArray(ws);
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
|
||||
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, 0x3FFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
rr = encode_row(R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
@ -26792,9 +26817,16 @@ function write_ws_biff8(idx, opts, wb) {
|
||||
var _WB = ((wb||{}).Workbook||{});
|
||||
var _sheet = ((_WB.Sheets||[])[idx]||{});
|
||||
var dense = Array.isArray(ws);
|
||||
var b8 = opts.biff == 8;
|
||||
var ref, rr = "", cols = [];
|
||||
var range = safe_decode_range(ws['!ref'] || "A1");
|
||||
var b8 = opts.biff == 8;
|
||||
var MAX_ROWS = b8 ? 65536 : 16384;
|
||||
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
|
||||
}
|
||||
|
||||
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "CalcMode", writeuint16(1));
|
||||
|
32
dist/xlsx.full.min.js
generated
vendored
32
dist/xlsx.full.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
generated
vendored
2
dist/xlsx.full.min.map
generated
vendored
File diff suppressed because one or more lines are too long
42
dist/xlsx.js
generated
vendored
42
dist/xlsx.js
generated
vendored
@ -4,7 +4,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.12.10';
|
||||
XLSX.version = '0.12.11';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -4105,7 +4105,6 @@ function write_cust_props(cp) {
|
||||
if(!cp) return o.join("");
|
||||
var pid = 1;
|
||||
keys(cp).forEach(function custprop(k) { ++pid;
|
||||
// $FlowIgnore
|
||||
o[o.length] = (writextag('property', write_vt(cp[k]), {
|
||||
'fmtid': '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}',
|
||||
'pid': pid,
|
||||
@ -11828,6 +11827,13 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
|
||||
}
|
||||
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
|
||||
}
|
||||
|
||||
function check_ws(ws, sname, i) {
|
||||
if(ws && ws['!ref']) {
|
||||
var range = safe_decode_range(ws['!ref']);
|
||||
if(range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
|
||||
}
|
||||
}
|
||||
function parse_ws_xml_dim(ws, s) {
|
||||
var d = safe_decode_range(s);
|
||||
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
|
||||
@ -12299,7 +12305,14 @@ function write_ws_xml(idx, opts, wb, rels) {
|
||||
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
|
||||
var ws = wb.Sheets[s];
|
||||
if(ws == null) ws = {};
|
||||
var ref = ws['!ref']; if(ref == null) ref = 'A1';
|
||||
var ref = ws['!ref'] || 'A1';
|
||||
var range = safe_decode_range(ref);
|
||||
if(range.e.c > 0x3FFF || range.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + ref + " exceeds format limit A1:XFD1048576");
|
||||
range.e.c = Math.min(range.e.c, 0x3FFF);
|
||||
range.e.r = Math.min(range.e.c, 0xFFFFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
if(!rels) rels = {};
|
||||
ws['!comments'] = [];
|
||||
ws['!drawing'] = [];
|
||||
@ -13217,6 +13230,11 @@ function write_ws_bin(idx, opts, wb, rels) {
|
||||
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
|
||||
var c = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
|
||||
var r = safe_decode_range(ws['!ref'] || "A1");
|
||||
if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:XFD1048576");
|
||||
r.e.c = Math.min(r.e.c, 0x3FFF);
|
||||
r.e.r = Math.min(r.e.c, 0xFFFFF);
|
||||
}
|
||||
ws['!links'] = [];
|
||||
/* passed back to write_zip and removed there */
|
||||
ws['!comments'] = [];
|
||||
@ -13550,6 +13568,7 @@ function check_wb(wb) {
|
||||
if(!wb.SheetNames.length) throw new Error("Workbook is empty");
|
||||
var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
|
||||
check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
|
||||
/* TODO: validate workbook */
|
||||
}
|
||||
/* 18.2 Workbook */
|
||||
@ -13600,7 +13619,7 @@ function parse_wb_xml(data, opts) {
|
||||
/* 18.2.1 bookViews CT_BookViews ? */
|
||||
case '<bookViews': case '<bookViews>': case '</bookViews>': break;
|
||||
/* 18.2.30 workbookView CT_BookView + */
|
||||
case '<workbookView': delete y[0]; wb.WBView.push(y); break;
|
||||
case '<workbookView': case '<workbookView/>': delete y[0]; wb.WBView.push(y); break;
|
||||
case '</workbookView>': break;
|
||||
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
@ -17546,6 +17565,12 @@ function write_ws_biff2_cell(ba, cell, R, C) {
|
||||
function write_ws_biff2(ba, ws, idx, opts) {
|
||||
var dense = Array.isArray(ws);
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
|
||||
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, 0x3FFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
rr = encode_row(R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
@ -17649,9 +17674,16 @@ function write_ws_biff8(idx, opts, wb) {
|
||||
var _WB = ((wb||{}).Workbook||{});
|
||||
var _sheet = ((_WB.Sheets||[])[idx]||{});
|
||||
var dense = Array.isArray(ws);
|
||||
var b8 = opts.biff == 8;
|
||||
var ref, rr = "", cols = [];
|
||||
var range = safe_decode_range(ws['!ref'] || "A1");
|
||||
var b8 = opts.biff == 8;
|
||||
var MAX_ROWS = b8 ? 65536 : 16384;
|
||||
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
|
||||
}
|
||||
|
||||
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "CalcMode", writeuint16(1));
|
||||
|
26
dist/xlsx.min.js
generated
vendored
26
dist/xlsx.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
generated
vendored
2
dist/xlsx.min.map
generated
vendored
File diff suppressed because one or more lines are too long
@ -31,6 +31,20 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Rich Text Format tables (RTF) | | :o: |
|
||||
| Ethercalc Record Format (ETH) | :o: | :o: |
|
||||
|
||||
Features not supported by a given file format will not be written. Formats with
|
||||
range limits will be silently truncated:
|
||||
|
||||
| Format | Last Cell | Max Cols | Max Rows |
|
||||
|:------------------------------------------|:-----------|---------:|---------:|
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 97-2004 (XLS BIFF8) | IV65536 | 256 | 65536 |
|
||||
| Excel 5.0/95 (XLS BIFF5) | IV16384 | 256 | 16384 |
|
||||
| Excel 2.0/2.1 (XLS BIFF2) | IV16384 | 256 | 16384 |
|
||||
|
||||
Excel 2003 SpreadsheetML range limits are governed by the version of Excel and
|
||||
are not enforced by the writer.
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
<details>
|
||||
|
@ -2112,6 +2112,20 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Rich Text Format tables (RTF) | | :o: |
|
||||
| Ethercalc Record Format (ETH) | :o: | :o: |
|
||||
|
||||
Features not supported by a given file format will not be written. Formats with
|
||||
range limits will be silently truncated:
|
||||
|
||||
| Format | Last Cell | Max Cols | Max Rows |
|
||||
|:------------------------------------------|:-----------|---------:|---------:|
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | XFD1048576 | 16384 | 1048576 |
|
||||
| Excel 97-2004 (XLS BIFF8) | IV65536 | 256 | 65536 |
|
||||
| Excel 5.0/95 (XLS BIFF5) | IV16384 | 256 | 16384 |
|
||||
| Excel 2.0/2.1 (XLS BIFF2) | IV16384 | 256 | 16384 |
|
||||
|
||||
Excel 2003 SpreadsheetML range limits are governed by the version of Excel and
|
||||
are not enforced by the writer.
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.12.10",
|
||||
"version": "0.12.11",
|
||||
"author": "sheetjs",
|
||||
"description": "SheetJS Spreadsheet data parser and writer",
|
||||
"keywords": [
|
||||
|
21
test.js
21
test.js
@ -1326,6 +1326,27 @@ describe('write features', function() {
|
||||
assert(str.indexOf("<b>abc</b>") > 0);
|
||||
});
|
||||
});
|
||||
describe('sheet range limits', function() { [
|
||||
["biff2", "IV16384"],
|
||||
["biff5", "IV16384"],
|
||||
["biff8", "IV65536"],
|
||||
["xlsx", "XFD1048576"],
|
||||
["xlsb", "XFD1048576"]
|
||||
].forEach(function(r) { it(r[0], function() {
|
||||
var C = X.utils.decode_cell(r[1]);
|
||||
var wopts = {bookType:r[0], type:'binary', WTF:1};
|
||||
var wb = { SheetNames: ["Sheet1"], Sheets: { Sheet1: {} } };
|
||||
|
||||
wb.Sheets.Sheet1['!ref'] = "A1:" + X.utils.encode_cell({r:0, c:C.c});
|
||||
X.write(wb, wopts);
|
||||
wb.Sheets.Sheet1['!ref'] = "A" + X.utils.encode_row(C.r - 5) + ":" + X.utils.encode_cell({r:C.r, c:0});
|
||||
X.write(wb, wopts);
|
||||
|
||||
wb.Sheets.Sheet1['!ref'] = "A1:" + X.utils.encode_cell({r:0, c:C.c+1});
|
||||
assert.throws(function() { X.write(wb, wopts); });
|
||||
wb.Sheets.Sheet1['!ref'] = "A" + X.utils.encode_row(C.r - 5) + ":" + X.utils.encode_cell({r:C.r+1, c:0});
|
||||
assert.throws(function() { X.write(wb, wopts); });
|
||||
}); }); });
|
||||
});
|
||||
|
||||
function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
||||
|
21
tests/core.js
generated
21
tests/core.js
generated
@ -1326,6 +1326,27 @@ describe('write features', function() {
|
||||
assert(str.indexOf("<b>abc</b>") > 0);
|
||||
});
|
||||
});
|
||||
describe('sheet range limits', function() { [
|
||||
["biff2", "IV16384"],
|
||||
["biff5", "IV16384"],
|
||||
["biff8", "IV65536"],
|
||||
["xlsx", "XFD1048576"],
|
||||
["xlsb", "XFD1048576"]
|
||||
].forEach(function(r) { it(r[0], function() {
|
||||
var C = X.utils.decode_cell(r[1]);
|
||||
var wopts = {bookType:r[0], type:'binary', WTF:1};
|
||||
var wb = { SheetNames: ["Sheet1"], Sheets: { Sheet1: {} } };
|
||||
|
||||
wb.Sheets.Sheet1['!ref'] = "A1:" + X.utils.encode_cell({r:0, c:C.c});
|
||||
X.write(wb, wopts);
|
||||
wb.Sheets.Sheet1['!ref'] = "A" + X.utils.encode_row(C.r - 5) + ":" + X.utils.encode_cell({r:C.r, c:0});
|
||||
X.write(wb, wopts);
|
||||
|
||||
wb.Sheets.Sheet1['!ref'] = "A1:" + X.utils.encode_cell({r:0, c:C.c+1});
|
||||
assert.throws(function() { X.write(wb, wopts); });
|
||||
wb.Sheets.Sheet1['!ref'] = "A" + X.utils.encode_row(C.r - 5) + ":" + X.utils.encode_cell({r:C.r+1, c:0});
|
||||
assert.throws(function() { X.write(wb, wopts); });
|
||||
}); }); });
|
||||
});
|
||||
|
||||
function seq(end/*:number*/, start/*:?number*/)/*:Array<number>*/ {
|
||||
|
41
xlsx.flow.js
41
xlsx.flow.js
@ -4,7 +4,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.12.10';
|
||||
XLSX.version = '0.12.11';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true */
|
||||
@ -11923,6 +11923,13 @@ function safe_format(p/*:Cell*/, fmtid/*:number*/, fillid/*:?number*/, opts, the
|
||||
}
|
||||
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
|
||||
}
|
||||
|
||||
function check_ws(ws/*:Worksheet*/, sname/*:string*/, i/*:number*/) {
|
||||
if(ws && ws['!ref']) {
|
||||
var range = safe_decode_range(ws['!ref']);
|
||||
if(range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
|
||||
}
|
||||
}
|
||||
function parse_ws_xml_dim(ws/*:Worksheet*/, s/*:string*/) {
|
||||
var d = safe_decode_range(s);
|
||||
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
|
||||
@ -12394,7 +12401,14 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
|
||||
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
|
||||
var ws = wb.Sheets[s];
|
||||
if(ws == null) ws = {};
|
||||
var ref = ws['!ref']; if(ref == null) ref = 'A1';
|
||||
var ref = ws['!ref'] || 'A1';
|
||||
var range = safe_decode_range(ref);
|
||||
if(range.e.c > 0x3FFF || range.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + ref + " exceeds format limit A1:XFD1048576");
|
||||
range.e.c = Math.min(range.e.c, 0x3FFF);
|
||||
range.e.r = Math.min(range.e.c, 0xFFFFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
if(!rels) rels = {};
|
||||
ws['!comments'] = [];
|
||||
ws['!drawing'] = [];
|
||||
@ -13313,6 +13327,11 @@ function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) {
|
||||
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
|
||||
var c/*:string*/ = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
|
||||
var r = safe_decode_range(ws['!ref'] || "A1");
|
||||
if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:XFD1048576");
|
||||
r.e.c = Math.min(r.e.c, 0x3FFF);
|
||||
r.e.r = Math.min(r.e.c, 0xFFFFF);
|
||||
}
|
||||
ws['!links'] = [];
|
||||
/* passed back to write_zip and removed there */
|
||||
ws['!comments'] = [];
|
||||
@ -13646,6 +13665,7 @@ function check_wb(wb) {
|
||||
if(!wb.SheetNames.length) throw new Error("Workbook is empty");
|
||||
var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
|
||||
check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
|
||||
/* TODO: validate workbook */
|
||||
}
|
||||
/* 18.2 Workbook */
|
||||
@ -13696,7 +13716,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
|
||||
/* 18.2.1 bookViews CT_BookViews ? */
|
||||
case '<bookViews': case '<bookViews>': case '</bookViews>': break;
|
||||
/* 18.2.30 workbookView CT_BookView + */
|
||||
case '<workbookView': delete y[0]; wb.WBView.push(y); break;
|
||||
case '<workbookView': case '<workbookView/>': delete y[0]; wb.WBView.push(y); break;
|
||||
case '</workbookView>': break;
|
||||
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
@ -17655,6 +17675,12 @@ function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:n
|
||||
function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/*::, wb:Workbook*/) {
|
||||
var dense = Array.isArray(ws);
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
||||
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, 0x3FFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
rr = encode_row(R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
@ -17759,9 +17785,16 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
var _WB/*:WBWBProps*/ = ((wb||{}).Workbook||{}/*:any*/);
|
||||
var _sheet/*:WBWSProp*/ = ((_WB.Sheets||[])[idx]||{}/*:any*/);
|
||||
var dense = Array.isArray(ws);
|
||||
var b8 = opts.biff == 8;
|
||||
var ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
||||
var range = safe_decode_range(ws['!ref'] || "A1");
|
||||
var b8 = opts.biff == 8;
|
||||
var MAX_ROWS = b8 ? 65536 : 16384;
|
||||
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
|
||||
}
|
||||
|
||||
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "CalcMode", writeuint16(1));
|
||||
|
41
xlsx.js
generated
41
xlsx.js
generated
@ -4,7 +4,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.12.10';
|
||||
XLSX.version = '0.12.11';
|
||||
var current_codepage = 1200, current_ansi = 1252;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -11827,6 +11827,13 @@ function safe_format(p, fmtid, fillid, opts, themes, styles) {
|
||||
}
|
||||
} catch(e) { if(opts.WTF && styles.Fills) throw e; }
|
||||
}
|
||||
|
||||
function check_ws(ws, sname, i) {
|
||||
if(ws && ws['!ref']) {
|
||||
var range = safe_decode_range(ws['!ref']);
|
||||
if(range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
|
||||
}
|
||||
}
|
||||
function parse_ws_xml_dim(ws, s) {
|
||||
var d = safe_decode_range(s);
|
||||
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
|
||||
@ -12298,7 +12305,14 @@ function write_ws_xml(idx, opts, wb, rels) {
|
||||
var s = wb.SheetNames[idx], sidx = 0, rdata = "";
|
||||
var ws = wb.Sheets[s];
|
||||
if(ws == null) ws = {};
|
||||
var ref = ws['!ref']; if(ref == null) ref = 'A1';
|
||||
var ref = ws['!ref'] || 'A1';
|
||||
var range = safe_decode_range(ref);
|
||||
if(range.e.c > 0x3FFF || range.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + ref + " exceeds format limit A1:XFD1048576");
|
||||
range.e.c = Math.min(range.e.c, 0x3FFF);
|
||||
range.e.r = Math.min(range.e.c, 0xFFFFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
if(!rels) rels = {};
|
||||
ws['!comments'] = [];
|
||||
ws['!drawing'] = [];
|
||||
@ -13216,6 +13230,11 @@ function write_ws_bin(idx, opts, wb, rels) {
|
||||
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
|
||||
var c = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
|
||||
var r = safe_decode_range(ws['!ref'] || "A1");
|
||||
if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:XFD1048576");
|
||||
r.e.c = Math.min(r.e.c, 0x3FFF);
|
||||
r.e.r = Math.min(r.e.c, 0xFFFFF);
|
||||
}
|
||||
ws['!links'] = [];
|
||||
/* passed back to write_zip and removed there */
|
||||
ws['!comments'] = [];
|
||||
@ -13549,6 +13568,7 @@ function check_wb(wb) {
|
||||
if(!wb.SheetNames.length) throw new Error("Workbook is empty");
|
||||
var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
|
||||
check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
|
||||
/* TODO: validate workbook */
|
||||
}
|
||||
/* 18.2 Workbook */
|
||||
@ -13599,7 +13619,7 @@ function parse_wb_xml(data, opts) {
|
||||
/* 18.2.1 bookViews CT_BookViews ? */
|
||||
case '<bookViews': case '<bookViews>': case '</bookViews>': break;
|
||||
/* 18.2.30 workbookView CT_BookView + */
|
||||
case '<workbookView': delete y[0]; wb.WBView.push(y); break;
|
||||
case '<workbookView': case '<workbookView/>': delete y[0]; wb.WBView.push(y); break;
|
||||
case '</workbookView>': break;
|
||||
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
@ -17545,6 +17565,12 @@ function write_ws_biff2_cell(ba, cell, R, C) {
|
||||
function write_ws_biff2(ba, ws, idx, opts) {
|
||||
var dense = Array.isArray(ws);
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = [];
|
||||
if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, 0x3FFF);
|
||||
ref = encode_range(range);
|
||||
}
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
rr = encode_row(R);
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
@ -17648,9 +17674,16 @@ function write_ws_biff8(idx, opts, wb) {
|
||||
var _WB = ((wb||{}).Workbook||{});
|
||||
var _sheet = ((_WB.Sheets||[])[idx]||{});
|
||||
var dense = Array.isArray(ws);
|
||||
var b8 = opts.biff == 8;
|
||||
var ref, rr = "", cols = [];
|
||||
var range = safe_decode_range(ws['!ref'] || "A1");
|
||||
var b8 = opts.biff == 8;
|
||||
var MAX_ROWS = b8 ? 65536 : 16384;
|
||||
if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
|
||||
if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
|
||||
range.e.c = Math.min(range.e.c, 0xFF);
|
||||
range.e.r = Math.min(range.e.c, MAX_ROWS-1);
|
||||
}
|
||||
|
||||
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "CalcMode", writeuint16(1));
|
||||
|
Loading…
Reference in New Issue
Block a user