version bump 0.11.12: merging js-harb

- ETH format and utils merged from js-harb
- added shim to npm package (fixes #911 h/t @dackmin)
- TS defs refresh
- updated test_files
This commit is contained in:
SheetJS 2017-12-03 23:41:41 -05:00
parent cd2e639fc2
commit eff7d153e8
37 changed files with 606 additions and 81 deletions

1
.gitignore vendored
View File

@ -22,6 +22,7 @@ tmp
*.[qQ][pP][wW]
*.[bB][iI][fF][fF][23458]
*.[rR][tT][fF]
*.[eE][tT][hH]
*.123
*.htm
*.html

View File

@ -24,6 +24,7 @@ tmp
*.[qQ][pP][wW]
*.[bB][iI][fF][fF][23458]
*.[rR][tT][fF]
*.[eE][tT][hH]
*.123
*.htm
*.html

View File

@ -34,6 +34,7 @@ tooltips
Browserify
CDNjs
CommonJS
Ethercalc
ExtendScript
FileSaver
JavaScriptCore

View File

@ -56,6 +56,7 @@ dist: dist-deps $(TARGET) bower.json ## Prepare JS files for distribution
mkdir -p dist
<$(TARGET) sed "s/require('stream')/{}/g;s/require('....*')/undefined/g" > dist/$(TARGET)
cp LICENSE dist/
uglifyjs shim.js $(UGLIFYOPTS) -o dist/shim.min.js --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(DISTHDR) dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 bits/00_header.js)"
misc/strip_sourcemap.sh dist/$(LIB).min.js
uglifyjs $(DISTHDR) $(REQS) dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).core.min.js --source-map dist/$(LIB).core.min.map --preamble "$$(head -n 1 bits/00_header.js)"

View File

