]*>)/i);
var R = -1, C = 0, RS = 0, CS = 0;
var range = {s:{r:10000000, c:10000000},e:{r:0,c:0}};
diff --git a/bits/82_sheeter.js b/bits/82_sheeter.js
index 91f8898..12e3a9b 100644
--- a/bits/82_sheeter.js
+++ b/bits/82_sheeter.js
@@ -13,4 +13,5 @@ var write_csv_str = write_obj_str({from_sheet:sheet_to_csv});
var write_slk_str = write_obj_str(SYLK);
var write_dif_str = write_obj_str(DIF);
var write_prn_str = write_obj_str(PRN);
+var write_rtf_str = write_obj_str(RTF);
var write_txt_str = write_obj_str({from_sheet:sheet_to_txt});
diff --git a/bits/87_read.js b/bits/87_read.js
index e9eee10..25f9a41 100644
--- a/bits/87_read.js
+++ b/bits/87_read.js
@@ -78,7 +78,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
case 0xFF: if(n[1] == 0xFE){ return read_utf16(d, o); } break;
case 0x00: if(n[1] == 0x00 && n[2] >= 0x02 && n[3] == 0x00) return WK_.to_workbook(d, o); break;
case 0x03: case 0x83: case 0x8B: return DBF.to_workbook(d, o);
- case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) throw new Error("Unsupported RTF"); break;
+ case 0x7B: if(n[1] == 0x5C && n[2] == 0x72 && n[3] == 0x74) return RTF.to_workbook(d, o); break;
case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
}
if(n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
diff --git a/bits/88_write.js b/bits/88_write.js
index 534db22..7e85975 100644
--- a/bits/88_write.js
+++ b/bits/88_write.js
@@ -69,6 +69,7 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
case 'csv': return write_string_type(write_csv_str(wb, o), o);
case 'dif': return write_string_type(write_dif_str(wb, o), o);
case 'prn': return write_string_type(write_prn_str(wb, o), o);
+ case 'rtf': return write_string_type(write_rtf_str(wb, o), o);
case 'fods': return write_string_type(write_ods(wb, o), o);
case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
case 'xlsx':
@@ -95,6 +96,7 @@ function resolve_book_type(o/*?WriteFileOpts*/) {
case '.txt': o.bookType = 'txt'; break;
case '.dif': o.bookType = 'dif'; break;
case '.prn': o.bookType = 'prn'; break;
+ case '.rtf': o.bookType = 'rtf'; break;
case '.slk': o.bookType = 'sylk'; break;
case '.htm': o.bookType = 'html'; break;
}
diff --git a/bits/90_utils.js b/bits/90_utils.js
index 0e773be..bfe6de1 100644
--- a/bits/90_utils.js
+++ b/bits/90_utils.js
@@ -112,11 +112,11 @@ function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row = "", cols = [];
o.dense = Array.isArray(sheet);
- var colInfos = o.skipHidden ? sheet["!cols"] : undefined;
- var rowInfos = o.skipHidden ? sheet["!rows"] : undefined;
- for(var C = r.s.c; C <= r.e.c; ++C) if (!colInfos || !colInfos[C] || !colInfos[C].hidden) cols[C] = encode_col(C);
+ var colInfos = o.skipHidden && sheet["!cols"] || [];
+ var rowInfos = o.skipHidden && sheet["!rows"] || [];
+ for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
for(var R = r.s.r; R <= r.e.r; ++R) {
- if (rowInfos && rowInfos[R] && rowInfos[R].hidden) continue;
+ if ((rowInfos[R]||{}).hidden) continue;
row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
if(row == null) { continue; }
if(o.strip) row = row.replace(endregex,"");
diff --git a/bits/97_node.js b/bits/97_node.js
index b0cb6d8..b7c668d 100644
--- a/bits/97_node.js
+++ b/bits/97_node.js
@@ -12,13 +12,16 @@ if(has_buf && typeof require != 'undefined') (function() {
var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
var row/*:?string*/ = "", cols = [];
o.dense = Array.isArray(sheet);
- for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
+ var colInfos = o.skipHidden && sheet["!cols"] || [];
+ var rowInfos = o.skipHidden && sheet["!rows"] || [];
+ for(var C = r.s.c; C <= r.e.c; ++C) if (!((colInfos[C]||{}).hidden)) cols[C] = encode_col(C);
var R = r.s.r;
stream._read = function() {
if(R > r.e.r) return stream.push(null);
while(R <= r.e.r) {
- row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
++R;
+ if ((rowInfos[R-1]||{}).hidden) continue;
+ row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
if(row != null) {
if(o.strip) row = row.replace(endregex,"");
stream.push(row + RS);
diff --git a/demos/requirejs/Makefile b/demos/requirejs/Makefile
index e608a58..03bafed 100644
--- a/demos/requirejs/Makefile
+++ b/demos/requirejs/Makefile
@@ -6,4 +6,5 @@ all: $(TOOL).js
$(TOOL).js:
if [ ! -e require.js ]; then curl -O http://requirejs.org/docs/release/2.3.3/comments/require.js; fi
if [ ! -e r.js ]; then curl -O http://requirejs.org/docs/release/2.3.3/r.js; fi
+ rm -f xlsx.full.min.js; ln -s ../../dist/xlsx.full.min.js
node r.js -o build.js
diff --git a/demos/requirejs/README.md b/demos/requirejs/README.md
new file mode 100644
index 0000000..afb6a86
--- /dev/null
+++ b/demos/requirejs/README.md
@@ -0,0 +1,11 @@
+# RequireJS
+
+The minified dist files trip up the RequireJS mechanism. To bypass, the scripts
+automatically expose an `XLSX` variable that can be used if the require callback
+argument is `_XLSX` rather than `XLSX`:
+
+```js
+require(["xlsx.full.min"], function(_XLSX) { /* ... */ });
+```
+
+This demo uses the `r.js` optimizer to build a source file.
diff --git a/demos/requirejs/requirejs.html b/demos/requirejs/requirejs.html
new file mode 100644
index 0000000..63118ad
--- /dev/null
+++ b/demos/requirejs/requirejs.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+JS-XLSX Live Demo
+
+
+
+JS-XLSX Live Demo
+Output Format:
+
+
+Drop a spreadsheet file here to see sheet data
+ ... or click here to select a file
+
+
+Advanced Demo Options:
+Use Web Workers: (when available)
+Use Transferrables: (when available)
+Use readAsBinaryString: (when available)
+
+
+
+
+
+
+
diff --git a/demos/requirejs/requirejs.js b/demos/requirejs/requirejs.js
index 32918e1..3ffde2f 100644
--- a/demos/requirejs/requirejs.js
+++ b/demos/requirejs/requirejs.js
@@ -1,4 +1,4 @@
-require(["xlsx.full"], function(_XLSX) {
+require(["xlsx.full.min"], function(_XLSX) {
var X = XLSX;
var rABS = typeof FileReader !== "undefined" && typeof FileReader.prototype !== "undefined" && typeof FileReader.prototype.readAsBinaryString !== "undefined";
diff --git a/demos/webpack/.gitignore b/demos/webpack/.gitignore
index 3620fff..e47b5c1 100644
--- a/demos/webpack/.gitignore
+++ b/demos/webpack/.gitignore
@@ -1,2 +1,3 @@
webpack.js
webpack.min.js
+*.out.js
diff --git a/demos/webpack/Makefile b/demos/webpack/Makefile
index 2ab7c07..f2b1c2f 100644
--- a/demos/webpack/Makefile
+++ b/demos/webpack/Makefile
@@ -1,10 +1,15 @@
TOOL=webpack
+WPOPTS=--display-modules --display-reasons --profile
.PHONY: all
-all: $(TOOL).min.js
+all: $(TOOL).min.js core.out.js full.out.js
$(TOOL).min.js: $(TOOL).js
uglifyjs $< > $@
.PHONY: $(TOOL).js
$(TOOL).js:
- webpack main.js --output-filename $@ --display-modules --profile
+ webpack main.js --output-filename $@ $(WPOPTS)
+
+.PHONY: core.out.js full.out.js
+core.out.js full.out.js: %.out.js: %.js
+ webpack $< --output-filename $@ $(WPOPTS)
diff --git a/demos/webpack/README.md b/demos/webpack/README.md
index f33eefb..11de320 100644
--- a/demos/webpack/README.md
+++ b/demos/webpack/README.md
@@ -40,3 +40,16 @@ the module can be omitted by aliasing the dependency:
alias: { "./dist/cpexcel.js": "" }
},
```
+
+## Bower and minified versions
+
+The minified versions, used in Bower, require `module.noParse` configuration:
+
+```js
+ module: {
+ noParse: [
+ /xlsx.core.min.js/,
+ /xlsx.full.min.js/
+ ]
+ }
+```
diff --git a/demos/webpack/app.js b/demos/webpack/app.js
new file mode 100644
index 0000000..a47ca30
--- /dev/null
+++ b/demos/webpack/app.js
@@ -0,0 +1,227 @@
+/*jshint browser:true */
+/*global XLSX */
+var X = XLSX;
+
+var rABS = typeof FileReader !== "undefined" && typeof FileReader.prototype !== "undefined" && typeof FileReader.prototype.readAsBinaryString !== "undefined";
+if(!rABS) {
+ document.getElementsByName("userabs")[0].disabled = true;
+ document.getElementsByName("userabs")[0].checked = false;
+}
+
+var use_worker = typeof Worker !== 'undefined';
+if(!use_worker) {
+ document.getElementsByName("useworker")[0].disabled = true;
+ document.getElementsByName("useworker")[0].checked = false;
+}
+
+var transferable = use_worker;
+if(!transferable) {
+ document.getElementsByName("xferable")[0].disabled = true;
+ document.getElementsByName("xferable")[0].checked = false;
+}
+
+var wtf_mode = false;
+
+function fixdata(data) {
+ var o = "", l = 0, w = 10240;
+ for(; l 0){
+ result[sheetName] = roa;
+ }
+ });
+ return result;
+}
+
+function to_csv(workbook) {
+ var result = [];
+ workbook.SheetNames.forEach(function(sheetName) {
+ var csv = X.utils.sheet_to_csv(workbook.Sheets[sheetName]);
+ if(csv.length > 0){
+ result.push("SHEET: " + sheetName);
+ result.push("");
+ result.push(csv);
+ }
+ });
+ return result.join("\n");
+}
+
+function to_formulae(workbook) {
+ var result = [];
+ workbook.SheetNames.forEach(function(sheetName) {
+ var formulae = X.utils.get_formulae(workbook.Sheets[sheetName]);
+ if(formulae.length > 0){
+ result.push("SHEET: " + sheetName);
+ result.push("");
+ result.push(formulae.join("\n"));
+ }
+ });
+ return result.join("\n");
+}
+
+var tarea = document.getElementById('b64data');
+function b64it() {
+ if(typeof console !== 'undefined') console.log("onload", new Date());
+ var wb = X.read(tarea.value, {type: 'base64',WTF:wtf_mode});
+ process_wb(wb);
+}
+
+function process_wb(wb) {
+ var output = "";
+ switch(get_radio_value("format")) {
+ case "json":
+ output = JSON.stringify(to_json(wb), 2, 2);
+ break;
+ case "form":
+ output = to_formulae(wb);
+ break;
+ default:
+ output = to_csv(wb);
+ }
+ if(out.innerText === undefined) out.textContent = output;
+ else out.innerText = output;
+ if(typeof console !== 'undefined') console.log("output", new Date());
+}
+
+var drop = document.getElementById('drop');
+function handleDrop(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ rABS = document.getElementsByName("userabs")[0].checked;
+ use_worker = document.getElementsByName("useworker")[0].checked;
+ var files = e.dataTransfer.files;
+ var f = files[0];
+ {
+ var reader = new FileReader();
+ var name = f.name;
+ reader.onload = function(e) {
+ if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
+ var data = e.target.result;
+ if(use_worker) {
+ xw(data, process_wb);
+ } else {
+ var wb;
+ if(rABS) {
+ wb = X.read(data, {type: 'binary'});
+ } else {
+ var arr = fixdata(data);
+ wb = X.read(btoa(arr), {type: 'base64'});
+ }
+ process_wb(wb);
+ }
+ };
+ if(rABS) reader.readAsBinaryString(f);
+ else reader.readAsArrayBuffer(f);
+ }
+}
+
+function handleDragover(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ e.dataTransfer.dropEffect = 'copy';
+}
+
+if(drop.addEventListener) {
+ drop.addEventListener('dragenter', handleDragover, false);
+ drop.addEventListener('dragover', handleDragover, false);
+ drop.addEventListener('drop', handleDrop, false);
+}
+
+
+var xlf = document.getElementById('xlf');
+function handleFile(e) {
+ rABS = document.getElementsByName("userabs")[0].checked;
+ use_worker = document.getElementsByName("useworker")[0].checked;
+ var files = e.target.files;
+ var f = files[0];
+ {
+ var reader = new FileReader();
+ var name = f.name;
+ reader.onload = function(e) {
+ if(typeof console !== 'undefined') console.log("onload", new Date(), rABS, use_worker);
+ var data = e.target.result;
+ if(use_worker) {
+ xw(data, process_wb);
+ } else {
+ var wb;
+ if(rABS) {
+ wb = X.read(data, {type: 'binary'});
+ } else {
+ var arr = fixdata(data);
+ wb = X.read(btoa(arr), {type: 'base64'});
+ }
+ process_wb(wb);
+ }
+ };
+ if(rABS) reader.readAsBinaryString(f);
+ else reader.readAsArrayBuffer(f);
+ }
+}
+
+if(xlf.addEventListener) xlf.addEventListener('change', handleFile, false);
+
diff --git a/demos/webpack/core.js b/demos/webpack/core.js
new file mode 100644
index 0000000..2a702bc
--- /dev/null
+++ b/demos/webpack/core.js
@@ -0,0 +1,3 @@
+var XLSX = require('./xlsx.core.min');
+console.log("it works!");
+module.exports = XLSX;
diff --git a/demos/webpack/coreworker.js b/demos/webpack/coreworker.js
new file mode 100644
index 0000000..4c97468
--- /dev/null
+++ b/demos/webpack/coreworker.js
@@ -0,0 +1,11 @@
+/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
+importScripts('core.out.js');
+postMessage({t:"ready"});
+
+onmessage = function (oEvent) {
+ var v;
+ try {
+ v = XLSX.read(oEvent.data.d, {type: oEvent.data.b ? 'binary' : 'base64'});
+ } catch(e) { postMessage({t:"e",d:e.stack||e}); }
+postMessage({t:"xlsx", d:JSON.stringify(v)});
+};
diff --git a/demos/webpack/coreworker1.js b/demos/webpack/coreworker1.js
new file mode 100644
index 0000000..34a36a5
--- /dev/null
+++ b/demos/webpack/coreworker1.js
@@ -0,0 +1,26 @@
+/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
+importScripts('core.out.js');
+postMessage({t:"ready"});
+
+function ab2str(data) {
+ var o = "", l = 0, w = 10240;
+ for(; l
+