updating to 0.11.7
This commit is contained in:
parent
3649c02041
commit
5ad2d6e47d
|
@ -22,7 +22,7 @@ var opts = ({cellNF: true}/*:any*/);
|
|||
var TYPE = browser ? "binary" : "buffer";
|
||||
opts.type = TYPE;
|
||||
var fullex = [".xlsb", /*".xlsm",*/ ".xlsx"/*, ".xlml", ".xls"*/];
|
||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "biff5", "biff8", "xlml", "sylk", "dif"];
|
||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "biff5", "biff8", "xlml", "sylk", "dif", "dbf"];
|
||||
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
|
||||
if(typeof process != 'undefined' && ((process||{}).env)) {
|
||||
opts.WTF = true;
|
||||
|
@ -505,7 +505,7 @@ describe('parse options', function() {
|
|||
X.utils.sheet_to_csv(wb.Sheets.Merge);
|
||||
X.utils.sheet_to_json(wb.Sheets.Merge);
|
||||
X.utils.sheet_to_formulae(wb.Sheets.Merge);
|
||||
ofmt.forEach(function(f) { X.write(wb, {type:TYPE, bookType:f}); });
|
||||
ofmt.forEach(function(f) { if(f != "dbf") X.write(wb, {type:TYPE, bookType:f}); });
|
||||
});
|
||||
});
|
||||
function checkcells(wb, A46, B26, C16, D2) {
|
||||
|
@ -541,6 +541,7 @@ describe('parse options', function() {
|
|||
});
|
||||
it('bookProps && bookSheets should not generate sheets', function() {
|
||||
PMPaths.forEach(function(p) {
|
||||
if(!fs.existsSync(p)) return;
|
||||
var wb = X.read(fs.readFileSync(p), {type:TYPE, bookProps:true, bookSheets:true});
|
||||
assert(typeof wb.Sheets === 'undefined');
|
||||
});
|
||||
|
@ -624,6 +625,7 @@ describe('output formats', function() {
|
|||
["sylk", false, true],
|
||||
["html", true, true],
|
||||
["dif", false, true],
|
||||
["dbf", false, false],
|
||||
["prn", false, true]
|
||||
];
|
||||
function RT(T) {
|
||||
|
@ -763,7 +765,7 @@ describe('parse features', function() {
|
|||
|
||||
describe('comments', function() {
|
||||
if(fs.existsSync(paths.swcxlsx)) it('should have comment as part of cell properties', function(){
|
||||
var X = require(modp);
|
||||
X = require(modp);
|
||||
var sheet = 'Sheet1';
|
||||
var wb1=X.read(fs.readFileSync(paths.swcxlsx), {type:TYPE});
|
||||
var wb2=X.read(fs.readFileSync(paths.swcxlsb), {type:TYPE});
|
||||
|
@ -1866,10 +1868,11 @@ describe('js -> file -> js', function() {
|
|||
var wb, BIN="binary";
|
||||
var bef = (function() {
|
||||
var ws = X.utils.aoa_to_sheet([
|
||||
[1,2,3],
|
||||
[true, false, null, "sheetjs"],
|
||||
["foo", "bar", fixdate, "0.3"],
|
||||
["baz", 6.9, "qux"]
|
||||
["number", "bool", "string", "date"],
|
||||
[1, true, "sheet"],
|
||||
[2, false, "dot"],
|
||||
[6.9, false, "JS", fixdate],
|
||||
[72.62, true, "0.3"]
|
||||
]);
|
||||
wb = { SheetNames: ['Sheet1'], Sheets: {Sheet1: ws} };
|
||||
});
|
||||
|
@ -1883,13 +1886,13 @@ describe('js -> file -> js', function() {
|
|||
it(f, function() {
|
||||
var newwb = X.read(X.write(wb, {type:BIN, bookType: f}), {type:BIN});
|
||||
var cb = function(cell) { eqcell(wb, newwb, 'Sheet1', cell); };
|
||||
['A1', 'B1', 'C1'].forEach(cb); /* int */
|
||||
['B4'].forEach(cb); /* double */
|
||||
['A2', 'B2'].forEach(cb); /* bool */
|
||||
['D2', 'A3', 'B3', 'A4', 'C4'].forEach(cb); /* string */
|
||||
if(!DIF_XL) cb('C3'); /* date */
|
||||
if(DIF_XL && f == "dif") assert.equal(get_cell(newwb.Sheets.Sheet1, 'D3').v, '=""0.3""');// dif forces string formula
|
||||
else eqcell(wb, newwb, 'Sheet1', 'D3');
|
||||
['A2', 'A3'].forEach(cb); /* int */
|
||||
['A4', 'A5'].forEach(cb); /* double */
|
||||
['B2', 'B3'].forEach(cb); /* bool */
|
||||
['C2', 'C3'].forEach(cb); /* string */
|
||||
if(!DIF_XL) cb('D4'); /* date */
|
||||
if(DIF_XL && f == "dif") assert.equal(get_cell(newwb.Sheets.Sheet1, 'C5').v, '=""0.3""');// dif forces string formula
|
||||
else eqcell(wb, newwb, 'Sheet1', 'C5');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
195
xlsx.js
195
xlsx.js
|
@ -4,7 +4,7 @@
|
|||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.11.6';
|
||||
XLSX.version = '0.11.7';
|
||||
var current_codepage = 1200;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
|
@ -1026,7 +1026,7 @@ var DO_NOT_EXPORT_CFB = true;
|
|||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '0.13.1';
|
||||
exports.version = '0.13.2';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l, r) {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
|
@ -1047,6 +1047,8 @@ function filename(p) {
|
|||
var c = p.lastIndexOf("/");
|
||||
return (c === -1) ? p : p.slice(c+1);
|
||||
}
|
||||
var fs;
|
||||
function get_fs() { return fs || (fs = require('fs')); }
|
||||
function parse(file, options) {
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
|
@ -1344,9 +1346,8 @@ function read_date(blob, offset) {
|
|||
return new Date(( ( (__readUInt32LE(blob,offset+4)/1e7)*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7 ) - 11644473600)*1000);
|
||||
}
|
||||
|
||||
var fs;
|
||||
function read_file(filename, options) {
|
||||
if(fs == null) fs = require('fs');
|
||||
get_fs();
|
||||
return parse(fs.readFileSync(filename), options);
|
||||
}
|
||||
|
||||
|
@ -1621,6 +1622,7 @@ var consts = {
|
|||
};
|
||||
|
||||
function write_file(cfb, filename, options) {
|
||||
get_fs();
|
||||
var o = _write(cfb, options);
|
||||
fs.writeFileSync(filename, o);
|
||||
}
|
||||
|
@ -1634,7 +1636,7 @@ function a2s(o) {
|
|||
function write(cfb, options) {
|
||||
var o = _write(cfb, options);
|
||||
switch(options && options.type) {
|
||||
case "file": fs.writeFileSync(options.filename, (o)); return o;
|
||||
case "file": get_fs(); fs.writeFileSync(options.filename, (o)); return o;
|
||||
case "binary": return a2s(o);
|
||||
case "base64": return Base64.encode(a2s(o));
|
||||
}
|
||||
|
@ -1656,7 +1658,7 @@ function cfb_add(cfb, name, content, opts) {
|
|||
if(fpath.slice(-1) != "/") fpath += "/";
|
||||
fpath = (fpath + name).replace("//","/");
|
||||
}
|
||||
file = ({name: filename(name)});
|
||||
file = ({name: filename(name), type: 2});
|
||||
cfb.FileIndex.push(file);
|
||||
cfb.FullPaths.push(fpath);
|
||||
CFB.utils.cfb_gc(cfb);
|
||||
|
@ -4339,6 +4341,14 @@ function parse_XLUnicodeString2(blob, length, opts) {
|
|||
if(cch === 0) { blob.l++; return ""; }
|
||||
return blob.read_shift(cch, 'sbcs-cont');
|
||||
}
|
||||
/* TODO: BIFF5 and lower, codepage awareness */
|
||||
function write_XLUnicodeString(str, opts, o) {
|
||||
if(!o) o = new_buf(3 + 2 * str.length);
|
||||
o.write_shift(2, str.length);
|
||||
o.write_shift(1, 1);
|
||||
o.write_shift(31, str, 'utf16le');
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.61 ControlInfo */
|
||||
function parse_ControlInfo(blob, length, opts) {
|
||||
|
@ -5579,9 +5589,105 @@ function dbf_to_workbook(buf, opts) {
|
|||
catch(e) { if(opts && opts.WTF) throw e; }
|
||||
return ({SheetNames:[],Sheets:{}});
|
||||
}
|
||||
|
||||
var _RLEN = { 'B': 8, 'C': 250, 'L': 1, 'D': 8, '?': 0, '': 0 };
|
||||
function sheet_to_dbf(ws, opts) {
|
||||
var o = opts || {};
|
||||
if(o.type == "string") throw new Error("Cannot write DBF to JS string");
|
||||
var ba = buf_array();
|
||||
var aoa = sheet_to_json(ws, {header:1, raw:true, cellDates:true});
|
||||
var headers = aoa[0], data = aoa.slice(1);
|
||||
var i = 0, j = 0, hcnt = 0, rlen = 1;
|
||||
for(i = 0; i < headers.length; ++i) {
|
||||
if(i == null) continue;
|
||||
++hcnt;
|
||||
if(typeof headers[i] !== 'string') throw new Error("DBF Invalid column name");
|
||||
if(headers.indexOf(headers[i]) !== i) for(j=0; j<1024;++j)
|
||||
if(headers.indexOf(headers[i] + "_" + j) == -1) { headers[i] += "_" + j; break; }
|
||||
}
|
||||
var range = safe_decode_range(ws['!ref']);
|
||||
var coltypes = [];
|
||||
for(i = 0; i <= range.e.c - range.s.c; ++i) {
|
||||
var col = [];
|
||||
for(j=0; j < data.length; ++j) {
|
||||
if(data[j][i] != null) col.push(data[j][i]);
|
||||
}
|
||||
if(col.length == 0 || headers[i] == null) { coltypes[i] = '?'; continue; }
|
||||
var guess = '', _guess = '';
|
||||
for(j = 0; j < col.length; ++j) {
|
||||
switch(typeof col[j]) {
|
||||
/* TODO: check if L2 compat is desired */
|
||||
case 'number': _guess = 'B'; break;
|
||||
case 'string': _guess = 'C'; break;
|
||||
case 'boolean': _guess = 'L'; break;
|
||||
case 'object': _guess = col[j] instanceof Date ? 'D' : 'C'; break;
|
||||
default: _guess = 'C';
|
||||
}
|
||||
guess = guess && guess != _guess ? 'C' : _guess;
|
||||
if(guess == 'C') break;
|
||||
}
|
||||
rlen += _RLEN[guess] || 0;
|
||||
coltypes[i] = guess;
|
||||
}
|
||||
|
||||
var h = ba.next(32);
|
||||
h.write_shift(4, 0x13021130);
|
||||
h.write_shift(4, data.length);
|
||||
h.write_shift(2, 296 + 32 * hcnt);
|
||||
h.write_shift(2, rlen);
|
||||
for(i=0; i < 4; ++i) h.write_shift(4, 0);
|
||||
h.write_shift(4, 0x00000300); // TODO: CP
|
||||
|
||||
for(i = 0, j = 0; i < headers.length; ++i) {
|
||||
if(headers[i] == null) continue;
|
||||
var hf = ba.next(32);
|
||||
var _f = (headers[i].slice(-10) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00").slice(0, 11);
|
||||
hf.write_shift(1, _f, "sbcs");
|
||||
hf.write_shift(1, coltypes[i] == '?' ? 'C' : coltypes[i], "sbcs");
|
||||
hf.write_shift(4, j);
|
||||
hf.write_shift(1, _RLEN[coltypes[i]] || 0);
|
||||
hf.write_shift(1, 0);
|
||||
hf.write_shift(1, 0x02);
|
||||
hf.write_shift(4, 0);
|
||||
hf.write_shift(1, 0);
|
||||
hf.write_shift(4, 0);
|
||||
hf.write_shift(4, 0);
|
||||
j += _RLEN[coltypes[i]] || 0;
|
||||
}
|
||||
|
||||
var hb = ba.next(264);
|
||||
hb.write_shift(4, 0x0000000D);
|
||||
for(i=0; i < 65;++i) hb.write_shift(4, 0x00000000);
|
||||
for(i=0; i < data.length; ++i) {
|
||||
var rout = ba.next(rlen);
|
||||
rout.write_shift(1, 0);
|
||||
for(j=0; j<headers.length; ++j) {
|
||||
if(headers[j] == null) continue;
|
||||
switch(coltypes[j]) {
|
||||
case 'L': rout.write_shift(1, data[i][j] == null ? 0x3F : data[i][j] ? 0x54 : 0x46); break;
|
||||
case 'B': rout.write_shift(8, data[i][j]||0, 'f'); break;
|
||||
case 'D':
|
||||
if(!data[i][j]) rout.write_shift(8, "00000000", "sbcs");
|
||||
else {
|
||||
rout.write_shift(4, ("0000"+data[i][j].getFullYear()).slice(-4), "sbcs");
|
||||
rout.write_shift(2, ("00"+(data[i][j].getMonth()+1)).slice(-2), "sbcs");
|
||||
rout.write_shift(2, ("00"+data[i][j].getDate()).slice(-2), "sbcs");
|
||||
} break;
|
||||
case 'C':
|
||||
var _s = String(data[i][j]||"");
|
||||
rout.write_shift(1, _s, "sbcs");
|
||||
for(hcnt=0; hcnt < 250-_s.length; ++hcnt) rout.write_shift(1, 0x20); break;
|
||||
}
|
||||
}
|
||||
// data
|
||||
}
|
||||
ba.next(1).write_shift(1, 0x1A);
|
||||
return ba.end();
|
||||
}
|
||||
return {
|
||||
to_workbook: dbf_to_workbook,
|
||||
to_sheet: dbf_to_sheet
|
||||
to_sheet: dbf_to_sheet,
|
||||
from_sheet: sheet_to_dbf
|
||||
};
|
||||
})();
|
||||
|
||||
|
@ -8670,6 +8776,15 @@ function make_vba_xls(cfb) {
|
|||
});
|
||||
return CFB.write(newcfb);
|
||||
}
|
||||
|
||||
function fill_vba_xls(cfb, vba) {
|
||||
vba.FullPaths.forEach(function(p, i) {
|
||||
if(i == 0) return;
|
||||
var newpath = p.replace(/[^/]*[/]/, "/_VBA_PROJECT_CUR/");
|
||||
if(newpath.slice(-1) !== "/") CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
|
||||
});
|
||||
}
|
||||
|
||||
RELS.DS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/dialogsheet";
|
||||
RELS.MS = "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet";
|
||||
|
||||
|
@ -14570,10 +14685,10 @@ function safe_format_xf(p, opts, date1904) {
|
|||
else p.w = SSF._general(p.v);
|
||||
}
|
||||
else p.w = SSF.format(fmtid,p.v, {date1904:!!date1904});
|
||||
if(opts.cellDates && fmtid && p.t == 'n' && SSF.is_date(SSF._table[fmtid] || String(fmtid))) {
|
||||
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
||||
}
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
if(opts.cellDates && fmtid && p.t == 'n' && SSF.is_date(SSF._table[fmtid] || String(fmtid))) {
|
||||
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
||||
}
|
||||
}
|
||||
|
||||
function make_cell(val, ixfe, t) {
|
||||
|
@ -15147,7 +15262,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
|||
/* empty */
|
||||
} break;
|
||||
case 'CodeName': {
|
||||
/* empty */
|
||||
if(!cur_sheet) Workbook.WBProps.codeName = val;
|
||||
} break;
|
||||
case 'GUIDTypeLib': {
|
||||
/* empty */
|
||||
|
@ -15381,6 +15496,7 @@ function write_xlscfb(wb, opts) {
|
|||
}
|
||||
CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
|
||||
// TODO: SI, DSI, CO
|
||||
if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"}));
|
||||
return cfb;
|
||||
}
|
||||
/* [MS-XLSB] 2.3 Record Enumeration */
|
||||
|
@ -16777,6 +16893,8 @@ function write_ws_biff8(idx, opts, wb) {
|
|||
write_ws_biff8_cell(ba, cell, R, C, opts);
|
||||
}
|
||||
}
|
||||
var cname = ((((wb||{}).Workbook||{}).Sheets||[])[idx]||{}).name||s;
|
||||
write_biff_rec(ba, "CodeName", write_XLUnicodeString(cname, opts));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "EOF");
|
||||
return ba.end();
|
||||
|
@ -16796,6 +16914,11 @@ function write_biff8_global(wb, bufs, opts) {
|
|||
write_biff_rec(A, "CodePage", writeuint16(b8 ? 0x04b0 : 0x04E4));
|
||||
if(b8) write_biff_rec(A, "DSF", writeuint16(0));
|
||||
write_biff_rec(A, "RRTabId", write_RRTabId(wb.SheetNames.length));
|
||||
if(b8 && wb.vbaraw) {
|
||||
write_biff_rec(A, "ObProj");
|
||||
var cname = ((wb.Workbook||{}).WBProps||{}).codeName || "ThisWorkbook";
|
||||
write_biff_rec(A, "CodeName", write_XLUnicodeString(cname, opts));
|
||||
}
|
||||
write_biff_rec(A, "BuiltInFnGroupCount", writeuint16(0x11));
|
||||
write_biff_rec(A, "WinProtect", writebool(false));
|
||||
write_biff_rec(A, "Protect", writebool(false));
|
||||
|
@ -17768,12 +17891,16 @@ var zip = new jszip();
|
|||
return zip;
|
||||
}
|
||||
|
||||
/* actual implementation elsewhere, wrappers are for read/write */
|
||||
function write_sheet_index(wb, sheet) {
|
||||
if(!sheet) return 0;
|
||||
var idx = wb.SheetNames.indexOf(sheet);
|
||||
if(idx == -1) throw new Error("Sheet not found: " + sheet);
|
||||
return idx;
|
||||
}
|
||||
|
||||
function write_obj_str(factory) {
|
||||
return function write_str(wb, o) {
|
||||
var idx = 0;
|
||||
for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
|
||||
if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
|
||||
var idx = write_sheet_index(wb, o.sheet);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o, wb);
|
||||
};
|
||||
}
|
||||
|
@ -17785,6 +17912,9 @@ var write_dif_str = write_obj_str(DIF);
|
|||
var write_prn_str = write_obj_str(PRN);
|
||||
var write_rtf_str = write_obj_str(RTF);
|
||||
var write_txt_str = write_obj_str({from_sheet:sheet_to_txt});
|
||||
// $FlowIgnore
|
||||
var write_dbf_buf = write_obj_str(DBF);
|
||||
|
||||
function fix_opts_func(defaults) {
|
||||
return function fix_opts(opts) {
|
||||
for(var i = 0; i != defaults.length; ++i) {
|
||||
|
@ -18358,13 +18488,15 @@ function writeSync(wb, opts) {
|
|||
case 'txt': return write_stxt_type(write_txt_str(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o, "\ufeff");
|
||||
case 'dif': return write_string_type(write_dif_str(wb, o), o);
|
||||
// $FlowIgnore
|
||||
case 'dbf': return write_binary_type(write_dbf_buf(wb, o), o);
|
||||
case 'prn': return write_string_type(write_prn_str(wb, o), o);
|
||||
case 'rtf': return write_string_type(write_rtf_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
|
||||
case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
|
||||
case 'biff4': if(!o.biff) o.biff = 4; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff5': if(!o.biff) o.biff = 5; return write_cfb_type(wb, o);
|
||||
case 'biff5': if(!o.biff) o.biff = 5; /* falls through */
|
||||
case 'biff8':
|
||||
case 'xls': if(!o.biff) o.biff = 8; return write_cfb_type(wb, o);
|
||||
case 'xlsx':
|
||||
|
@ -18375,26 +18507,17 @@ function writeSync(wb, opts) {
|
|||
}
|
||||
}
|
||||
|
||||
function resolve_book_type(o/*?WriteFileOpts*/) {
|
||||
if(!o.bookType) switch(o.file.slice(o.file.lastIndexOf(".")).toLowerCase()) {
|
||||
case '.xlsx': o.bookType = 'xlsx'; break;
|
||||
case '.xlsm': o.bookType = 'xlsm'; break;
|
||||
case '.xlsb': o.bookType = 'xlsb'; break;
|
||||
case '.fods': o.bookType = 'fods'; break;
|
||||
case '.xlml': o.bookType = 'xlml'; break;
|
||||
case '.sylk': o.bookType = 'sylk'; break;
|
||||
case '.html': o.bookType = 'html'; break;
|
||||
case '.xls': o.bookType = 'biff8'; break;
|
||||
case '.xml': o.bookType = 'xml'; break;
|
||||
case '.ods': o.bookType = 'ods'; break;
|
||||
case '.csv': o.bookType = 'csv'; break;
|
||||
case '.txt': o.bookType = 'txt'; break;
|
||||
case '.dif': o.bookType = 'dif'; break;
|
||||
case '.prn': o.bookType = 'prn'; break;
|
||||
case '.rtf': o.bookType = 'rtf'; break;
|
||||
case '.slk': o.bookType = 'sylk'; break;
|
||||
case '.htm': o.bookType = 'html'; break;
|
||||
}
|
||||
function resolve_book_type(o) {
|
||||
if(o.bookType) return;
|
||||
var _BT = {
|
||||
"xls": "biff8",
|
||||
"htm": "html",
|
||||
"slk": "sylk",
|
||||
"Sh33tJS": "WTF"
|
||||
};
|
||||
var ext = o.file.slice(o.file.lastIndexOf(".")).toLowerCase();
|
||||
if(ext.match(/^\.[a-z]+$/)) o.bookType = ext.slice(1);
|
||||
o.bookType = _BT[o.bookType] || o.bookType;
|
||||
}
|
||||
|
||||
function writeFileSync(wb, filename, opts) {
|
||||
|
|
Loading…
Reference in New Issue