@ -128,6 +128,7 @@ enhancements, additional features by request, and dedicated support.
+ [Data Interchange Format (DIF)](#data-interchange-format-dif)
+ [HTML](#html)
+ [Rich Text Format (RTF)](#rich-text-format-rtf)
+ [Ethercalc Record Format (ETH)](#ethercalc-record-format-eth)
- [Testing](#testing)
* [Node](#node)
* [Browser](#browser)
@ -1586,6 +1587,7 @@ Plain text format guessing follows the priority order:
| DSV | more unquoted `";"` chars than `"\t"` or `","` in the first 1024 |
| TSV | more unquoted `"\t"` chars than `","` chars in the first 1024 |
| CSV | one of the first 1024 characters is a comma `","` |
| ETH | starts with `socialcalc:version:` |
| PRN | (default) |
- HTML tags include: `html`, `table`, `head`, `meta`, `script`, `style`, `div`
@ -1661,6 +1663,7 @@ output formats. The specific file type is controlled with `bookType` option:
| `dbf` | `.dbf` | none | single | dBASE II + VFP Extensions (DBF) |
| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) |
| `prn` | `.prn` | none | single | Lotus Formatted Text |
| `eth` | `.eth` | none | single | Ethercalc Record Format (ETH) |
- `compression` only applies to formats with ZIP containers.
- Formats that only support a single sheet require a `sheet` option specifying
@ -2000,6 +2003,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
| HTML Tables | :o: | :o: |
| Rich Text Format tables (RTF) | | :o: |
| Ethercalc Record Format (ETH) | :o: | :o: |
### Excel 2007+ XML (XLSX/XLSM)
@ -2235,6 +2239,16 @@ worksheet. The supported codes are a subset of the Word RTF support.
</details>
#### Ethercalc Record Format (ETH)
<details>
<summary>(click to show)</summary>
[Ethercalc](https://ethercalc.net/) is an open source web spreadsheet powered by
a record format reminiscent of SYLK wrapped in a MIME multi-part message.
</details>
## Testing

View File

@ -37,6 +37,7 @@ program
.option('-U, --dbf', 'emit DBF to <sheetname> or <file>.dbf (MSVFP DBF)')
.option('-K, --sylk', 'emit SYLK to <sheetname> or <file>.slk (Excel SYLK)')
.option('-P, --prn', 'emit PRN to <sheetname> or <file>.prn (Lotus PRN)')
.option('-E, --eth', 'emit ETH to <sheetname> or <file>.eth (Ethercalc)')
.option('-t, --txt', 'emit TXT to <sheetname> or <file>.txt (UTF-8 TSV)')
.option('-r, --rtf', 'emit RTF to <sheetname> or <file>.txt (Table RTF)')
@ -188,6 +189,7 @@ if(!program.quiet && !program.book) console.error(target_sheet);
['sylk', '.slk'],
['html', '.html'],
['prn', '.prn'],
['eth', '.eth'],
['rtf', '.rtf'],
['txt', '.txt'],
['dbf', '.dbf'],

View File

@ -1 +1 @@
XLSX.version = '0.11.11';
XLSX.version = '0.11.12';

View File

@ -126,6 +126,12 @@ function ReadShift(size/*:number*/, t/*:?string*/)/*:number|string*/ {
loc+=2;
} o = oo.join(""); size *= 2; break;
case 'cpstr':
if(typeof cptable !== 'undefined') {
o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l + size));
break;
}
/* falls through */
case 'sbcs-cont': o = ""; loc = this.l;
for(i = 0; i != size; ++i) {
if(this.lens && this.lens.indexOf(loc) !== -1) {

View File

@ -360,7 +360,7 @@ function parse_XLUnicodeString2(blob, length, opts) {
if(opts.biff > 5) return parse_XLUnicodeString(blob, length, opts);
var cch = blob.read_shift(1);
if(cch === 0) { blob.l++; return ""; }
return blob.read_shift(cch, 'sbcs-cont');
return blob.read_shift(cch, opts.biff == 4 ? 'cpstr' : 'sbcs-cont');
}
/* TODO: BIFF5 and lower, codepage awareness */
function write_XLUnicodeString(str, opts, o) {

View File

@ -580,6 +580,105 @@ var DIF = (function() {
};
})();
var ETH = (function() {
function decode(s/*:string*/)/*:string*/ { return s.replace(/\\b/g,"\\").replace(/\\c/g,":").replace(/\\n/g,"\n"); }
function encode(s/*:string*/)/*:string*/ { return s.replace(/\\/g, "\\b").replace(/:/g, "\\c").replace(/\n/g,"\\n"); }
function eth_to_aoa(str/*:string*/, opts)/*:AOA*/ {
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr = [];
for (; ri !== records.length; ++ri) {
var record = records[ri].trim().split(":");
if(record[0] !== 'cell') continue;
var addr = decode_cell(record[1]);
if(arr.length <= addr.r) for(R = arr.length; R <= addr.r; ++R) if(!arr[R]) arr[R] = [];
R = addr.r; C = addr.c;
switch(record[2]) {
case 't': arr[R][C] = decode(record[3]); break;
case 'v': arr[R][C] = +record[3]; break;
case 'vtf': var _f = record[record.length - 1];
/* falls through */
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
}
return arr;
}
function eth_to_sheet(d/*:string*/, opts)/*:Worksheet*/ { return aoa_to_sheet(eth_to_aoa(d, opts), opts); }
function eth_to_workbook(d/*:string*/, opts)/*:Workbook*/ { return sheet_to_workbook(eth_to_sheet(d, opts), opts); }
var header = [
"socialcalc:version:1.5",
"MIME-Version: 1.0",
"Content-Type: multipart/mixed; boundary=SocialCalcSpreadsheetControlSave"
].join("\n");
var sep = [
"--SocialCalcSpreadsheetControlSave",
"Content-type: text/plain; charset=UTF-8"
].join("\n") + "\n";
/* TODO: the other parts */
var meta = [
"# SocialCalc Spreadsheet Control Save",
"part:sheet"
].join("\n");
var end = "--SocialCalcSpreadsheetControlSave--";
function sheet_to_eth_data(ws/*:Worksheet*/)/*:string*/ {
if(!ws || !ws['!ref']) return "";
var o = [], oo = [], cell, coord;
var r = decode_range(ws['!ref']);
var dense = Array.isArray(ws);
for(var R = r.s.r; R <= r.e.r; ++R) {
for(var C = r.s.c; C <= r.e.c; ++C) {
coord = encode_cell({r:R,c:C});
cell = dense ? (ws[R]||[])[C] : ws[coord];
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=+!!cell.v;
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
break;
case 'd':
var t = datenum(parseDate(cell.v));
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = t;
oo[5] = cell.w || SSF.format(cell.z || SSF._table[14], t);
break;
case 'e': continue;
}
o.push(oo.join(":"));
}
}
o.push("sheet:c:" + (r.e.c-r.s.c+1) + ":r:" + (r.e.r-r.s.r+1) + ":tvf:1");
o.push("valueformat:1:text-wiki");
//o.push("copiedfrom:" + ws['!ref']); // clipboard only
return o.join("\n");
}
function sheet_to_eth(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
return [header, sep, meta, sep, sheet_to_eth_data(ws), end].join("\n");
// return ["version:1.5", sheet_to_eth_data(ws)].join("\n"); // clipboard form
}
return {
to_workbook: eth_to_workbook,
to_sheet: eth_to_sheet,
from_sheet: sheet_to_eth
};
})();
var PRN = (function() {
function set_text_arr(data/*:string*/, arr/*:AOA*/, R/*:number*/, C/*:number*/, o/*:any*/) {
if(o.raw) arr[R][C] = data;
@ -713,7 +812,7 @@ var PRN = (function() {
}
function prn_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
if(str.substr(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.slice(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts);
return aoa_to_sheet(prn_to_aoa_str(str, opts), opts);
}
@ -729,6 +828,7 @@ var PRN = (function() {
default: throw new Error("Unrecognized type " + opts.type);
}
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
if(str.slice(0,19) == "socialcalc:version:") return ETH.to_sheet(opts.type == 'string' ? str : utf8read(str), opts);
return prn_to_sheet_str(str, opts);
}

View File

@ -21,4 +21,5 @@ 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);
var write_eth_str = write_obj_str(ETH);

View File

@ -92,6 +92,7 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
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 'eth': return write_string_type(write_eth_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 */
@ -113,6 +114,7 @@ function resolve_book_type(o/*:WriteFileOpts*/) {
"xls": "biff8",
"htm": "html",
"slk": "sylk",
"socialcalc": "eth",
"Sh33tJS": "WTF"
};
var ext = o.file.slice(o.file.lastIndexOf(".")).toLowerCase();

View File

@ -222,6 +222,9 @@ var utils/*:any*/ = {
sheet_to_txt: sheet_to_txt,
sheet_to_json: sheet_to_json,
sheet_to_html: HTML_.from_sheet,
sheet_to_dif: DIF.from_sheet,
sheet_to_slk: SYLK.from_sheet,
sheet_to_eth: ETH.from_sheet,
sheet_to_formulae: sheet_to_formulae,
sheet_to_row_object_array: sheet_to_json
};

2
dist/shim.min.js vendored Normal file
View File

@ -0,0 +1,2 @@
/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
if(!Object.keys){Object.keys=function(){var r=Object.prototype.hasOwnProperty,t=!{toString:null}.propertyIsEnumerable("toString"),e=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],n=e.length;return function(i){if(typeof i!=="object"&&typeof i!=="function"||i===null)throw new TypeError("Object.keys called on non-object");var o=[];for(var f in i){if(r.call(i,f))o.push(f)}if(t){for(var a=0;a<n;a++){if(r.call(i,e[a]))o.push(e[a])}}return o}}()}if(!Array.prototype.filter){Array.prototype.filter=function(r){"use strict";if(this==null)throw new TypeError;var t=Object(this);var e=t.length>>>0;if(typeof r!="function")throw new TypeError;var n=[];var i=arguments[1];for(var o=0;o<e;o++){if(o in t){var f=t[o];if(r.call(i,f,o,t))n.push(f)}}return n}}if(!String.prototype.trim){String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}}if(!Array.prototype.forEach){Array.prototype.forEach=function(r){"use strict";if(this===void 0||this===null)throw new TypeError;var t=Object(this);var e=t.length>>>0;if(typeof r!=="function")throw new TypeError;var n=arguments.length>=2?arguments[1]:void 0;for(var i=0;i<e;i++){if(i in t)r.call(n,t[i],i,t)}}}if(!Array.prototype.map){Array.prototype.map=function(r,t){var e,n,i;if(this==null){throw new TypeError(" this is null or not defined")}var o=Object(this);var f=o.length>>>0;if(typeof r!=="function"){throw new TypeError(r+" is not a function")}if(t){e=t}n=new Array(f);i=0;while(i<f){var a,s;if(i in o){a=o[i];s=r.call(e,a,i,o);n[i]=s}i++}return n}}if(!Array.prototype.indexOf){Array.prototype.indexOf=function(r,t){if(this===undefined||this===null){throw new TypeError('"this" is null or not defined')}var e=this.length>>>0;t=+t||0;if(Math.abs(t)===Infinity){t=0}if(t<0){t+=e;if(t<0){t=0}}for(;t<e;t++){if(this[t]===r){return t}}return-1}}if(!Array.isArray){Array.isArray=function(r){return Object.prototype.toString.call(r)==="[object Array]"}}"use strict";if(typeof ArrayBuffer!=="undefined"&&!ArrayBuffer.prototype.slice){ArrayBuffer.prototype.slice=function(r,t){r=r|0||0;var e=this.byteLength;t=t===void 0?e:t|0;if(r<0)r+=e;if(t<0)t+=e;if(e===0||r>=e||r>=t){return new ArrayBuffer(0)}var n=Math.min(e-r,t-r);var i=new ArrayBuffer(n);var o=new Uint8Array(i);o.set(new Uint8Array(this,r,n));return i}}(function(){var r=typeof exports!="undefined"?exports:typeof self!="undefined"?self:$.global;var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";function e(r){this.message=r}e.prototype=new Error;e.prototype.name="InvalidCharacterError";r.btoa||(r.btoa=function(r){var n=String(r);for(var i,o,f=0,a=t,s="";n.charAt(f|0)||(a="=",f%1);s+=a.charAt(63&i>>8-f%1*8)){o=n.charCodeAt(f+=3/4);if(o>255){throw new e("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.")}i=i<<8|o}return s});r.atob||(r.atob=function(r){var n=String(r).replace(/[=]+$/,"");if(n.length%4==1){throw new e("'atob' failed: The string to be decoded is not correctly encoded.")}for(var i=0,o,f,a=0,s="";f=n.charAt(a++);~f&&(o=i%4?o*64+f:f,i++%4)?s+=String.fromCharCode(255&o>>(-2*i&6)):0){f=t.indexOf(f)}return s})})();if(!Date.prototype.toISOString){(function(){function r(r){if(r<10){return"0"+r}return r}Date.prototype.toISOString=function(){return this.getUTCFullYear()+"-"+r(this.getUTCMonth()+1)+"-"+r(this.getUTCDate())+"T"+r(this.getUTCHours())+":"+r(this.getUTCMinutes())+":"+r(this.getUTCSeconds())+"."+(this.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z"}})()}if(typeof Uint8Array!=="undefined"&&!Uint8Array.prototype.slice)Uint8Array.prototype.slice=function(r,t){if(r<0){r+=this.length;if(r<0)r=0}if(r>=this.length)return new Uint8Array(0);if(t==null)t=this.length;if(t<0){t+=this.length;if(t<0)t=0}if(t>this.length)t=this.length;var e=new Uint8Array(t-r);while(r<=--t)e[t-r]=this[t];return e};

25
dist/xlsx.core.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

26
dist/xlsx.full.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

118
dist/xlsx.js vendored
View File

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.11.11';
XLSX.version = '0.11.12';
var current_codepage = 1200;
/*global cptable:true */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
@ -2313,6 +2313,12 @@ function ReadShift(size, t) {
loc+=2;
} o = oo.join(""); size *= 2; break;
case 'cpstr':
if(typeof cptable !== 'undefined') {
o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l + size));
break;
}
/* falls through */
case 'sbcs-cont': o = ""; loc = this.l;
for(i = 0; i != size; ++i) {
if(this.lens && this.lens.indexOf(loc) !== -1) {
@ -4351,7 +4357,7 @@ function parse_XLUnicodeString2(blob, length, opts) {
if(opts.biff > 5) return parse_XLUnicodeString(blob, length, opts);
var cch = blob.read_shift(1);
if(cch === 0) { blob.l++; return ""; }
return blob.read_shift(cch, 'sbcs-cont');
return blob.read_shift(cch, opts.biff == 4 ? 'cpstr' : 'sbcs-cont');
}
/* TODO: BIFF5 and lower, codepage awareness */
function write_XLUnicodeString(str, opts, o) {
@ -5994,6 +6000,105 @@ var DIF = (function() {
};
})();
var ETH = (function() {
function decode(s) { return s.replace(/\\b/g,"\\").replace(/\\c/g,":").replace(/\\n/g,"\n"); }
function encode(s) { return s.replace(/\\/g, "\\b").replace(/:/g, "\\c").replace(/\n/g,"\\n"); }
function eth_to_aoa(str, opts) {
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr = [];
for (; ri !== records.length; ++ri) {
var record = records[ri].trim().split(":");
if(record[0] !== 'cell') continue;
var addr = decode_cell(record[1]);
if(arr.length <= addr.r) for(R = arr.length; R <= addr.r; ++R) if(!arr[R]) arr[R] = [];
R = addr.r; C = addr.c;
switch(record[2]) {
case 't': arr[R][C] = decode(record[3]); break;
case 'v': arr[R][C] = +record[3]; break;
case 'vtf': var _f = record[record.length - 1];
/* falls through */
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
}
return arr;
}
function eth_to_sheet(d, opts) { return aoa_to_sheet(eth_to_aoa(d, opts), opts); }
function eth_to_workbook(d, opts) { return sheet_to_workbook(eth_to_sheet(d, opts), opts); }
var header = [
"socialcalc:version:1.5",
"MIME-Version: 1.0",
"Content-Type: multipart/mixed; boundary=SocialCalcSpreadsheetControlSave"
].join("\n");
var sep = [
"--SocialCalcSpreadsheetControlSave",
"Content-type: text/plain; charset=UTF-8"
].join("\n") + "\n";
/* TODO: the other parts */
var meta = [
"# SocialCalc Spreadsheet Control Save",
"part:sheet"
].join("\n");
var end = "--SocialCalcSpreadsheetControlSave--";
function sheet_to_eth_data(ws) {
if(!ws || !ws['!ref']) return "";
var o = [], oo = [], cell, coord;
var r = decode_range(ws['!ref']);
var dense = Array.isArray(ws);
for(var R = r.s.r; R <= r.e.r; ++R) {
for(var C = r.s.c; C <= r.e.c; ++C) {
coord = encode_cell({r:R,c:C});
cell = dense ? (ws[R]||[])[C] : ws[coord];
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=+!!cell.v;
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
break;
case 'd':
var t = datenum(parseDate(cell.v));
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = t;
oo[5] = cell.w || SSF.format(cell.z || SSF._table[14], t);
break;
case 'e': continue;
}
o.push(oo.join(":"));
}
}
o.push("sheet:c:" + (r.e.c-r.s.c+1) + ":r:" + (r.e.r-r.s.r+1) + ":tvf:1");
o.push("valueformat:1:text-wiki");
//o.push("copiedfrom:" + ws['!ref']); // clipboard only
return o.join("\n");
}
function sheet_to_eth(ws, opts) {
return [header, sep, meta, sep, sheet_to_eth_data(ws), end].join("\n");
// return ["version:1.5", sheet_to_eth_data(ws)].join("\n"); // clipboard form
}
return {
to_workbook: eth_to_workbook,
to_sheet: eth_to_sheet,
from_sheet: sheet_to_eth
};
})();
var PRN = (function() {
function set_text_arr(data, arr, R, C, o) {
if(o.raw) arr[R][C] = data;
@ -6127,7 +6232,7 @@ var PRN = (function() {
}
function prn_to_sheet_str(str, opts) {
if(str.substr(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.slice(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts);
return aoa_to_sheet(prn_to_aoa_str(str, opts), opts);
}
@ -6143,6 +6248,7 @@ var PRN = (function() {
default: throw new Error("Unrecognized type " + opts.type);
}
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
if(str.slice(0,19) == "socialcalc:version:") return ETH.to_sheet(opts.type == 'string' ? str : utf8read(str), opts);
return prn_to_sheet_str(str, opts);
}
@ -18046,6 +18152,7 @@ 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);
var write_eth_str = write_obj_str(ETH);
function fix_opts_func(defaults) {
return function fix_opts(opts) {
@ -18626,6 +18733,7 @@ function writeSync(wb, opts) {
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 'eth': return write_string_type(write_eth_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 */
@ -18647,6 +18755,7 @@ function resolve_book_type(o) {
"xls": "biff8",
"htm": "html",
"slk": "sylk",
"socialcalc": "eth",
"Sh33tJS": "WTF"
};
var ext = o.file.slice(o.file.lastIndexOf(".")).toLowerCase();
@ -18893,6 +19002,9 @@ var utils = {
sheet_to_txt: sheet_to_txt,
sheet_to_json: sheet_to_json,
sheet_to_html: HTML_.from_sheet,
sheet_to_dif: DIF.from_sheet,
sheet_to_slk: SYLK.from_sheet,
sheet_to_eth: ETH.from_sheet,
sheet_to_formulae: sheet_to_formulae,
sheet_to_row_object_array: sheet_to_json
};

24
dist/xlsx.min.js vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.min.map vendored

File diff suppressed because one or more lines are too long

View File

@ -100,6 +100,7 @@ Plain text format guessing follows the priority order:
| DSV | more unquoted `";"` chars than `"\t"` or `","` in the first 1024 |
| TSV | more unquoted `"\t"` chars than `","` chars in the first 1024 |
| CSV | one of the first 1024 characters is a comma `","` |
| ETH | starts with `socialcalc:version:` |
| PRN | (default) |
- HTML tags include: `html`, `table`, `head`, `meta`, `script`, `style`, `div`

View File

@ -49,6 +49,7 @@ output formats. The specific file type is controlled with `bookType` option:
| `dbf` | `.dbf` | none | single | dBASE II + VFP Extensions (DBF) |
| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) |
| `prn` | `.prn` | none | single | Lotus Formatted Text |
| `eth` | `.eth` | none | single | Ethercalc Record Format (ETH) |
- `compression` only applies to formats with ZIP containers.
- Formats that only support a single sheet require a `sheet` option specifying

View File

@ -29,6 +29,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
| HTML Tables | :o: | :o: |
| Rich Text Format tables (RTF) | | :o: |
| Ethercalc Record Format (ETH) | :o: | :o: |
### Excel 2007+ XML (XLSX/XLSM)
@ -264,4 +265,14 @@ worksheet. The supported codes are a subset of the Word RTF support.
</details>
#### Ethercalc Record Format (ETH)
<details>
<summary>(click to show)</summary>
[Ethercalc](https://ethercalc.net/) is an open source web spreadsheet powered by
a record format reminiscent of SYLK wrapped in a MIME multi-part message.
</details>

View File

@ -123,6 +123,7 @@ enhancements, additional features by request, and dedicated support.
+ [Data Interchange Format (DIF)](#data-interchange-format-dif)
+ [HTML](#html)
+ [Rich Text Format (RTF)](#rich-text-format-rtf)
+ [Ethercalc Record Format (ETH)](#ethercalc-record-format-eth)
- [Testing](#testing)
* [Node](#node)
* [Browser](#browser)
@ -1455,6 +1456,7 @@ Plain text format guessing follows the priority order:
| DSV | more unquoted `";"` chars than `"\t"` or `","` in the first 1024 |
| TSV | more unquoted `"\t"` chars than `","` chars in the first 1024 |
| CSV | one of the first 1024 characters is a comma `","` |
| ETH | starts with `socialcalc:version:` |
| PRN | (default) |
- HTML tags include: `html`, `table`, `head`, `meta`, `script`, `style`, `div`
@ -1526,6 +1528,7 @@ output formats. The specific file type is controlled with `bookType` option:
| `dbf` | `.dbf` | none | single | dBASE II + VFP Extensions (DBF) |
| `rtf` | `.rtf` | none | single | Rich Text Format (RTF) |
| `prn` | `.prn` | none | single | Lotus Formatted Text |
| `eth` | `.eth` | none | single | Ethercalc Record Format (ETH) |
- `compression` only applies to formats with ZIP containers.
- Formats that only support a single sheet require a `sheet` option specifying
@ -1844,6 +1847,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
| HTML Tables | :o: | :o: |
| Rich Text Format tables (RTF) | | :o: |
| Ethercalc Record Format (ETH) | :o: | :o: |
### Excel 2007+ XML (XLSX/XLSM)
@ -2028,6 +2032,13 @@ Excel RTF worksheets are stored in clipboard when copying cells or ranges from a
worksheet. The supported codes are a subset of the Word RTF support.
#### Ethercalc Record Format (ETH)
[Ethercalc](https://ethercalc.net/) is an open source web spreadsheet powered by
a record format reminiscent of SYLK wrapped in a MIME multi-part message.
## Testing

View File

@ -76,6 +76,7 @@
+ [Data Interchange Format (DIF)](README.md#data-interchange-format-dif)
+ [HTML](README.md#html)
+ [Rich Text Format (RTF)](README.md#rich-text-format-rtf)
+ [Ethercalc Record Format (ETH)](README.md#ethercalc-record-format-eth)
- [Testing](README.md#testing)
* [Node](README.md#node)
* [Browser](README.md#browser)

View File

@ -1,6 +1,6 @@
{
"name": "xlsx",
"version": "0.11.11",
"version": "0.11.12",
"author": "sheetjs",
"description": "SheetJS Spreadsheet data parser and writer",
"keywords": [

View File

@ -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", "dbf"];
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "biff5", "biff8", "xlml", "sylk", "dif", "dbf", "eth"];
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
if(typeof process != 'undefined' && ((process||{}).env)) {
opts.WTF = true;
@ -321,7 +321,7 @@ var wbtable = {};
fileA.forEach(function(x) {
if(x.slice(-8) == ".pending" || !fs.existsSync(dir + x)) return;
it(x, function() {
var wb = X.readFile(dir + x, {WTF:opts.wtf, sheetRows:10});
var wb = X.readFile(dir + x, {WTF:opts.WTF, sheetRows:10});
parsetest(x, wb, false);
});
});
@ -623,6 +623,7 @@ describe('output formats', function() {
["csv", true, true],
["txt", true, true],
["sylk", false, true],
["eth", false, true],
["html", true, true],
["dif", false, true],
["dbf", false, false],

@ -1 +1 @@
Subproject commit e16abc3908a12be7c7293518e5fed1e31e374605
Subproject commit 8b3f773774567a164c0654a0b8056db680c3e5a5

View File

@ -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", "dbf"];
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "biff5", "biff8", "xlml", "sylk", "dif", "dbf", "eth"];
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
if(typeof process != 'undefined' && ((process||{}).env)) {
opts.WTF = true;
@ -321,7 +321,7 @@ var wbtable = {};
fileA.forEach(function(x) {
if(x.slice(-8) == ".pending" || !fs.existsSync(dir + x)) return;
it(x, function() {
var wb = X.readFile(dir + x, {WTF:opts.wtf, sheetRows:10});
var wb = X.readFile(dir + x, {WTF:opts.WTF, sheetRows:10});
parsetest(x, wb, false);
});
});
@ -623,6 +623,7 @@ describe('output formats', function() {
["csv", true, true],
["txt", true, true],
["sylk", false, true],
["eth", true, true],
["html", true, true],
["dif", false, true],
["dbf", false, false],

View File

@ -171,6 +171,7 @@ var filenames = [
['sheetjs.csv'],
['sheetjs.txt'],
['sheetjs.slk'],
['sheetjs.eth'],
['sheetjs.htm'],
['sheetjs.dif'],
['sheetjs.dbf', {sheet:"Hidden"}],

View File

@ -21,6 +21,7 @@ program
.option('-X, --xlsx', 'emit XLSX to <sheetname> or <file>.xlsx')
.option('-Y, --ods', 'emit ODS to <sheetname> or <file>.ods')
.option('-8, --xls', 'emit XLS to <sheetname> or <file>.xls (BIFF8)')
.option('-5, --biff5','emit XLS to <sheetname> or <file>.xls (BIFF5)')
.option('-2, --biff2','emit XLS to <sheetname> or <file>.xls (BIFF2)')
.option('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)')
.option('-T, --fods', 'emit FODS to <sheetname> or <file>.fods (Flat ODS)')
@ -31,8 +32,10 @@ program
.option('-A, --arrays', 'emit rows as JS objects (raw numbers)')
.option('-H, --html', 'emit HTML to <sheetname> or <file>.html')
.option('-D, --dif', 'emit DIF to <sheetname> or <file>.dif (Lotus DIF)')
.option('-U, --dbf', 'emit DBF to <sheetname> or <file>.dbf (MSVFP DBF)')
.option('-K, --sylk', 'emit SYLK to <sheetname> or <file>.slk (Excel SYLK)')
.option('-P, --prn', 'emit PRN to <sheetname> or <file>.prn (Lotus PRN)')
.option('-E, --eth', 'emit ETH to <sheetname> or <file>.eth (Ethercalc)')
.option('-t, --txt', 'emit TXT to <sheetname> or <file>.txt (UTF-8 TSV)')
.option('-r, --rtf', 'emit RTF to <sheetname> or <file>.txt (Table RTF)')
@ -41,11 +44,11 @@ program
.option('-n, --sheet-rows <num>', 'Number of rows to process (0=all rows)')
.option('--sst', 'generate shared string table for XLS* formats')
.option('--compress', 'use compression when writing XLSX/M/B and ODS')
.option('--read-only', 'do not generate output')
.option('--read', 'read but do not generate output')
.option('--book', 'for single-sheet formats, emit a file per worksheet')
.option('--all', 'parse everything; write as much as possible')
.option('--dev', 'development mode')
.option('--sparse', 'sparse mode')
.option('--read', 'read but do not print out contents')
.option('-q, --quiet', 'quiet mode');
program.on('--help', function() {
@ -81,7 +84,6 @@ if(!filename) {
console.error(n + ": must specify a filename");
process.exit(1);
}
/*:: if(filename) { */
if(!fs.existsSync(filename)) {
console.error(n + ": " + filename + ": No such file or directory");
process.exit(2);
@ -109,6 +111,9 @@ if(seen) {
} else if(program.formulae) opts.cellFormula = true;
else opts.cellFormula = false;
let wopts: X.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
if(program.compress) wopts.compression = true;
if(program.all) {
opts.cellFormula = true;
opts.bookVBA = true;
@ -117,6 +122,8 @@ if(program.all) {
opts.cellStyles = true;
opts.sheetStubs = true;
opts.cellDates = true;
wopts.cellStyles = true;
wopts.bookVBA = true;
}
if(program.sparse) opts.dense = false; else opts.dense = true;
@ -132,16 +139,13 @@ if(program.dev) {
process.exit(3);
}
if(program.read) process.exit(0);
/*:: if(wb) { */
if(!wb) { console.error(n + ": error parsing " + filename + ": empty workbook"); process.exit(0); }
/*:: if(!wb) throw new Error("unreachable"); */
if(program.listSheets) {
console.log((wb.SheetNames||[]).join("\n"));
process.exit(0);
}
let wopts: X.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
if(program.compress) wopts.compression = true;
/* full workbook formats */
workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
wopts.bookType = <X.BookType>(m[1]);
@ -173,9 +177,9 @@ try {
process.exit(4);
}
if(program.readOnly) process.exit(0);
if(!program.quiet && !program.book) console.error(target_sheet);
/* single worksheet formats */
/* single worksheet file formats */
[
['biff2', '.xls'],
['biff3', '.xls'],
@ -183,8 +187,10 @@ if(program.readOnly) process.exit(0);
['sylk', '.slk'],
['html', '.html'],
['prn', '.prn'],
['eth', '.eth'],
['rtf', '.rtf'],
['txt', '.txt'],
['dbf', '.dbf'],
['dif', '.dif']
].forEach(function(m) { if(program[m[0]] || isfmt(m[1])) {
wopts.bookType = <X.BookType>(m[0]);

42
types/index.d.ts vendored
View File

@ -7,6 +7,9 @@ export const version: string;
/** SSF Formatter Library */
export const SSF: any;
/** CFB Library */
export const CFB: any;
/** Attempts to read filename and parse */
export function readFile(filename: string, opts?: ParsingOptions): WorkBook;
/** Attempts to parse data */
@ -75,12 +78,26 @@ export interface CommonOptions {
*/
WTF?: boolean;
/**
* When reading a file with VBA macros, expose CFB blob to `vbaraw` field
* When writing BIFF8/XLSB/XLSM, reseat `vbaraw` and export to file
* @default false
*/
bookVBA?: boolean;
/**
* When reading a file, store dates as type d (default is n)
* When writing XLSX/XLSM file, use native date (default uses date codes)
* @default false
*/
cellDates?: boolean;
/**
* When reading a file, save style/theme info to the .s field
* When writing a file, export style/theme info
* @default false
*/
cellStyles?: boolean;
}
export interface DateNFOption {
@ -111,12 +128,6 @@ export interface ParsingOptions extends CommonOptions {
*/
cellNF?: boolean;
/**
* Save style/theme info to the .s field
* @default false
*/
cellStyles?: boolean;
/**
* Generate formatted text to the .w field
* @default true
@ -162,12 +173,6 @@ export interface ParsingOptions extends CommonOptions {
*/
bookSheets?: boolean;
/**
* If true, expose vbaProject.bin to vbaraw field
* @default false
*/
bookVBA?: boolean;
/**
* If defined and file is encrypted, use password
* @default ''
@ -231,6 +236,8 @@ export interface WorkBook {
Props?: FullProperties;
Workbook?: WBProps;
vbaraw?: any;
}
export interface SheetProps {
@ -483,7 +490,7 @@ export type ExcelDataType = 'b' | 'n' | 'e' | 's' | 'd' | 'z';
* Type of generated workbook
* @default 'xlsx'
*/
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'biff8' | 'biff5' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'rtf' | 'prn';
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'biff8' | 'biff5' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'rtf' | 'prn' | 'eth';
/** Comment element */
export interface Comment {
@ -658,6 +665,15 @@ export interface XLSX$Utils {
/** Generates a list of the formulae (with value fallbacks) */
sheet_to_formulae(worksheet: WorkSheet): string[];
/** Generates DIF */
sheet_to_dif(worksheet: WorkSheet, options?: Sheet2HTMLOpts): string;
/** Generates SYLK (Symbolic Link) */
sheet_to_slk(worksheet: WorkSheet, options?: Sheet2HTMLOpts): string;
/** Generates ETH */
sheet_to_eth(worksheet: WorkSheet, options?: Sheet2HTMLOpts): string;
/* --- Cell Address Utilities --- */
/** Converts 0-indexed cell address to A1 form */

View File

@ -159,6 +159,7 @@ const filenames: Array<[string]|[string, XLSX.WritingOptions]> = [
['sheetjs.csv'],
['sheetjs.txt'],
['sheetjs.slk'],
['sheetjs.eth'],
['sheetjs.htm'],
['sheetjs.dif'],
['sheetjs.dbf', {sheet:"Hidden"}],

View File

@ -21,6 +21,9 @@ interface Tester {
const jsonvalues: Tester[] = XLSX.utils.sheet_to_json<Tester>(firstworksheet);
const csv: string = XLSX.utils.sheet_to_csv(firstworksheet);
const txt: string = XLSX.utils.sheet_to_txt(firstworksheet);
const dif: string = XLSX.utils.sheet_to_dif(firstworksheet);
const slk: string = XLSX.utils.sheet_to_slk(firstworksheet);
const eth: string = XLSX.utils.sheet_to_eth(firstworksheet);
const formulae: string[] = XLSX.utils.sheet_to_formulae(firstworksheet);
const aoa: any[][] = XLSX.utils.sheet_to_json<any[]>(firstworksheet, {raw:true, header:1});

View File

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.11.11';
XLSX.version = '0.11.12';
var current_codepage = 1200;
/*:: declare var cptable:any; */
/*global cptable:true */
@ -2385,6 +2385,12 @@ function ReadShift(size/*:number*/, t/*:?string*/)/*:number|string*/ {
loc+=2;
} o = oo.join(""); size *= 2; break;
case 'cpstr':
if(typeof cptable !== 'undefined') {
o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l + size));
break;
}
/* falls through */
case 'sbcs-cont': o = ""; loc = this.l;
for(i = 0; i != size; ++i) {
if(this.lens && this.lens.indexOf(loc) !== -1) {
@ -4436,7 +4442,7 @@ function parse_XLUnicodeString2(blob, length, opts) {
if(opts.biff > 5) return parse_XLUnicodeString(blob, length, opts);
var cch = blob.read_shift(1);
if(cch === 0) { blob.l++; return ""; }
return blob.read_shift(cch, 'sbcs-cont');
return blob.read_shift(cch, opts.biff == 4 ? 'cpstr' : 'sbcs-cont');
}
/* TODO: BIFF5 and lower, codepage awareness */
function write_XLUnicodeString(str, opts, o) {
@ -6079,6 +6085,105 @@ var DIF = (function() {
};
})();
var ETH = (function() {
function decode(s/*:string*/)/*:string*/ { return s.replace(/\\b/g,"\\").replace(/\\c/g,":").replace(/\\n/g,"\n"); }
function encode(s/*:string*/)/*:string*/ { return s.replace(/\\/g, "\\b").replace(/:/g, "\\c").replace(/\n/g,"\\n"); }
function eth_to_aoa(str/*:string*/, opts)/*:AOA*/ {
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr = [];
for (; ri !== records.length; ++ri) {
var record = records[ri].trim().split(":");
if(record[0] !== 'cell') continue;
var addr = decode_cell(record[1]);
if(arr.length <= addr.r) for(R = arr.length; R <= addr.r; ++R) if(!arr[R]) arr[R] = [];
R = addr.r; C = addr.c;
switch(record[2]) {
case 't': arr[R][C] = decode(record[3]); break;
case 'v': arr[R][C] = +record[3]; break;
case 'vtf': var _f = record[record.length - 1];
/* falls through */
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
}
return arr;
}
function eth_to_sheet(d/*:string*/, opts)/*:Worksheet*/ { return aoa_to_sheet(eth_to_aoa(d, opts), opts); }
function eth_to_workbook(d/*:string*/, opts)/*:Workbook*/ { return sheet_to_workbook(eth_to_sheet(d, opts), opts); }
var header = [
"socialcalc:version:1.5",
"MIME-Version: 1.0",
"Content-Type: multipart/mixed; boundary=SocialCalcSpreadsheetControlSave"
].join("\n");
var sep = [
"--SocialCalcSpreadsheetControlSave",
"Content-type: text/plain; charset=UTF-8"
].join("\n") + "\n";
/* TODO: the other parts */
var meta = [
"# SocialCalc Spreadsheet Control Save",
"part:sheet"
].join("\n");
var end = "--SocialCalcSpreadsheetControlSave--";
function sheet_to_eth_data(ws/*:Worksheet*/)/*:string*/ {
if(!ws || !ws['!ref']) return "";
var o = [], oo = [], cell, coord;
var r = decode_range(ws['!ref']);
var dense = Array.isArray(ws);
for(var R = r.s.r; R <= r.e.r; ++R) {
for(var C = r.s.c; C <= r.e.c; ++C) {
coord = encode_cell({r:R,c:C});
cell = dense ? (ws[R]||[])[C] : ws[coord];
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=+!!cell.v;
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
break;
case 'd':
var t = datenum(parseDate(cell.v));
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = t;
oo[5] = cell.w || SSF.format(cell.z || SSF._table[14], t);
break;
case 'e': continue;
}
o.push(oo.join(":"));
}
}
o.push("sheet:c:" + (r.e.c-r.s.c+1) + ":r:" + (r.e.r-r.s.r+1) + ":tvf:1");
o.push("valueformat:1:text-wiki");
//o.push("copiedfrom:" + ws['!ref']); // clipboard only
return o.join("\n");
}
function sheet_to_eth(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
return [header, sep, meta, sep, sheet_to_eth_data(ws), end].join("\n");
// return ["version:1.5", sheet_to_eth_data(ws)].join("\n"); // clipboard form
}
return {
to_workbook: eth_to_workbook,
to_sheet: eth_to_sheet,
from_sheet: sheet_to_eth
};
})();
var PRN = (function() {
function set_text_arr(data/*:string*/, arr/*:AOA*/, R/*:number*/, C/*:number*/, o/*:any*/) {
if(o.raw) arr[R][C] = data;
@ -6212,7 +6317,7 @@ var PRN = (function() {
}
function prn_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
if(str.substr(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.slice(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts);
return aoa_to_sheet(prn_to_aoa_str(str, opts), opts);
}
@ -6228,6 +6333,7 @@ var PRN = (function() {
default: throw new Error("Unrecognized type " + opts.type);
}
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
if(str.slice(0,19) == "socialcalc:version:") return ETH.to_sheet(opts.type == 'string' ? str : utf8read(str), opts);
return prn_to_sheet_str(str, opts);
}
@ -18148,6 +18254,7 @@ 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);
var write_eth_str = write_obj_str(ETH);
function fix_opts_func(defaults/*:Array<Array<any> >*/)/*:{(o:any):void}*/ {
return function fix_opts(opts) {
@ -18732,6 +18839,7 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
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 'eth': return write_string_type(write_eth_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 */
@ -18753,6 +18861,7 @@ function resolve_book_type(o/*:WriteFileOpts*/) {
"xls": "biff8",
"htm": "html",
"slk": "sylk",
"socialcalc": "eth",
"Sh33tJS": "WTF"
};
var ext = o.file.slice(o.file.lastIndexOf(".")).toLowerCase();
@ -18999,6 +19108,9 @@ var utils/*:any*/ = {
sheet_to_txt: sheet_to_txt,
sheet_to_json: sheet_to_json,
sheet_to_html: HTML_.from_sheet,
sheet_to_dif: DIF.from_sheet,
sheet_to_slk: SYLK.from_sheet,
sheet_to_eth: ETH.from_sheet,
sheet_to_formulae: sheet_to_formulae,
sheet_to_row_object_array: sheet_to_json
};

118
xlsx.js
View File

@ -4,7 +4,7 @@
/*global global, exports, module, require:false, process:false, Buffer:false */
var XLSX = {};
(function make_xlsx(XLSX){
XLSX.version = '0.11.11';
XLSX.version = '0.11.12';
var current_codepage = 1200;
/*global cptable:true */
if(typeof module !== "undefined" && typeof require !== 'undefined') {
@ -2313,6 +2313,12 @@ function ReadShift(size, t) {
loc+=2;
} o = oo.join(""); size *= 2; break;
case 'cpstr':
if(typeof cptable !== 'undefined') {
o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l + size));
break;
}
/* falls through */
case 'sbcs-cont': o = ""; loc = this.l;
for(i = 0; i != size; ++i) {
if(this.lens && this.lens.indexOf(loc) !== -1) {
@ -4351,7 +4357,7 @@ function parse_XLUnicodeString2(blob, length, opts) {
if(opts.biff > 5) return parse_XLUnicodeString(blob, length, opts);
var cch = blob.read_shift(1);
if(cch === 0) { blob.l++; return ""; }
return blob.read_shift(cch, 'sbcs-cont');
return blob.read_shift(cch, opts.biff == 4 ? 'cpstr' : 'sbcs-cont');
}
/* TODO: BIFF5 and lower, codepage awareness */
function write_XLUnicodeString(str, opts, o) {
@ -5994,6 +6000,105 @@ var DIF = (function() {
};
})();
var ETH = (function() {
function decode(s) { return s.replace(/\\b/g,"\\").replace(/\\c/g,":").replace(/\\n/g,"\n"); }
function encode(s) { return s.replace(/\\/g, "\\b").replace(/:/g, "\\c").replace(/\n/g,"\\n"); }
function eth_to_aoa(str, opts) {
var records = str.split('\n'), R = -1, C = -1, ri = 0, arr = [];
for (; ri !== records.length; ++ri) {
var record = records[ri].trim().split(":");
if(record[0] !== 'cell') continue;
var addr = decode_cell(record[1]);
if(arr.length <= addr.r) for(R = arr.length; R <= addr.r; ++R) if(!arr[R]) arr[R] = [];
R = addr.r; C = addr.c;
switch(record[2]) {
case 't': arr[R][C] = decode(record[3]); break;
case 'v': arr[R][C] = +record[3]; break;
case 'vtf': var _f = record[record.length - 1];
/* falls through */
case 'vtc':
switch(record[3]) {
case 'nl': arr[R][C] = +record[4] ? true : false; break;
default: arr[R][C] = +record[4]; break;
}
if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
}
}
return arr;
}
function eth_to_sheet(d, opts) { return aoa_to_sheet(eth_to_aoa(d, opts), opts); }
function eth_to_workbook(d, opts) { return sheet_to_workbook(eth_to_sheet(d, opts), opts); }
var header = [
"socialcalc:version:1.5",
"MIME-Version: 1.0",
"Content-Type: multipart/mixed; boundary=SocialCalcSpreadsheetControlSave"
].join("\n");
var sep = [
"--SocialCalcSpreadsheetControlSave",
"Content-type: text/plain; charset=UTF-8"
].join("\n") + "\n";
/* TODO: the other parts */
var meta = [
"# SocialCalc Spreadsheet Control Save",
"part:sheet"
].join("\n");
var end = "--SocialCalcSpreadsheetControlSave--";
function sheet_to_eth_data(ws) {
if(!ws || !ws['!ref']) return "";
var o = [], oo = [], cell, coord;
var r = decode_range(ws['!ref']);
var dense = Array.isArray(ws);
for(var R = r.s.r; R <= r.e.r; ++R) {
for(var C = r.s.c; C <= r.e.c; ++C) {
coord = encode_cell({r:R,c:C});
cell = dense ? (ws[R]||[])[C] : ws[coord];
if(!cell || cell.v == null || cell.t === 'z') continue;
oo = ["cell", coord, 't'];
switch(cell.t) {
case 's': case 'str': oo.push(encode(cell.v)); break;
case 'n':
if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
break;
case 'b':
oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=+!!cell.v;
oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
break;
case 'd':
var t = datenum(parseDate(cell.v));
oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = t;
oo[5] = cell.w || SSF.format(cell.z || SSF._table[14], t);
break;
case 'e': continue;
}
o.push(oo.join(":"));
}
}
o.push("sheet:c:" + (r.e.c-r.s.c+1) + ":r:" + (r.e.r-r.s.r+1) + ":tvf:1");
o.push("valueformat:1:text-wiki");
//o.push("copiedfrom:" + ws['!ref']); // clipboard only
return o.join("\n");
}
function sheet_to_eth(ws, opts) {
return [header, sep, meta, sep, sheet_to_eth_data(ws), end].join("\n");
// return ["version:1.5", sheet_to_eth_data(ws)].join("\n"); // clipboard form
}
return {
to_workbook: eth_to_workbook,
to_sheet: eth_to_sheet,
from_sheet: sheet_to_eth
};
})();
var PRN = (function() {
function set_text_arr(data, arr, R, C, o) {
if(o.raw) arr[R][C] = data;
@ -6127,7 +6232,7 @@ var PRN = (function() {
}
function prn_to_sheet_str(str, opts) {
if(str.substr(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.slice(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
if(str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts);
return aoa_to_sheet(prn_to_aoa_str(str, opts), opts);
}
@ -6143,6 +6248,7 @@ var PRN = (function() {
default: throw new Error("Unrecognized type " + opts.type);
}
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
if(str.slice(0,19) == "socialcalc:version:") return ETH.to_sheet(opts.type == 'string' ? str : utf8read(str), opts);
return prn_to_sheet_str(str, opts);
}
@ -18046,6 +18152,7 @@ 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);
var write_eth_str = write_obj_str(ETH);
function fix_opts_func(defaults) {
return function fix_opts(opts) {
@ -18626,6 +18733,7 @@ function writeSync(wb, opts) {
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 'eth': return write_string_type(write_eth_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 */
@ -18647,6 +18755,7 @@ function resolve_book_type(o) {
"xls": "biff8",
"htm": "html",
"slk": "sylk",
"socialcalc": "eth",
"Sh33tJS": "WTF"
};
var ext = o.file.slice(o.file.lastIndexOf(".")).toLowerCase();
@ -18893,6 +19002,9 @@ var utils = {
sheet_to_txt: sheet_to_txt,
sheet_to_json: sheet_to_json,
sheet_to_html: HTML_.from_sheet,
sheet_to_dif: DIF.from_sheet,
sheet_to_slk: SYLK.from_sheet,
sheet_to_eth: ETH.from_sheet,
sheet_to_formulae: sheet_to_formulae,
sheet_to_row_object_array: sheet_to_json
};