version bump 0.8.6: module flush
- fixes #571 h/t @FredrikL @mooyoul - pin npm version in travis, see https://github.com/npm/npm/issues/15855 - updated CFB (fixes #569 h/t @e12009) - remove BOM for some SpreadsheetML files case insensitive zip file search fixes: - fixes #439 h/t @chikh - fixes #440 h/t @chikh - fixes #567 h/t @duzun
This commit is contained in:
parent
7683e213ea
commit
5ae6b1965b
|
@ -9,7 +9,7 @@ node_js:
|
|||
- "0.9"
|
||||
- "0.8"
|
||||
before_install:
|
||||
- "npm install -g npm@next"
|
||||
- "npm install -g npm@4.3.0"
|
||||
- "npm install -g mocha@2.x voc"
|
||||
- "npm install blanket"
|
||||
- "npm install xlsjs"
|
||||
|
|
4
Makefile
4
Makefile
|
@ -30,7 +30,7 @@ $(FLOWTARGET): $(DEPS)
|
|||
bits/01_version.js: package.json
|
||||
echo "$(ULIB).version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@
|
||||
|
||||
bits/18_cfb.js: node_modules/cfb/dist/xlscfb.js
|
||||
bits/18_cfb.js: node_modules/cfb/xlscfb.flow.js
|
||||
cp $^ $@
|
||||
|
||||
.PHONY: clean
|
||||
|
@ -76,7 +76,7 @@ ods: ods.js
|
|||
|
||||
ODSDEPS=$(sort $(wildcard odsbits/*.js))
|
||||
ods.flow.js: $(ODSDEPS) ## Build ODS support library
|
||||
cat $(ODSDEPS) | tr -d '\15\32' > $@
|
||||
cat $^ | tr -d '\15\32' > $@
|
||||
|
||||
|
||||
## Testing
|
||||
|
|
|
@ -559,6 +559,7 @@ file but Excel will know how to handle it. This library applies similar logic:
|
|||
| `0x09` | BIFF Stream | BIFF 2/3/4/5 |
|
||||
| `0x3C` | XML | SpreadsheetML or Flat ODS or UOS1 |
|
||||
| `0x50` | ZIP Archive | XLSB or XLSX/M or ODS or UOS2 |
|
||||
| `0xFE` | UTF8 Text | SpreadsheetML or Flat ODS or UOS1 |
|
||||
|
||||
## Writing Options
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
XLSX.version = '0.8.5';
|
||||
XLSX.version = '0.8.6';
|
||||
|
|
|
@ -7,12 +7,18 @@ function reset_cp() { set_cp(1200); }
|
|||
var set_cp = function(cp) { current_codepage = cp; };
|
||||
|
||||
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
|
||||
var debom_xml = function(data) { return data; };
|
||||
var debom = function(data/*:string*/)/*:string*/ {
|
||||
var c1 = data.charCodeAt(0), c2 = data.charCodeAt(1);
|
||||
if(c1 == 0xFF && c2 == 0xFE) return data.substr(2);
|
||||
if(c1 == 0xFE && c2 == 0xFF) return data.substr(2);
|
||||
if(c1 == 0xFEFF) return data.substr(1);
|
||||
return data;
|
||||
};
|
||||
|
||||
var _getchar = function _gc1(x) { return String.fromCharCode(x); };
|
||||
if(typeof cptable !== 'undefined') {
|
||||
set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
|
||||
debom_xml = function(data) {
|
||||
debom = function(data) {
|
||||
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
|
||||
return data;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var Base64 = (function make_b64(){
|
||||
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
return {
|
||||
encode: function(input, utf8) {
|
||||
encode: function(input/*:string*/, utf8)/*:string*/ {
|
||||
var o = "";
|
||||
var c1, c2, c3, e1, e2, e3, e4;
|
||||
for(var i = 0; i < input.length; ) {
|
||||
|
@ -18,7 +18,7 @@ var Base64 = (function make_b64(){
|
|||
}
|
||||
return o;
|
||||
},
|
||||
decode: function b64_decode(input, utf8) {
|
||||
decode: function b64_decode(input/*:string*/, utf8)/*:string*/ {
|
||||
var o = "";
|
||||
var c1, c2, c3;
|
||||
var e1, e2, e3, e4;
|
||||
|
|
|
@ -1,12 +1,36 @@
|
|||
var DO_NOT_EXPORT_CFB = true;
|
||||
/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||
/*::
|
||||
declare var Base64:any;
|
||||
declare var ReadShift:any;
|
||||
declare var CheckField:any;
|
||||
declare var prep_blob:any;
|
||||
declare var __readUInt32LE:any;
|
||||
declare var __readInt32LE:any;
|
||||
declare var __toBuffer:any;
|
||||
declare var __utf16le:any;
|
||||
declare var bconcat:any;
|
||||
declare var s2a:any;
|
||||
declare var chr0:any;
|
||||
declare var chr1:any;
|
||||
*/
|
||||
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint eqnull:true */
|
||||
|
||||
/*::
|
||||
declare var DO_NOT_EXPORT_CFB:any;
|
||||
type SectorEntry = any;
|
||||
type SectorList = {
|
||||
(k:string|number):SectorEntry;
|
||||
name:?string;
|
||||
fat_addrs:any;
|
||||
ssz:number;
|
||||
}
|
||||
*/
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '0.10.2';
|
||||
exports.version = '0.11.0';
|
||||
function parse(file) {
|
||||
var mver = 3; // major version
|
||||
var ssz = 512; // sector size
|
||||
|
@ -19,7 +43,7 @@ var difat_start = 0; // first mini FAT sector location
|
|||
var fat_addrs = []; // locations of FAT sectors
|
||||
|
||||
/* [MS-CFB] 2.2 Compound File Header */
|
||||
var blob = file.slice(0,512);
|
||||
var blob/*:any*/ = file.slice(0,512);
|
||||
prep_blob(blob, 0);
|
||||
|
||||
/* major version */
|
||||
|
@ -79,7 +103,7 @@ var sectors = sectorify(file, ssz);
|
|||
sleuth_fat(difat_start, ndfs, sectors, ssz, fat_addrs);
|
||||
|
||||
/** Chains */
|
||||
var sector_list = make_sector_list(sectors, dir_start, fat_addrs, ssz);
|
||||
var sector_list/*:SectorList*/ = make_sector_list(sectors, dir_start, fat_addrs, ssz);
|
||||
|
||||
sector_list[dir_start].name = "!Directory";
|
||||
if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT";
|
||||
|
@ -88,7 +112,7 @@ sector_list.fat_addrs = fat_addrs;
|
|||
sector_list.ssz = ssz;
|
||||
|
||||
/* [MS-CFB] 2.6.1 Compound File Directory Entry */
|
||||
var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {};
|
||||
var files = {}, Paths/*:any*/ = [], FileIndex = [], FullPaths = [], FullPathDir = {};
|
||||
read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex);
|
||||
|
||||
build_full_paths(FileIndex, FullPathDir, FullPaths, Paths);
|
||||
|
@ -197,7 +221,7 @@ function make_find_path(FullPaths, Paths, FileIndex, files, root_name) {
|
|||
var UCPaths = new Array(Paths.length), i;
|
||||
for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase().replace(chr0,'').replace(chr1,'!');
|
||||
for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!');
|
||||
return function find_path(path) {
|
||||
return function find_path(path/*:string*/) {
|
||||
var k;
|
||||
if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; }
|
||||
else k = path.indexOf("/") !== -1;
|
||||
|
@ -216,6 +240,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) {
|
|||
if(cnt !== 0) throw "DIFAT chain shorter than expected";
|
||||
} else if(idx !== -1 /*FREESECT*/) {
|
||||
var sector = sectors[idx], m = (ssz>>>2)-1;
|
||||
if(!sector) return;
|
||||
for(var i = 0; i < m; ++i) {
|
||||
if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
|
||||
fat_addrs.push(q);
|
||||
|
@ -239,13 +264,14 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) {
|
|||
var addr = fat_addrs[Math.floor(j*4/ssz)];
|
||||
jj = ((j*4) & modulus);
|
||||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz;
|
||||
if(!sectors[addr]) break;
|
||||
j = __readInt32LE(sectors[addr], jj);
|
||||
}
|
||||
return {nodes: buf, data:__toBuffer([buf_chain])};
|
||||
}
|
||||
|
||||
/** Chase down the sector linked lists */
|
||||
function make_sector_list(sectors, dir_start, fat_addrs, ssz) {
|
||||
function make_sector_list(sectors, dir_start, fat_addrs, ssz/*:number*/)/*:any*/ {
|
||||
var sl = sectors.length, sector_list = new Array(sl);
|
||||
var chkd = new Array(sl), buf, buf_chain;
|
||||
var modulus = ssz - 1, i, j, k, jj;
|
||||
|
@ -261,6 +287,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) {
|
|||
var addr = fat_addrs[Math.floor(j*4/ssz)];
|
||||
jj = ((j*4) & modulus);
|
||||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz;
|
||||
if(!sectors[addr]) break;
|
||||
j = __readInt32LE(sectors[addr], jj);
|
||||
}
|
||||
sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])};
|
||||
|
@ -281,7 +308,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
|||
if(namelen === 0) continue;
|
||||
name = __utf16le(blob,0,namelen-pl);
|
||||
Paths.push(name);
|
||||
o = {
|
||||
o = ({
|
||||
name: name,
|
||||
type: blob.read_shift(1),
|
||||
color: blob.read_shift(1),
|
||||
|
@ -290,7 +317,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
|||
C: blob.read_shift(4, 'i'),
|
||||
clsid: blob.read_shift(16),
|
||||
state: blob.read_shift(4, 'i')
|
||||
};
|
||||
}/*:any*/);
|
||||
ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
|
||||
if(ctime !== 0) {
|
||||
o.ctime = ctime; o.ct = read_date(blob, blob.l-8);
|
||||
|
@ -328,12 +355,12 @@ function read_date(blob, offset) {
|
|||
}
|
||||
|
||||
var fs;
|
||||
function readFileSync(filename, options) {
|
||||
function readFileSync(filename/*:string*/, options/*:any*/) {
|
||||
if(fs === undefined) fs = require('fs');
|
||||
return parse(fs.readFileSync(filename), options);
|
||||
}
|
||||
|
||||
function readSync(blob, options) {
|
||||
function readSync(blob/*:any*/, options/*:any*/) {
|
||||
switch(options !== undefined && options.type !== undefined ? options.type : "base64") {
|
||||
case "file": return readFileSync(blob, options);
|
||||
case "base64": return parse(s2a(Base64.decode(blob)), options);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
function getdatastr(data)/*:?string*/ {
|
||||
if(!data) return null;
|
||||
if(data.data) return debom_xml(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
|
||||
if(data.asBinary) return debom_xml(data.asBinary());
|
||||
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
|
||||
if(data.data) return debom(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return debom(data.asNodeBuffer().toString('binary'));
|
||||
if(data.asBinary) return debom(data.asBinary());
|
||||
if(data._data && data._data.getContent) return debom(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,14 @@ function getdatabin(data) {
|
|||
|
||||
function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
|
||||
/* Part 2 Section 10.1.2 "Mapping Content Types" Names are case-insensitive */
|
||||
function safegetzipfile(zip, file/*:string*/) {
|
||||
var f = file; if(zip.files[f]) return zip.files[f];
|
||||
f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
|
||||
f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
|
||||
var k = keys(zip.files);
|
||||
var f = file.toLowerCase(), g = f.replace(/\//g,'\\');
|
||||
for(var i=0; i<k.length; ++i) {
|
||||
var n = k[i].toLowerCase();
|
||||
if(f == n || g == n) return zip.files[k[i]];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ function xlml_normalize(d)/*:string*/ {
|
|||
/* TODO: Everything */
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;
|
||||
function parse_xlml_xml(d, opts) {
|
||||
var str = xlml_normalize(d);
|
||||
var str = debom(xlml_normalize(d));
|
||||
var Rn;
|
||||
var state = [], tmp;
|
||||
var sheets = {}, sheetnames = [], cursheet = {}, sheetname = "";
|
||||
|
|
|
@ -32,6 +32,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
|||
case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o);
|
||||
case 0x3C: return parse_xlml(d, o);
|
||||
case 0x50: return read_zip(d, o);
|
||||
case 0xEF: return parse_xlml(d, o);
|
||||
default: throw new Error("Unsupported file " + n);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,23 +14,28 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
|||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_string_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": break; // TODO
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, out, {encoding:'utf8'});
|
||||
case "buffer": break; // TODO
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
} break;
|
||||
default: return out;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_binary_type(out, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "base64":
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
|
@ -39,12 +44,16 @@ function write_binary_type(out, opts/*:WriteOpts*/) {
|
|||
|
||||
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
var o = opts||{};
|
||||
switch(o.bookType) {
|
||||
switch(o.bookType || 'xlsx') {
|
||||
case 'xml': return write_string_type(write_xlml(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
|
||||
default: return write_zip_type(wb, o);
|
||||
case 'xlsx':
|
||||
case 'xlsm':
|
||||
case 'xlsb':
|
||||
case 'ods': return write_zip_type(wb, o);
|
||||
default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -290,7 +290,7 @@ var parse_content_xml = (function() {
|
|||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]=Rn[3].replace(/_.*$/,"")) {
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -4,7 +4,7 @@
|
|||
/*jshint funcscope:true, eqnull:true */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.8.5';
|
||||
XLSX.version = '0.8.6';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
|
||||
|
@ -14,12 +14,18 @@ function reset_cp() { set_cp(1200); }
|
|||
var set_cp = function(cp) { current_codepage = cp; };
|
||||
|
||||
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
|
||||
var debom_xml = function(data) { return data; };
|
||||
var debom = function(data) {
|
||||
var c1 = data.charCodeAt(0), c2 = data.charCodeAt(1);
|
||||
if(c1 == 0xFF && c2 == 0xFE) return data.substr(2);
|
||||
if(c1 == 0xFE && c2 == 0xFF) return data.substr(2);
|
||||
if(c1 == 0xFEFF) return data.substr(1);
|
||||
return data;
|
||||
};
|
||||
|
||||
var _getchar = function _gc1(x) { return String.fromCharCode(x); };
|
||||
if(typeof cptable !== 'undefined') {
|
||||
set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
|
||||
debom_xml = function(data) {
|
||||
debom = function(data) {
|
||||
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
|
||||
return data;
|
||||
};
|
||||
|
@ -871,14 +877,14 @@ var XLMLFormatMap/*{[string]:string}*/ = ({
|
|||
});
|
||||
|
||||
var DO_NOT_EXPORT_CFB = true;
|
||||
/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint eqnull:true */
|
||||
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '0.10.2';
|
||||
exports.version = '0.11.0';
|
||||
function parse(file) {
|
||||
var mver = 3; // major version
|
||||
var ssz = 512; // sector size
|
||||
|
@ -1088,6 +1094,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) {
|
|||
if(cnt !== 0) throw "DIFAT chain shorter than expected";
|
||||
} else if(idx !== -1 /*FREESECT*/) {
|
||||
var sector = sectors[idx], m = (ssz>>>2)-1;
|
||||
if(!sector) return;
|
||||
for(var i = 0; i < m; ++i) {
|
||||
if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
|
||||
fat_addrs.push(q);
|
||||
|
@ -1111,6 +1118,7 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) {
|
|||
var addr = fat_addrs[Math.floor(j*4/ssz)];
|
||||
jj = ((j*4) & modulus);
|
||||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz;
|
||||
if(!sectors[addr]) break;
|
||||
j = __readInt32LE(sectors[addr], jj);
|
||||
}
|
||||
return {nodes: buf, data:__toBuffer([buf_chain])};
|
||||
|
@ -1133,6 +1141,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) {
|
|||
var addr = fat_addrs[Math.floor(j*4/ssz)];
|
||||
jj = ((j*4) & modulus);
|
||||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz;
|
||||
if(!sectors[addr]) break;
|
||||
j = __readInt32LE(sectors[addr], jj);
|
||||
}
|
||||
sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])};
|
||||
|
@ -1153,7 +1162,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
|||
if(namelen === 0) continue;
|
||||
name = __utf16le(blob,0,namelen-pl);
|
||||
Paths.push(name);
|
||||
o = {
|
||||
o = ({
|
||||
name: name,
|
||||
type: blob.read_shift(1),
|
||||
color: blob.read_shift(1),
|
||||
|
@ -1162,7 +1171,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
|||
C: blob.read_shift(4, 'i'),
|
||||
clsid: blob.read_shift(16),
|
||||
state: blob.read_shift(4, 'i')
|
||||
};
|
||||
});
|
||||
ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
|
||||
if(ctime !== 0) {
|
||||
o.ctime = ctime; o.ct = read_date(blob, blob.l-8);
|
||||
|
@ -1314,10 +1323,10 @@ function dup(o) {
|
|||
function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; }
|
||||
function getdatastr(data) {
|
||||
if(!data) return null;
|
||||
if(data.data) return debom_xml(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
|
||||
if(data.asBinary) return debom_xml(data.asBinary());
|
||||
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
|
||||
if(data.data) return debom(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return debom(data.asNodeBuffer().toString('binary'));
|
||||
if(data.asBinary) return debom(data.asBinary());
|
||||
if(data._data && data._data.getContent) return debom(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1335,10 +1344,14 @@ function getdatabin(data) {
|
|||
|
||||
function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
|
||||
/* Part 2 Section 10.1.2 "Mapping Content Types" Names are case-insensitive */
|
||||
function safegetzipfile(zip, file) {
|
||||
var f = file; if(zip.files[f]) return zip.files[f];
|
||||
f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
|
||||
f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
|
||||
var k = keys(zip.files);
|
||||
var f = file.toLowerCase(), g = f.replace(/\//g,'\\');
|
||||
for(var i=0; i<k.length; ++i) {
|
||||
var n = k[i].toLowerCase();
|
||||
if(f == n || g == n) return zip.files[k[i]];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -9464,7 +9477,7 @@ function xlml_normalize(d) {
|
|||
/* TODO: Everything */
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;
|
||||
function parse_xlml_xml(d, opts) {
|
||||
var str = xlml_normalize(d);
|
||||
var str = debom(xlml_normalize(d));
|
||||
var Rn;
|
||||
var state = [], tmp;
|
||||
var sheets = {}, sheetnames = [], cursheet = {}, sheetname = "";
|
||||
|
@ -12418,6 +12431,7 @@ function readSync(data, opts) {
|
|||
case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o);
|
||||
case 0x3C: return parse_xlml(d, o);
|
||||
case 0x50: return read_zip(d, o);
|
||||
case 0xEF: return parse_xlml(d, o);
|
||||
default: throw new Error("Unsupported file " + n);
|
||||
}
|
||||
}
|
||||
|
@ -12442,23 +12456,28 @@ function write_zip_type(wb, opts) {
|
|||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_string_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": break; // TODO
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, out, {encoding:'utf8'});
|
||||
case "buffer": break; // TODO
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
} break;
|
||||
default: return out;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_binary_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "base64":
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
|
@ -12467,12 +12486,16 @@ function write_binary_type(out, opts) {
|
|||
|
||||
function writeSync(wb, opts) {
|
||||
var o = opts||{};
|
||||
switch(o.bookType) {
|
||||
switch(o.bookType || 'xlsx') {
|
||||
case 'xml': return write_string_type(write_xlml(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
|
||||
default: return write_zip_type(wb, o);
|
||||
case 'xlsx':
|
||||
case 'xlsm':
|
||||
case 'xlsb':
|
||||
case 'ods': return write_zip_type(wb, o);
|
||||
default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -227,7 +227,7 @@ function handleDrop(e) {
|
|||
if(rABS) {
|
||||
wb = X.read(data, {type: 'binary'});
|
||||
} else {
|
||||
var arr = fixdata(data);
|
||||
var arr = fixdata(data);
|
||||
wb = X.read(btoa(arr), {type: 'base64'});
|
||||
}
|
||||
process_wb(wb);
|
||||
|
|
|
@ -292,7 +292,7 @@ var parse_content_xml = (function() {
|
|||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]=Rn[3].replace(/_.*$/,"")) {
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
|
|
2
ods.js
2
ods.js
|
@ -290,7 +290,7 @@ var parse_content_xml = (function() {
|
|||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]=Rn[3].replace(/_.*$/,"")) {
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
|
|
|
@ -30,7 +30,7 @@ var parse_content_xml = (function() {
|
|||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]=Rn[3].replace(/_.*$/,"")) {
|
||||
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
|
||||
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.8.5",
|
||||
"version": "0.8.6",
|
||||
"author": "sheetjs",
|
||||
"description": "Excel (XLSB/XLSX/XLSM/XLS/XML) and ODS (ODS/FODS/UOS) spreadsheet parser and writer",
|
||||
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "office", "spreadsheet" ],
|
||||
|
@ -12,7 +12,7 @@
|
|||
"exit-on-epipe":"",
|
||||
"ssf":"~0.8.1",
|
||||
"codepage":"",
|
||||
"cfb":">=0.10.0",
|
||||
"cfb":"~0.11.0",
|
||||
"crc-32":"",
|
||||
"adler-32":"",
|
||||
"commander":""
|
||||
|
|
|
@ -91,3 +91,12 @@ XLSX.writeFile(wb, 'sheetjs.xls', {bookType:'biff2'});
|
|||
XLSX.writeFile(wb, 'sheetjs.ods');
|
||||
XLSX.writeFile(wb, 'sheetjs.fods');
|
||||
XLSX.writeFile(wb, 'sheetjs.csv');
|
||||
|
||||
/* test by reading back files */
|
||||
XLSX.readFile('sheetjs.xlsx');
|
||||
XLSX.readFile('sheetjs.xlsm');
|
||||
XLSX.readFile('sheetjs.xlsb');
|
||||
XLSX.readFile('sheetjs.xls');
|
||||
XLSX.readFile('sheetjs.ods');
|
||||
XLSX.readFile('sheetjs.fods');
|
||||
//XLSX.readFile('sheetjs.csv');
|
||||
|
|
109
xlsx.flow.js
109
xlsx.flow.js
|
@ -4,7 +4,7 @@
|
|||
/*jshint funcscope:true, eqnull:true */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.8.5';
|
||||
XLSX.version = '0.8.6';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
|
||||
|
@ -14,12 +14,18 @@ function reset_cp() { set_cp(1200); }
|
|||
var set_cp = function(cp) { current_codepage = cp; };
|
||||
|
||||
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
|
||||
var debom_xml = function(data) { return data; };
|
||||
var debom = function(data/*:string*/)/*:string*/ {
|
||||
var c1 = data.charCodeAt(0), c2 = data.charCodeAt(1);
|
||||
if(c1 == 0xFF && c2 == 0xFE) return data.substr(2);
|
||||
if(c1 == 0xFE && c2 == 0xFF) return data.substr(2);
|
||||
if(c1 == 0xFEFF) return data.substr(1);
|
||||
return data;
|
||||
};
|
||||
|
||||
var _getchar = function _gc1(x) { return String.fromCharCode(x); };
|
||||
if(typeof cptable !== 'undefined') {
|
||||
set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
|
||||
debom_xml = function(data) {
|
||||
debom = function(data) {
|
||||
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
|
||||
return data;
|
||||
};
|
||||
|
@ -31,7 +37,7 @@ if(typeof cptable !== 'undefined') {
|
|||
var Base64 = (function make_b64(){
|
||||
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
return {
|
||||
encode: function(input, utf8) {
|
||||
encode: function(input/*:string*/, utf8)/*:string*/ {
|
||||
var o = "";
|
||||
var c1, c2, c3, e1, e2, e3, e4;
|
||||
for(var i = 0; i < input.length; ) {
|
||||
|
@ -48,7 +54,7 @@ var Base64 = (function make_b64(){
|
|||
}
|
||||
return o;
|
||||
},
|
||||
decode: function b64_decode(input, utf8) {
|
||||
decode: function b64_decode(input/*:string*/, utf8)/*:string*/ {
|
||||
var o = "";
|
||||
var c1, c2, c3;
|
||||
var e1, e2, e3, e4;
|
||||
|
@ -888,14 +894,38 @@ var XLMLFormatMap/*{[string]:string}*/ = ({
|
|||
}/*:any*/);
|
||||
|
||||
var DO_NOT_EXPORT_CFB = true;
|
||||
/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||
/*::
|
||||
declare var Base64:any;
|
||||
declare var ReadShift:any;
|
||||
declare var CheckField:any;
|
||||
declare var prep_blob:any;
|
||||
declare var __readUInt32LE:any;
|
||||
declare var __readInt32LE:any;
|
||||
declare var __toBuffer:any;
|
||||
declare var __utf16le:any;
|
||||
declare var bconcat:any;
|
||||
declare var s2a:any;
|
||||
declare var chr0:any;
|
||||
declare var chr1:any;
|
||||
*/
|
||||
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint eqnull:true */
|
||||
|
||||
/*::
|
||||
declare var DO_NOT_EXPORT_CFB:any;
|
||||
type SectorEntry = any;
|
||||
type SectorList = {
|
||||
(k:string|number):SectorEntry;
|
||||
name:?string;
|
||||
fat_addrs:any;
|
||||
ssz:number;
|
||||
}
|
||||
*/
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '0.10.2';
|
||||
exports.version = '0.11.0';
|
||||
function parse(file) {
|
||||
var mver = 3; // major version
|
||||
var ssz = 512; // sector size
|
||||
|
@ -908,7 +938,7 @@ var difat_start = 0; // first mini FAT sector location
|
|||
var fat_addrs = []; // locations of FAT sectors
|
||||
|
||||
/* [MS-CFB] 2.2 Compound File Header */
|
||||
var blob = file.slice(0,512);
|
||||
var blob/*:any*/ = file.slice(0,512);
|
||||
prep_blob(blob, 0);
|
||||
|
||||
/* major version */
|
||||
|
@ -968,7 +998,7 @@ var sectors = sectorify(file, ssz);
|
|||
sleuth_fat(difat_start, ndfs, sectors, ssz, fat_addrs);
|
||||
|
||||
/** Chains */
|
||||
var sector_list = make_sector_list(sectors, dir_start, fat_addrs, ssz);
|
||||
var sector_list/*:SectorList*/ = make_sector_list(sectors, dir_start, fat_addrs, ssz);
|
||||
|
||||
sector_list[dir_start].name = "!Directory";
|
||||
if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT";
|
||||
|
@ -977,7 +1007,7 @@ sector_list.fat_addrs = fat_addrs;
|
|||
sector_list.ssz = ssz;
|
||||
|
||||
/* [MS-CFB] 2.6.1 Compound File Directory Entry */
|
||||
var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {};
|
||||
var files = {}, Paths/*:any*/ = [], FileIndex = [], FullPaths = [], FullPathDir = {};
|
||||
read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex);
|
||||
|
||||
build_full_paths(FileIndex, FullPathDir, FullPaths, Paths);
|
||||
|
@ -1086,7 +1116,7 @@ function make_find_path(FullPaths, Paths, FileIndex, files, root_name) {
|
|||
var UCPaths = new Array(Paths.length), i;
|
||||
for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase().replace(chr0,'').replace(chr1,'!');
|
||||
for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!');
|
||||
return function find_path(path) {
|
||||
return function find_path(path/*:string*/) {
|
||||
var k;
|
||||
if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; }
|
||||
else k = path.indexOf("/") !== -1;
|
||||
|
@ -1105,6 +1135,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) {
|
|||
if(cnt !== 0) throw "DIFAT chain shorter than expected";
|
||||
} else if(idx !== -1 /*FREESECT*/) {
|
||||
var sector = sectors[idx], m = (ssz>>>2)-1;
|
||||
if(!sector) return;
|
||||
for(var i = 0; i < m; ++i) {
|
||||
if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
|
||||
fat_addrs.push(q);
|
||||
|
@ -1128,13 +1159,14 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) {
|
|||
var addr = fat_addrs[Math.floor(j*4/ssz)];
|
||||
jj = ((j*4) & modulus);
|
||||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz;
|
||||
if(!sectors[addr]) break;
|
||||
j = __readInt32LE(sectors[addr], jj);
|
||||
}
|
||||
return {nodes: buf, data:__toBuffer([buf_chain])};
|
||||
}
|
||||
|
||||
/** Chase down the sector linked lists */
|
||||
function make_sector_list(sectors, dir_start, fat_addrs, ssz) {
|
||||
function make_sector_list(sectors, dir_start, fat_addrs, ssz/*:number*/)/*:any*/ {
|
||||
var sl = sectors.length, sector_list = new Array(sl);
|
||||
var chkd = new Array(sl), buf, buf_chain;
|
||||
var modulus = ssz - 1, i, j, k, jj;
|
||||
|
@ -1150,6 +1182,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) {
|
|||
var addr = fat_addrs[Math.floor(j*4/ssz)];
|
||||
jj = ((j*4) & modulus);
|
||||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz;
|
||||
if(!sectors[addr]) break;
|
||||
j = __readInt32LE(sectors[addr], jj);
|
||||
}
|
||||
sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])};
|
||||
|
@ -1170,7 +1203,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
|||
if(namelen === 0) continue;
|
||||
name = __utf16le(blob,0,namelen-pl);
|
||||
Paths.push(name);
|
||||
o = {
|
||||
o = ({
|
||||
name: name,
|
||||
type: blob.read_shift(1),
|
||||
color: blob.read_shift(1),
|
||||
|
@ -1179,7 +1212,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
|||
C: blob.read_shift(4, 'i'),
|
||||
clsid: blob.read_shift(16),
|
||||
state: blob.read_shift(4, 'i')
|
||||
};
|
||||
}/*:any*/);
|
||||
ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
|
||||
if(ctime !== 0) {
|
||||
o.ctime = ctime; o.ct = read_date(blob, blob.l-8);
|
||||
|
@ -1217,12 +1250,12 @@ function read_date(blob, offset) {
|
|||
}
|
||||
|
||||
var fs;
|
||||
function readFileSync(filename, options) {
|
||||
function readFileSync(filename/*:string*/, options/*:any*/) {
|
||||
if(fs === undefined) fs = require('fs');
|
||||
return parse(fs.readFileSync(filename), options);
|
||||
}
|
||||
|
||||
function readSync(blob, options) {
|
||||
function readSync(blob/*:any*/, options/*:any*/) {
|
||||
switch(options !== undefined && options.type !== undefined ? options.type : "base64") {
|
||||
case "file": return readFileSync(blob, options);
|
||||
case "base64": return parse(s2a(Base64.decode(blob)), options);
|
||||
|
@ -1331,10 +1364,10 @@ function dup(o/*:any*/)/*:any*/ {
|
|||
function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; }
|
||||
function getdatastr(data)/*:?string*/ {
|
||||
if(!data) return null;
|
||||
if(data.data) return debom_xml(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
|
||||
if(data.asBinary) return debom_xml(data.asBinary());
|
||||
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
|
||||
if(data.data) return debom(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return debom(data.asNodeBuffer().toString('binary'));
|
||||
if(data.asBinary) return debom(data.asBinary());
|
||||
if(data._data && data._data.getContent) return debom(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1352,10 +1385,14 @@ function getdatabin(data) {
|
|||
|
||||
function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
|
||||
/* Part 2 Section 10.1.2 "Mapping Content Types" Names are case-insensitive */
|
||||
function safegetzipfile(zip, file/*:string*/) {
|
||||
var f = file; if(zip.files[f]) return zip.files[f];
|
||||
f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
|
||||
f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
|
||||
var k = keys(zip.files);
|
||||
var f = file.toLowerCase(), g = f.replace(/\//g,'\\');
|
||||
for(var i=0; i<k.length; ++i) {
|
||||
var n = k[i].toLowerCase();
|
||||
if(f == n || g == n) return zip.files[k[i]];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -9484,7 +9521,7 @@ function xlml_normalize(d)/*:string*/ {
|
|||
/* TODO: Everything */
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;
|
||||
function parse_xlml_xml(d, opts) {
|
||||
var str = xlml_normalize(d);
|
||||
var str = debom(xlml_normalize(d));
|
||||
var Rn;
|
||||
var state = [], tmp;
|
||||
var sheets = {}, sheetnames = [], cursheet = {}, sheetname = "";
|
||||
|
@ -12440,6 +12477,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
|||
case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o);
|
||||
case 0x3C: return parse_xlml(d, o);
|
||||
case 0x50: return read_zip(d, o);
|
||||
case 0xEF: return parse_xlml(d, o);
|
||||
default: throw new Error("Unsupported file " + n);
|
||||
}
|
||||
}
|
||||
|
@ -12464,23 +12502,28 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
|||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_string_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": break; // TODO
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, out, {encoding:'utf8'});
|
||||
case "buffer": break; // TODO
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
} break;
|
||||
default: return out;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_binary_type(out, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "base64":
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
|
@ -12489,12 +12532,16 @@ function write_binary_type(out, opts/*:WriteOpts*/) {
|
|||
|
||||
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
var o = opts||{};
|
||||
switch(o.bookType) {
|
||||
switch(o.bookType || 'xlsx') {
|
||||
case 'xml': return write_string_type(write_xlml(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
|
||||
default: return write_zip_type(wb, o);
|
||||
case 'xlsx':
|
||||
case 'xlsm':
|
||||
case 'xlsb':
|
||||
case 'ods': return write_zip_type(wb, o);
|
||||
default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
67
xlsx.js
67
xlsx.js
|
@ -4,7 +4,7 @@
|
|||
/*jshint funcscope:true, eqnull:true */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.8.5';
|
||||
XLSX.version = '0.8.6';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
|
||||
|
@ -14,12 +14,18 @@ function reset_cp() { set_cp(1200); }
|
|||
var set_cp = function(cp) { current_codepage = cp; };
|
||||
|
||||
function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
|
||||
var debom_xml = function(data) { return data; };
|
||||
var debom = function(data) {
|
||||
var c1 = data.charCodeAt(0), c2 = data.charCodeAt(1);
|
||||
if(c1 == 0xFF && c2 == 0xFE) return data.substr(2);
|
||||
if(c1 == 0xFE && c2 == 0xFF) return data.substr(2);
|
||||
if(c1 == 0xFEFF) return data.substr(1);
|
||||
return data;
|
||||
};
|
||||
|
||||
var _getchar = function _gc1(x) { return String.fromCharCode(x); };
|
||||
if(typeof cptable !== 'undefined') {
|
||||
set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; };
|
||||
debom_xml = function(data) {
|
||||
debom = function(data) {
|
||||
if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); }
|
||||
return data;
|
||||
};
|
||||
|
@ -871,14 +877,14 @@ var XLMLFormatMap/*{[string]:string}*/ = ({
|
|||
});
|
||||
|
||||
var DO_NOT_EXPORT_CFB = true;
|
||||
/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint eqnull:true */
|
||||
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports = {};
|
||||
exports.version = '0.10.2';
|
||||
exports.version = '0.11.0';
|
||||
function parse(file) {
|
||||
var mver = 3; // major version
|
||||
var ssz = 512; // sector size
|
||||
|
@ -1088,6 +1094,7 @@ function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) {
|
|||
if(cnt !== 0) throw "DIFAT chain shorter than expected";
|
||||
} else if(idx !== -1 /*FREESECT*/) {
|
||||
var sector = sectors[idx], m = (ssz>>>2)-1;
|
||||
if(!sector) return;
|
||||
for(var i = 0; i < m; ++i) {
|
||||
if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
|
||||
fat_addrs.push(q);
|
||||
|
@ -1111,6 +1118,7 @@ function get_sector_list(sectors, start, fat_addrs, ssz, chkd) {
|
|||
var addr = fat_addrs[Math.floor(j*4/ssz)];
|
||||
jj = ((j*4) & modulus);
|
||||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz;
|
||||
if(!sectors[addr]) break;
|
||||
j = __readInt32LE(sectors[addr], jj);
|
||||
}
|
||||
return {nodes: buf, data:__toBuffer([buf_chain])};
|
||||
|
@ -1133,6 +1141,7 @@ function make_sector_list(sectors, dir_start, fat_addrs, ssz) {
|
|||
var addr = fat_addrs[Math.floor(j*4/ssz)];
|
||||
jj = ((j*4) & modulus);
|
||||
if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz;
|
||||
if(!sectors[addr]) break;
|
||||
j = __readInt32LE(sectors[addr], jj);
|
||||
}
|
||||
sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])};
|
||||
|
@ -1153,7 +1162,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
|||
if(namelen === 0) continue;
|
||||
name = __utf16le(blob,0,namelen-pl);
|
||||
Paths.push(name);
|
||||
o = {
|
||||
o = ({
|
||||
name: name,
|
||||
type: blob.read_shift(1),
|
||||
color: blob.read_shift(1),
|
||||
|
@ -1162,7 +1171,7 @@ function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, Fil
|
|||
C: blob.read_shift(4, 'i'),
|
||||
clsid: blob.read_shift(16),
|
||||
state: blob.read_shift(4, 'i')
|
||||
};
|
||||
});
|
||||
ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
|
||||
if(ctime !== 0) {
|
||||
o.ctime = ctime; o.ct = read_date(blob, blob.l-8);
|
||||
|
@ -1314,10 +1323,10 @@ function dup(o) {
|
|||
function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; }
|
||||
function getdatastr(data) {
|
||||
if(!data) return null;
|
||||
if(data.data) return debom_xml(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary'));
|
||||
if(data.asBinary) return debom_xml(data.asBinary());
|
||||
if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
|
||||
if(data.data) return debom(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return debom(data.asNodeBuffer().toString('binary'));
|
||||
if(data.asBinary) return debom(data.asBinary());
|
||||
if(data._data && data._data.getContent) return debom(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1335,10 +1344,14 @@ function getdatabin(data) {
|
|||
|
||||
function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
|
||||
/* Part 2 Section 10.1.2 "Mapping Content Types" Names are case-insensitive */
|
||||
function safegetzipfile(zip, file) {
|
||||
var f = file; if(zip.files[f]) return zip.files[f];
|
||||
f = file.toLowerCase(); if(zip.files[f]) return zip.files[f];
|
||||
f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f];
|
||||
var k = keys(zip.files);
|
||||
var f = file.toLowerCase(), g = f.replace(/\//g,'\\');
|
||||
for(var i=0; i<k.length; ++i) {
|
||||
var n = k[i].toLowerCase();
|
||||
if(f == n || g == n) return zip.files[k[i]];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -9464,7 +9477,7 @@ function xlml_normalize(d) {
|
|||
/* TODO: Everything */
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;
|
||||
function parse_xlml_xml(d, opts) {
|
||||
var str = xlml_normalize(d);
|
||||
var str = debom(xlml_normalize(d));
|
||||
var Rn;
|
||||
var state = [], tmp;
|
||||
var sheets = {}, sheetnames = [], cursheet = {}, sheetname = "";
|
||||
|
@ -12418,6 +12431,7 @@ function readSync(data, opts) {
|
|||
case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(d) : d), o);
|
||||
case 0x3C: return parse_xlml(d, o);
|
||||
case 0x50: return read_zip(d, o);
|
||||
case 0xEF: return parse_xlml(d, o);
|
||||
default: throw new Error("Unsupported file " + n);
|
||||
}
|
||||
}
|
||||
|
@ -12442,23 +12456,28 @@ function write_zip_type(wb, opts) {
|
|||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_string_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": break; // TODO
|
||||
case "base64": return Base64.encode(out);
|
||||
case "binary": return out;
|
||||
case "file": return _fs.writeFileSync(opts.file, out, {encoding:'utf8'});
|
||||
case "buffer": break; // TODO
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
} break;
|
||||
default: return out;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_binary_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "base64":
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
return opts.type == 'base64' ? Base64.encode(bstr) : bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
|
@ -12467,12 +12486,16 @@ function write_binary_type(out, opts) {
|
|||
|
||||
function writeSync(wb, opts) {
|
||||
var o = opts||{};
|
||||
switch(o.bookType) {
|
||||
switch(o.bookType || 'xlsx') {
|
||||
case 'xml': return write_string_type(write_xlml(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
|
||||
default: return write_zip_type(wb, o);
|
||||
case 'xlsx':
|
||||
case 'xlsm':
|
||||
case 'xlsb':
|
||||
case 'ods': return write_zip_type(wb, o);
|
||||
default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue