forked from sheetjs/sheetjs
version bump 0.10.5
- HTML output new preamble, <table> should not be in header/footer - XLS Built-In defined names translated to XLSX _xlnm form - README: streaming read strategies - If approximation error is sufficiently small, assume MDW is 6 - TS rename Utils type to XLSX$Utils (see #618)
This commit is contained in:
parent
da1c111275
commit
5d997df419
@ -5,7 +5,7 @@ but not limited to API changes and file location changes. Minor behavioral
|
||||
changes may not be included if they are not expected to break existing code.
|
||||
|
||||
|
||||
## Unreleased (2017-06-??)
|
||||
## 0.10.5 (2017-06-09)
|
||||
|
||||
* HTML Table output header/footer should not include `<table>` tag
|
||||
|
||||
|
69
README.md
69
README.md
@ -60,7 +60,7 @@ enhancements, additional features by request, and dedicated support.
|
||||
- [Philosophy](#philosophy)
|
||||
- [Parsing Workbooks](#parsing-workbooks)
|
||||
* [Complete Examples](#complete-examples)
|
||||
* [Note on Streaming Read](#note-on-streaming-read)
|
||||
* [Streaming Read](#streaming-read)
|
||||
- [Working with the Workbook](#working-with-the-workbook)
|
||||
* [Complete Examples](#complete-examples-1)
|
||||
- [Writing Workbooks](#writing-workbooks)
|
||||
@ -429,7 +429,10 @@ On Windows XP and up you can get the base64 encoding using `certutil`:
|
||||
|
||||
- <http://oss.sheetjs.com/js-xlsx/ajax.html> XMLHttpRequest
|
||||
|
||||
### Note on Streaming Read
|
||||
### Streaming Read
|
||||
|
||||
<details>
|
||||
<summary><b>Why is there no Streaming Read API?</b> (click to show)</summary>
|
||||
|
||||
The most common and interesting formats (XLS, XLSX/M, XLSB, ODS) are ultimately
|
||||
ZIP or CFB containers of files. Neither format puts the directory structure at
|
||||
@ -437,9 +440,61 @@ the beginning of the file: ZIP files place the Central Directory records at the
|
||||
end of the logical file, while CFB files can place the FAT structure anywhere in
|
||||
the file! As a result, to properly handle these formats, a streaming function
|
||||
would have to buffer the entire file before commencing. That belies the
|
||||
expectations of streaming, so we do not provide any streaming read API. If you
|
||||
really want to stream, there are node modules like `concat-stream` that will do
|
||||
the buffering for you.
|
||||
expectations of streaming, so we do not provide any streaming read API.
|
||||
|
||||
</details>
|
||||
|
||||
When dealing with Readable Streams, the easiest approach is to buffer the stream
|
||||
and process the whole thing at the end. This can be done with a temporary file
|
||||
or by explicitly concatenating the stream:
|
||||
|
||||
<details>
|
||||
<summary><b>Explicitly concatenating streams</b> (click to show)</summary>
|
||||
|
||||
```js
|
||||
var fs = require('fs');
|
||||
var XLSX = require('xlsx');
|
||||
function process_RS(stream/*:ReadStream*/, cb/*:(wb:Workbook)=>void*/)/*:void*/{
|
||||
var buffers = [];
|
||||
stream.on('data', function(data) { buffers.push(data); });
|
||||
stream.on('end', function() {
|
||||
var buffer = Buffer.concat(buffers);
|
||||
var workbook = XLSX.read(buffer, {type:"buffer"});
|
||||
|
||||
/* DO SOMETHING WITH workbook IN THE CALLBACK */
|
||||
cb(workbook);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
More robust solutions are available using modules like `concat-stream`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Writing to filesystem first</b> (click to show)</summary>
|
||||
|
||||
This example uses [`tempfile`](https://npm.im/tempfile) for filenames:
|
||||
|
||||
```js
|
||||
var fs = require('fs'), tempfile = require('tempfile');
|
||||
var XLSX = require('xlsx');
|
||||
function process_RS(stream/*:ReadStream*/, cb/*:(wb:Workbook)=>void*/)/*:void*/{
|
||||
var fname = tempfile('.sheetjs');
|
||||
console.log(fname);
|
||||
var ostream = fs.createWriteStream(fname);
|
||||
stream.pipe(ostream);
|
||||
ostream.on('finish', function() {
|
||||
var workbook = XLSX.readFile(fname);
|
||||
fs.unlinkSync(fname);
|
||||
|
||||
/* DO SOMETHING WITH workbook IN THE CALLBACK */
|
||||
cb(workbook);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Working with the Workbook
|
||||
|
||||
@ -558,8 +613,8 @@ saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), "test.xlsx");
|
||||
### Streaming Write
|
||||
|
||||
The streaming write functions are available in the `XLSX.stream` object. They
|
||||
take the same arguments as the normal write functions but return a readable
|
||||
stream. They are only exposed in node.
|
||||
take the same arguments as the normal write functions but return a Readable
|
||||
Stream. They are only exposed in NodeJS.
|
||||
|
||||
- `XLSX.stream.to_csv` is the streaming version of `XLSX.utils.sheet_to_csv`.
|
||||
- `XLSX.stream.to_html` is the streaming version of `XLSX.utils.sheet_to_html`.
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.10.4';
|
||||
XLSX.version = '0.10.5';
|
||||
|
@ -15,5 +15,5 @@ type EvertArrType = {[string]:Array<string>};
|
||||
|
||||
type StringConv = {(string):string};
|
||||
|
||||
type WriteObjStrFactory = {from_sheet(ws:Worksheet, o:any):string};
|
||||
type WriteObjStrFactory = {from_sheet(ws:Worksheet, o:any, wb:?Workbook):string};
|
||||
*/
|
||||
|
@ -441,10 +441,11 @@ function parse_SupBook(blob, length, opts) {
|
||||
var end = blob.l + length;
|
||||
var ctab = blob.read_shift(2);
|
||||
var cch = blob.read_shift(2);
|
||||
var virtPath;
|
||||
if(cch >=0x01 && cch <=0xff) virtPath = parse_XLUnicodeStringNoCch(blob, cch);
|
||||
var rgst = blob.read_shift(end - blob.l);
|
||||
opts.sbcch = cch;
|
||||
if(cch == 0x0401 || cch == 0x3A01) return [cch, ctab];
|
||||
if(cch < 0x01 || cch >0xff) throw new Error("Unexpected SupBook type: "+cch);
|
||||
var virtPath = parse_XLUnicodeStringNoCch(blob, cch);
|
||||
var rgst = blob.read_shift(end - blob.l);
|
||||
return [cch, ctab, virtPath, rgst];
|
||||
}
|
||||
|
||||
@ -469,6 +470,22 @@ function parse_ExternName(blob, length, opts) {
|
||||
}
|
||||
|
||||
/* 2.4.150 TODO */
|
||||
var XLSLblBuiltIn = [
|
||||
"_xlnm.Consolidate_Area",
|
||||
"_xlnm.Auto_Open",
|
||||
"_xlnm.Auto_Close",
|
||||
"_xlnm.Extract",
|
||||
"_xlnm.Database",
|
||||
"_xlnm.Criteria",
|
||||
"_xlnm.Print_Area",
|
||||
"_xlnm.Print_Titles",
|
||||
"_xlnm.Recorder",
|
||||
"_xlnm.Data_Form",
|
||||
"_xlnm.Auto_Activate",
|
||||
"_xlnm.Auto_Deactivate",
|
||||
"_xlnm.Sheet_Title",
|
||||
"_xlnm._FilterDatabase"
|
||||
];
|
||||
function parse_Lbl(blob, length, opts) {
|
||||
var target = blob.l + length;
|
||||
var flags = blob.read_shift(2);
|
||||
@ -482,6 +499,7 @@ function parse_Lbl(blob, length, opts) {
|
||||
blob.l += 4;
|
||||
}
|
||||
var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
|
||||
if(flags & 0x20) name = XLSLblBuiltIn[name.charCodeAt(0)];
|
||||
var npflen = target - blob.l; if(opts && opts.biff == 2) --npflen;
|
||||
var rgce = target == blob.l || cce == 0 ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
|
||||
return {
|
||||
|
@ -60,8 +60,8 @@ function char2width_(chr) { return (((chr * MDW + 5)/MDW*256))/256; }
|
||||
function cycle_width(collw) { return char2width(px2char(width2px(collw))); }
|
||||
/* XLSX/XLSB/XLS specify width in units of MDW */
|
||||
function find_mdw_colw(collw) {
|
||||
var delta = Infinity, _MDW = MIN_MDW;
|
||||
for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
|
||||
var delta = Math.abs(collw - cycle_width(collw)), _MDW = MDW;
|
||||
if(delta > 0.005) for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
|
||||
MDW = _MDW;
|
||||
}
|
||||
/* XLML specifies width in terms of pixels */
|
||||
|
@ -260,11 +260,13 @@ function write_numFmts(NF/*:{[n:number]:string}*/, opts) {
|
||||
}
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs */
|
||||
var cellXF_uint = [ "numFmtId", "fillId", "fontId", "borderId", "xfId" ];
|
||||
var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "applyNumberFormat", "applyProtection", "pivotButton", "quotePrefix" ];
|
||||
function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
var xf;
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
var y = parsexmltag(x), i = 0;
|
||||
switch(y[0]) {
|
||||
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
|
||||
|
||||
@ -272,8 +274,10 @@ function parse_cellXfs(t, styles, opts) {
|
||||
case '<xf':
|
||||
xf = y;
|
||||
delete xf[0];
|
||||
if(xf.numFmtId) xf.numFmtId = parseInt(xf.numFmtId, 10);
|
||||
if(xf.fillId) xf.fillId = parseInt(xf.fillId, 10);
|
||||
for(i = 0; i < cellXF_uint.length; ++i) if(xf[cellXF_uint[i]])
|
||||
xf[cellXF_uint[i]] = parseInt(xf[cellXF_uint[i]], 10);
|
||||
for(i = 0; i < cellXF_bool.length; ++i) if(xf[cellXF_bool[i]])
|
||||
xf[cellXF_bool[i]] = parsexmlbool(xf[cellXF_bool[i]], "");
|
||||
styles.CellXf.push(xf); break;
|
||||
case '</xf>': break;
|
||||
|
||||
|
@ -19,7 +19,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksh
|
||||
var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/);
|
||||
|
||||
var data1 = "", data2 = "";
|
||||
var mtch/*:?any*/ =data.match(sheetdataregex);
|
||||
var mtch/*:?any*/ = data.match(sheetdataregex);
|
||||
if(mtch) {
|
||||
data1 = data.substr(0, mtch.index);
|
||||
data2 = data.substr(mtch.index + mtch[0].length);
|
||||
|
@ -256,7 +256,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
||||
row = xlml_parsexmltag(Rn[0]);
|
||||
if(row.Index) r = +row.Index - 1;
|
||||
rowobj = {};
|
||||
if(row.AutoFitHeight == "0") {
|
||||
if(row.AutoFitHeight == "0" || row.Height) {
|
||||
rowobj.hpx = parseInt(row.Height, 10); rowobj.hpt = px2pt(rowobj.hpx);
|
||||
rowinfo[r] = rowobj;
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
supbooks.names.push(last_lbl);
|
||||
if(!supbooks[0]) supbooks[0] = [];
|
||||
supbooks[supbooks.length-1].push(val);
|
||||
if(val.Name == "\r" && val.itab > 0)
|
||||
if(val.Name == "_xlnm._FilterDatabase" && val.itab > 0)
|
||||
if(val.rgce && val.rgce[0] && val.rgce[0][0] && val.rgce[0][0][0] == 'PtgArea3d')
|
||||
FilterDatabases[val.itab - 1] = { ref: encode_range(val.rgce[0][0][1][2]) };
|
||||
break;
|
||||
|
@ -82,7 +82,7 @@ function write_biff_ws(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts,
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
if(R === range.s.r) cols[C] = encode_col(C);
|
||||
ref = cols[C] + rr;
|
||||
var cell = dense ? ws[R][C] : ws[ref];
|
||||
var cell = dense ? (ws[R]||[])[C] : ws[ref];
|
||||
if(!cell) continue;
|
||||
/* write cell */
|
||||
write_ws_biff_cell(ba, cell, R, C, opts);
|
||||
|
@ -73,21 +73,29 @@ var HTML_ = (function() {
|
||||
if(RS > 1) sp.rowspan = RS;
|
||||
if(CS > 1) sp.colspan = CS;
|
||||
if(o.editable) sp.contenteditable = "true";
|
||||
sp.id = "sjs-" + coord;
|
||||
oo.push(writextag('td', w, sp));
|
||||
}
|
||||
return "<tr>" + oo.join("") + "</tr>";
|
||||
var preamble = "<tr>";
|
||||
return preamble + oo.join("") + "</tr>";
|
||||
}
|
||||
var _BEGIN = "<html><head><title>SheetJS Table Export</title></head><body><table>";
|
||||
var _END = "</table></body></html>";
|
||||
function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/)/*:string*/ {
|
||||
function make_html_preamble(ws/*:Worksheet*/, R/*:Range*/, o/*:Sheet2HTMLOpts*/)/*:string*/ {
|
||||
var out = [];
|
||||
return out.join("") + '<table>';
|
||||
}
|
||||
var _BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
|
||||
var _END = '</body></html>';
|
||||
function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/, wb/*:?Workbook*/)/*:string*/ {
|
||||
var o = opts || {};
|
||||
var out/*:Array<string>*/ = [];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
var header = o.header != null ? o.header : _BEGIN;
|
||||
var footer = o.footer != null ? o.footer : _END;
|
||||
return header + out.join("") + footer ;
|
||||
var out/*:Array<string>*/ = [header];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
out.push(make_html_preamble(ws, r, o));
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
out.push("</table>" + footer);
|
||||
return out.join("");
|
||||
}
|
||||
|
||||
return {
|
||||
@ -96,6 +104,7 @@ var HTML_ = (function() {
|
||||
_row: make_html_row,
|
||||
BEGIN: _BEGIN,
|
||||
END: _END,
|
||||
_preamble: make_html_preamble,
|
||||
from_sheet: sheet_to_html
|
||||
};
|
||||
})();
|
||||
|
@ -4,7 +4,7 @@ function write_obj_str(factory/*:WriteObjStrFactory*/) {
|
||||
var idx = 0;
|
||||
for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
|
||||
if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o, wb);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,23 +29,25 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
return stream;
|
||||
};
|
||||
|
||||
var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) {
|
||||
var write_html_stream = function(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) {
|
||||
var stream = Readable();
|
||||
|
||||
var o = opts == null ? {} : opts;
|
||||
var r = decode_range(sheet['!ref']), cell/*:Cell*/;
|
||||
o.dense = Array.isArray(sheet);
|
||||
stream.push(HTML_.BEGIN);
|
||||
|
||||
var o = opts || {};
|
||||
var header = o.header != null ? o.header : HTML_.BEGIN;
|
||||
var footer = o.footer != null ? o.footer : HTML_.END;
|
||||
stream.push(header);
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
stream.push(HTML_._preamble(ws, r, o));
|
||||
var R = r.s.r;
|
||||
var end = false;
|
||||
stream._read = function() {
|
||||
if(R > r.e.r) {
|
||||
if(!end) { end = true; stream.push(HTML_.END); }
|
||||
if(!end) { end = true; stream.push("</table>" + footer); }
|
||||
return stream.push(null);
|
||||
}
|
||||
while(R <= r.e.r) {
|
||||
stream.push(HTML_._row(sheet, r, R, o));
|
||||
stream.push(HTML_._row(ws, r, R, o));
|
||||
++R;
|
||||
break;
|
||||
}
|
||||
|
30
dist/xlsx.core.min.js
vendored
30
dist/xlsx.core.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
vendored
2
dist/xlsx.core.min.map
vendored
File diff suppressed because one or more lines are too long
30
dist/xlsx.full.min.js
vendored
30
dist/xlsx.full.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
vendored
2
dist/xlsx.full.min.map
vendored
File diff suppressed because one or more lines are too long
121
dist/xlsx.js
vendored
121
dist/xlsx.js
vendored
@ -6,7 +6,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.10.4';
|
||||
XLSX.version = '0.10.5';
|
||||
var current_codepage = 1200;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -99,7 +99,7 @@ var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/;
|
||||
/*jshint -W041 */
|
||||
var SSF = {};
|
||||
var make_ssf = function make_ssf(SSF){
|
||||
SSF.version = '0.9.3';
|
||||
SSF.version = '0.9.4';
|
||||
function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; }
|
||||
function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; }
|
||||
function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
|
||||
@ -395,7 +395,7 @@ function write_num_f1(r, aval, sign) {
|
||||
function write_num_f2(r, aval, sign) {
|
||||
return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
|
||||
}
|
||||
var dec1 = /^#*0*\.(0+)/;
|
||||
var dec1 = /^#*0*\.([0#]+)/;
|
||||
var closeparen = /\).*[0#]/;
|
||||
var phone = /\(###\) ###\\?-####/;
|
||||
function hashq(str) {
|
||||
@ -442,7 +442,7 @@ function write_num_flt(type, fmt, val) {
|
||||
if((r = fmt.match(frac1))) return write_num_f1(r, aval, sign);
|
||||
if(fmt.match(/^#+0+$/)) return sign + pad0r(aval,fmt.length - fmt.indexOf("0"));
|
||||
if((r = fmt.match(dec1))) {
|
||||
o = rnd(val, r[1].length).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); });
|
||||
o = rnd(val, r[1].length).replace(/^([^\.]+)$/,"$1."+hashq(r[1])).replace(/\.$/,"."+hashq(r[1])).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", hashq(r[1]).length-$1.length); });
|
||||
return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,".");
|
||||
}
|
||||
fmt = fmt.replace(/^#+([0.])/, "$1");
|
||||
@ -558,9 +558,9 @@ function write_num_int(type, fmt, val) {
|
||||
if((r = fmt.match(frac1))) return write_num_f2(r, aval, sign);
|
||||
if(fmt.match(/^#+0+$/)) return sign + pad0(aval,fmt.length - fmt.indexOf("0"));
|
||||
if((r = fmt.match(dec1))) {
|
||||
o = (""+val).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]);
|
||||
o = (""+val).replace(/^([^\.]+)$/,"$1."+hashq(r[1])).replace(/\.$/,"."+hashq(r[1]));
|
||||
o = o.replace(/\.(\d*)$/,function($$, $1) {
|
||||
return "." + $1 + fill("0", r[1].length-$1.length); });
|
||||
return "." + $1 + fill("0", hashq(r[1]).length-$1.length); });
|
||||
return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,".");
|
||||
}
|
||||
fmt = fmt.replace(/^#+([0.])/, "$1");
|
||||
@ -658,9 +658,9 @@ function fmt_is_date(fmt) {
|
||||
case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E':
|
||||
/* falls through */
|
||||
case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true;
|
||||
case 'A':
|
||||
if(fmt.substr(i, 3) === "A/P") return true;
|
||||
if(fmt.substr(i, 5) === "AM/PM") return true;
|
||||
case 'A': case 'a':
|
||||
if(fmt.substr(i, 3).toUpperCase() === "A/P") return true;
|
||||
if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true;
|
||||
++i; break;
|
||||
case '[':
|
||||
o = c;
|
||||
@ -717,11 +717,11 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
if(c === 'm' && lst.toLowerCase() === 'h') c = 'M';
|
||||
if(c === 'h') c = hr;
|
||||
out[out.length] = {t:c, v:o}; lst = c; break;
|
||||
case 'A':
|
||||
q={t:c, v:"A"};
|
||||
case 'A': case 'a':
|
||||
q={t:c, v:c};
|
||||
if(dt==null) dt=parse_date_code(v, opts);
|
||||
if(fmt.substr(i, 3) === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
|
||||
else if(fmt.substr(i,5) === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
|
||||
if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
|
||||
else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
|
||||
else { q.t = "t"; ++i; }
|
||||
if(dt==null && q.t === 'T') return "";
|
||||
out[out.length] = q; lst = c; break;
|
||||
@ -758,7 +758,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
out[out.length] = {t:'D', v:o}; break;
|
||||
case ' ': out[out.length] = {t:c, v:c}; ++i; break;
|
||||
default:
|
||||
if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxz".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt);
|
||||
if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt);
|
||||
out[out.length] = {t:'t', v:c}; ++i; break;
|
||||
}
|
||||
}
|
||||
@ -4433,10 +4433,11 @@ function parse_SupBook(blob, length, opts) {
|
||||
var end = blob.l + length;
|
||||
var ctab = blob.read_shift(2);
|
||||
var cch = blob.read_shift(2);
|
||||
var virtPath;
|
||||
if(cch >=0x01 && cch <=0xff) virtPath = parse_XLUnicodeStringNoCch(blob, cch);
|
||||
var rgst = blob.read_shift(end - blob.l);
|
||||
opts.sbcch = cch;
|
||||
if(cch == 0x0401 || cch == 0x3A01) return [cch, ctab];
|
||||
if(cch < 0x01 || cch >0xff) throw new Error("Unexpected SupBook type: "+cch);
|
||||
var virtPath = parse_XLUnicodeStringNoCch(blob, cch);
|
||||
var rgst = blob.read_shift(end - blob.l);
|
||||
return [cch, ctab, virtPath, rgst];
|
||||
}
|
||||
|
||||
@ -4461,6 +4462,22 @@ function parse_ExternName(blob, length, opts) {
|
||||
}
|
||||
|
||||
/* 2.4.150 TODO */
|
||||
var XLSLblBuiltIn = [
|
||||
"_xlnm.Consolidate_Area",
|
||||
"_xlnm.Auto_Open",
|
||||
"_xlnm.Auto_Close",
|
||||
"_xlnm.Extract",
|
||||
"_xlnm.Database",
|
||||
"_xlnm.Criteria",
|
||||
"_xlnm.Print_Area",
|
||||
"_xlnm.Print_Titles",
|
||||
"_xlnm.Recorder",
|
||||
"_xlnm.Data_Form",
|
||||
"_xlnm.Auto_Activate",
|
||||
"_xlnm.Auto_Deactivate",
|
||||
"_xlnm.Sheet_Title",
|
||||
"_xlnm._FilterDatabase"
|
||||
];
|
||||
function parse_Lbl(blob, length, opts) {
|
||||
var target = blob.l + length;
|
||||
var flags = blob.read_shift(2);
|
||||
@ -4474,6 +4491,7 @@ function parse_Lbl(blob, length, opts) {
|
||||
blob.l += 4;
|
||||
}
|
||||
var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
|
||||
if(flags & 0x20) name = XLSLblBuiltIn[name.charCodeAt(0)];
|
||||
var npflen = target - blob.l; if(opts && opts.biff == 2) --npflen;
|
||||
var rgce = target == blob.l || cce == 0 ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
|
||||
return {
|
||||
@ -6706,8 +6724,8 @@ function char2width_(chr) { return (((chr * MDW + 5)/MDW*256))/256; }
|
||||
function cycle_width(collw) { return char2width(px2char(width2px(collw))); }
|
||||
/* XLSX/XLSB/XLS specify width in units of MDW */
|
||||
function find_mdw_colw(collw) {
|
||||
var delta = Infinity, _MDW = MIN_MDW;
|
||||
for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
|
||||
var delta = Math.abs(collw - cycle_width(collw)), _MDW = MDW;
|
||||
if(delta > 0.005) for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
|
||||
MDW = _MDW;
|
||||
}
|
||||
/* XLML specifies width in terms of pixels */
|
||||
@ -7024,11 +7042,13 @@ function write_numFmts(NF, opts) {
|
||||
}
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs */
|
||||
var cellXF_uint = [ "numFmtId", "fillId", "fontId", "borderId", "xfId" ];
|
||||
var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "applyNumberFormat", "applyProtection", "pivotButton", "quotePrefix" ];
|
||||
function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
var xf;
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
var y = parsexmltag(x), i = 0;
|
||||
switch(y[0]) {
|
||||
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
|
||||
|
||||
@ -7036,8 +7056,10 @@ function parse_cellXfs(t, styles, opts) {
|
||||
case '<xf':
|
||||
xf = y;
|
||||
delete xf[0];
|
||||
if(xf.numFmtId) xf.numFmtId = parseInt(xf.numFmtId, 10);
|
||||
if(xf.fillId) xf.fillId = parseInt(xf.fillId, 10);
|
||||
for(i = 0; i < cellXF_uint.length; ++i) if(xf[cellXF_uint[i]])
|
||||
xf[cellXF_uint[i]] = parseInt(xf[cellXF_uint[i]], 10);
|
||||
for(i = 0; i < cellXF_bool.length; ++i) if(xf[cellXF_bool[i]])
|
||||
xf[cellXF_bool[i]] = parsexmlbool(xf[cellXF_bool[i]], "");
|
||||
styles.CellXf.push(xf); break;
|
||||
case '</xf>': break;
|
||||
|
||||
@ -10639,7 +10661,7 @@ function parse_ws_xml(data, opts, rels, wb, themes, styles) {
|
||||
var refguess = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} });
|
||||
|
||||
var data1 = "", data2 = "";
|
||||
var mtch =data.match(sheetdataregex);
|
||||
var mtch = data.match(sheetdataregex);
|
||||
if(mtch) {
|
||||
data1 = data.substr(0, mtch.index);
|
||||
data2 = data.substr(mtch.index + mtch[0].length);
|
||||
@ -13051,7 +13073,7 @@ for(var cma = c; cma <= cc; ++cma) {
|
||||
row = xlml_parsexmltag(Rn[0]);
|
||||
if(row.Index) r = +row.Index - 1;
|
||||
rowobj = {};
|
||||
if(row.AutoFitHeight == "0") {
|
||||
if(row.AutoFitHeight == "0" || row.Height) {
|
||||
rowobj.hpx = parseInt(row.Height, 10); rowobj.hpt = px2pt(rowobj.hpx);
|
||||
rowinfo[r] = rowobj;
|
||||
}
|
||||
@ -14149,7 +14171,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
||||
supbooks.names.push(last_lbl);
|
||||
if(!supbooks[0]) supbooks[0] = [];
|
||||
supbooks[supbooks.length-1].push(val);
|
||||
if(val.Name == "\r" && val.itab > 0)
|
||||
if(val.Name == "_xlnm._FilterDatabase" && val.itab > 0)
|
||||
if(val.rgce && val.rgce[0] && val.rgce[0][0] && val.rgce[0][0][0] == 'PtgArea3d')
|
||||
FilterDatabases[val.itab - 1] = { ref: encode_range(val.rgce[0][0][1][2]) };
|
||||
break;
|
||||
@ -16047,7 +16069,7 @@ function write_biff_ws(ba, ws, idx, opts, wb) {
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
if(R === range.s.r) cols[C] = encode_col(C);
|
||||
ref = cols[C] + rr;
|
||||
var cell = dense ? ws[R][C] : ws[ref];
|
||||
var cell = dense ? (ws[R]||[])[C] : ws[ref];
|
||||
if(!cell) continue;
|
||||
/* write cell */
|
||||
write_ws_biff_cell(ba, cell, R, C, opts);
|
||||
@ -16146,21 +16168,29 @@ var HTML_ = (function() {
|
||||
if(RS > 1) sp.rowspan = RS;
|
||||
if(CS > 1) sp.colspan = CS;
|
||||
if(o.editable) sp.contenteditable = "true";
|
||||
sp.id = "sjs-" + coord;
|
||||
oo.push(writextag('td', w, sp));
|
||||
}
|
||||
return "<tr>" + oo.join("") + "</tr>";
|
||||
var preamble = "<tr>";
|
||||
return preamble + oo.join("") + "</tr>";
|
||||
}
|
||||
var _BEGIN = "<html><head><title>SheetJS Table Export</title></head><body><table>";
|
||||
var _END = "</table></body></html>";
|
||||
function sheet_to_html(ws, opts) {
|
||||
var o = opts || {};
|
||||
function make_html_preamble(ws, R, o) {
|
||||
var out = [];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
return out.join("") + '<table>';
|
||||
}
|
||||
var _BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
|
||||
var _END = '</body></html>';
|
||||
function sheet_to_html(ws, opts, wb) {
|
||||
var o = opts || {};
|
||||
var header = o.header != null ? o.header : _BEGIN;
|
||||
var footer = o.footer != null ? o.footer : _END;
|
||||
return header + out.join("") + footer ;
|
||||
var out = [header];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
out.push(make_html_preamble(ws, r, o));
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
out.push("</table>" + footer);
|
||||
return out.join("");
|
||||
}
|
||||
|
||||
return {
|
||||
@ -16169,6 +16199,7 @@ var HTML_ = (function() {
|
||||
_row: make_html_row,
|
||||
BEGIN: _BEGIN,
|
||||
END: _END,
|
||||
_preamble: make_html_preamble,
|
||||
from_sheet: sheet_to_html
|
||||
};
|
||||
})();
|
||||
@ -16871,7 +16902,7 @@ function write_obj_str(factory) {
|
||||
var idx = 0;
|
||||
for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
|
||||
if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o, wb);
|
||||
};
|
||||
}
|
||||
|
||||
@ -17808,23 +17839,25 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
return stream;
|
||||
};
|
||||
|
||||
var write_html_stream = function(sheet, opts) {
|
||||
var write_html_stream = function(ws, opts) {
|
||||
var stream = Readable();
|
||||
|
||||
var o = opts == null ? {} : opts;
|
||||
var r = decode_range(sheet['!ref']), cell;
|
||||
o.dense = Array.isArray(sheet);
|
||||
stream.push(HTML_.BEGIN);
|
||||
|
||||
var o = opts || {};
|
||||
var header = o.header != null ? o.header : HTML_.BEGIN;
|
||||
var footer = o.footer != null ? o.footer : HTML_.END;
|
||||
stream.push(header);
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
stream.push(HTML_._preamble(ws, r, o));
|
||||
var R = r.s.r;
|
||||
var end = false;
|
||||
stream._read = function() {
|
||||
if(R > r.e.r) {
|
||||
if(!end) { end = true; stream.push(HTML_.END); }
|
||||
if(!end) { end = true; stream.push("</table>" + footer); }
|
||||
return stream.push(null);
|
||||
}
|
||||
while(R <= r.e.r) {
|
||||
stream.push(HTML_._row(sheet, r, R, o));
|
||||
stream.push(HTML_._row(ws, r, R, o));
|
||||
++R;
|
||||
break;
|
||||
}
|
||||
|
28
dist/xlsx.min.js
vendored
28
dist/xlsx.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
vendored
2
dist/xlsx.min.map
vendored
File diff suppressed because one or more lines are too long
@ -1,4 +1,7 @@
|
||||
### Note on Streaming Read
|
||||
### Streaming Read
|
||||
|
||||
<details>
|
||||
<summary><b>Why is there no Streaming Read API?</b> (click to show)</summary>
|
||||
|
||||
The most common and interesting formats (XLS, XLSX/M, XLSB, ODS) are ultimately
|
||||
ZIP or CFB containers of files. Neither format puts the directory structure at
|
||||
@ -6,7 +9,59 @@ the beginning of the file: ZIP files place the Central Directory records at the
|
||||
end of the logical file, while CFB files can place the FAT structure anywhere in
|
||||
the file! As a result, to properly handle these formats, a streaming function
|
||||
would have to buffer the entire file before commencing. That belies the
|
||||
expectations of streaming, so we do not provide any streaming read API. If you
|
||||
really want to stream, there are node modules like `concat-stream` that will do
|
||||
the buffering for you.
|
||||
expectations of streaming, so we do not provide any streaming read API.
|
||||
|
||||
</details>
|
||||
|
||||
When dealing with Readable Streams, the easiest approach is to buffer the stream
|
||||
and process the whole thing at the end. This can be done with a temporary file
|
||||
or by explicitly concatenating the stream:
|
||||
|
||||
<details>
|
||||
<summary><b>Explicitly concatenating streams</b> (click to show)</summary>
|
||||
|
||||
```js
|
||||
var fs = require('fs');
|
||||
var XLSX = require('xlsx');
|
||||
function process_RS(stream/*:ReadStream*/, cb/*:(wb:Workbook)=>void*/)/*:void*/{
|
||||
var buffers = [];
|
||||
stream.on('data', function(data) { buffers.push(data); });
|
||||
stream.on('end', function() {
|
||||
var buffer = Buffer.concat(buffers);
|
||||
var workbook = XLSX.read(buffer, {type:"buffer"});
|
||||
|
||||
/* DO SOMETHING WITH workbook IN THE CALLBACK */
|
||||
cb(workbook);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
More robust solutions are available using modules like `concat-stream`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Writing to filesystem first</b> (click to show)</summary>
|
||||
|
||||
This example uses [`tempfile`](https://npm.im/tempfile) for filenames:
|
||||
|
||||
```js
|
||||
var fs = require('fs'), tempfile = require('tempfile');
|
||||
var XLSX = require('xlsx');
|
||||
function process_RS(stream/*:ReadStream*/, cb/*:(wb:Workbook)=>void*/)/*:void*/{
|
||||
var fname = tempfile('.sheetjs');
|
||||
console.log(fname);
|
||||
var ostream = fs.createWriteStream(fname);
|
||||
stream.pipe(ostream);
|
||||
ostream.on('finish', function() {
|
||||
var workbook = XLSX.readFile(fname);
|
||||
fs.unlinkSync(fname);
|
||||
|
||||
/* DO SOMETHING WITH workbook IN THE CALLBACK */
|
||||
cb(workbook);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
### Streaming Write
|
||||
|
||||
The streaming write functions are available in the `XLSX.stream` object. They
|
||||
take the same arguments as the normal write functions but return a readable
|
||||
stream. They are only exposed in node.
|
||||
take the same arguments as the normal write functions but return a Readable
|
||||
Stream. They are only exposed in NodeJS.
|
||||
|
||||
- `XLSX.stream.to_csv` is the streaming version of `XLSX.utils.sheet_to_csv`.
|
||||
- `XLSX.stream.to_html` is the streaming version of `XLSX.utils.sheet_to_html`.
|
||||
|
@ -8,7 +8,7 @@
|
||||
- [Philosophy](README.md#philosophy)
|
||||
- [Parsing Workbooks](README.md#parsing-workbooks)
|
||||
* [Complete Examples](README.md#complete-examples)
|
||||
* [Note on Streaming Read](README.md#note-on-streaming-read)
|
||||
* [Streaming Read](README.md#streaming-read)
|
||||
- [Working with the Workbook](README.md#working-with-the-workbook)
|
||||
* [Complete Examples](README.md#complete-examples-1)
|
||||
- [Writing Workbooks](README.md#writing-workbooks)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.10.4",
|
||||
"version": "0.10.5",
|
||||
"author": "sheetjs",
|
||||
"description": "Excel (XLSB/XLSX/XLS/XML) ODS and other spreadsheet format (CSV/DIF/DBF/SYLK) parser and writer",
|
||||
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "csv", "dbf", "dif", "sylk", "office", "spreadsheet" ],
|
||||
|
4
types/index.d.ts
vendored
4
types/index.d.ts
vendored
@ -13,7 +13,7 @@ export function writeFile(data: WorkBook, filename: string, opts?: WritingOption
|
||||
/** Attempts to write the workbook data */
|
||||
export function write(data: WorkBook, opts?: WritingOptions): any;
|
||||
|
||||
export const utils: Utils;
|
||||
export const utils: XLSX$Utils;
|
||||
export const stream: StreamUtils;
|
||||
|
||||
/** Number Format (either a string or an index to the format table) */
|
||||
@ -571,7 +571,7 @@ export interface Table2SheetOpts {
|
||||
/**
|
||||
* General utilities
|
||||
*/
|
||||
export interface Utils {
|
||||
export interface XLSX$Utils {
|
||||
/* --- Import Functions --- */
|
||||
|
||||
/** Converts an array of arrays of JS data to a worksheet. */
|
||||
|
97
xlsx.flow.js
97
xlsx.flow.js
@ -6,7 +6,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.10.4';
|
||||
XLSX.version = '0.10.5';
|
||||
var current_codepage = 1200;
|
||||
/*:: declare var cptable:any; */
|
||||
/*global cptable:true */
|
||||
@ -113,7 +113,7 @@ type EvertArrType = {[string]:Array<string>};
|
||||
|
||||
type StringConv = {(string):string};
|
||||
|
||||
type WriteObjStrFactory = {from_sheet(ws:Worksheet, o:any):string};
|
||||
type WriteObjStrFactory = {from_sheet(ws:Worksheet, o:any, wb:?Workbook):string};
|
||||
*/
|
||||
/* ssf.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint -W041 */
|
||||
@ -4495,10 +4495,11 @@ function parse_SupBook(blob, length, opts) {
|
||||
var end = blob.l + length;
|
||||
var ctab = blob.read_shift(2);
|
||||
var cch = blob.read_shift(2);
|
||||
var virtPath;
|
||||
if(cch >=0x01 && cch <=0xff) virtPath = parse_XLUnicodeStringNoCch(blob, cch);
|
||||
var rgst = blob.read_shift(end - blob.l);
|
||||
opts.sbcch = cch;
|
||||
if(cch == 0x0401 || cch == 0x3A01) return [cch, ctab];
|
||||
if(cch < 0x01 || cch >0xff) throw new Error("Unexpected SupBook type: "+cch);
|
||||
var virtPath = parse_XLUnicodeStringNoCch(blob, cch);
|
||||
var rgst = blob.read_shift(end - blob.l);
|
||||
return [cch, ctab, virtPath, rgst];
|
||||
}
|
||||
|
||||
@ -4523,6 +4524,22 @@ function parse_ExternName(blob, length, opts) {
|
||||
}
|
||||
|
||||
/* 2.4.150 TODO */
|
||||
var XLSLblBuiltIn = [
|
||||
"_xlnm.Consolidate_Area",
|
||||
"_xlnm.Auto_Open",
|
||||
"_xlnm.Auto_Close",
|
||||
"_xlnm.Extract",
|
||||
"_xlnm.Database",
|
||||
"_xlnm.Criteria",
|
||||
"_xlnm.Print_Area",
|
||||
"_xlnm.Print_Titles",
|
||||
"_xlnm.Recorder",
|
||||
"_xlnm.Data_Form",
|
||||
"_xlnm.Auto_Activate",
|
||||
"_xlnm.Auto_Deactivate",
|
||||
"_xlnm.Sheet_Title",
|
||||
"_xlnm._FilterDatabase"
|
||||
];
|
||||
function parse_Lbl(blob, length, opts) {
|
||||
var target = blob.l + length;
|
||||
var flags = blob.read_shift(2);
|
||||
@ -4536,6 +4553,7 @@ function parse_Lbl(blob, length, opts) {
|
||||
blob.l += 4;
|
||||
}
|
||||
var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
|
||||
if(flags & 0x20) name = XLSLblBuiltIn[name.charCodeAt(0)];
|
||||
var npflen = target - blob.l; if(opts && opts.biff == 2) --npflen;
|
||||
var rgce = target == blob.l || cce == 0 ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
|
||||
return {
|
||||
@ -6769,8 +6787,8 @@ function char2width_(chr) { return (((chr * MDW + 5)/MDW*256))/256; }
|
||||
function cycle_width(collw) { return char2width(px2char(width2px(collw))); }
|
||||
/* XLSX/XLSB/XLS specify width in units of MDW */
|
||||
function find_mdw_colw(collw) {
|
||||
var delta = Infinity, _MDW = MIN_MDW;
|
||||
for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
|
||||
var delta = Math.abs(collw - cycle_width(collw)), _MDW = MDW;
|
||||
if(delta > 0.005) for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
|
||||
MDW = _MDW;
|
||||
}
|
||||
/* XLML specifies width in terms of pixels */
|
||||
@ -7087,11 +7105,13 @@ function write_numFmts(NF/*:{[n:number]:string}*/, opts) {
|
||||
}
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs */
|
||||
var cellXF_uint = [ "numFmtId", "fillId", "fontId", "borderId", "xfId" ];
|
||||
var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "applyNumberFormat", "applyProtection", "pivotButton", "quotePrefix" ];
|
||||
function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
var xf;
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
var y = parsexmltag(x), i = 0;
|
||||
switch(y[0]) {
|
||||
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
|
||||
|
||||
@ -7099,8 +7119,10 @@ function parse_cellXfs(t, styles, opts) {
|
||||
case '<xf':
|
||||
xf = y;
|
||||
delete xf[0];
|
||||
if(xf.numFmtId) xf.numFmtId = parseInt(xf.numFmtId, 10);
|
||||
if(xf.fillId) xf.fillId = parseInt(xf.fillId, 10);
|
||||
for(i = 0; i < cellXF_uint.length; ++i) if(xf[cellXF_uint[i]])
|
||||
xf[cellXF_uint[i]] = parseInt(xf[cellXF_uint[i]], 10);
|
||||
for(i = 0; i < cellXF_bool.length; ++i) if(xf[cellXF_bool[i]])
|
||||
xf[cellXF_bool[i]] = parsexmlbool(xf[cellXF_bool[i]], "");
|
||||
styles.CellXf.push(xf); break;
|
||||
case '</xf>': break;
|
||||
|
||||
@ -10705,7 +10727,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksh
|
||||
var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/);
|
||||
|
||||
var data1 = "", data2 = "";
|
||||
var mtch/*:?any*/ =data.match(sheetdataregex);
|
||||
var mtch/*:?any*/ = data.match(sheetdataregex);
|
||||
if(mtch) {
|
||||
data1 = data.substr(0, mtch.index);
|
||||
data2 = data.substr(mtch.index + mtch[0].length);
|
||||
@ -13122,7 +13144,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
||||
row = xlml_parsexmltag(Rn[0]);
|
||||
if(row.Index) r = +row.Index - 1;
|
||||
rowobj = {};
|
||||
if(row.AutoFitHeight == "0") {
|
||||
if(row.AutoFitHeight == "0" || row.Height) {
|
||||
rowobj.hpx = parseInt(row.Height, 10); rowobj.hpt = px2pt(rowobj.hpx);
|
||||
rowinfo[r] = rowobj;
|
||||
}
|
||||
@ -14223,7 +14245,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
supbooks.names.push(last_lbl);
|
||||
if(!supbooks[0]) supbooks[0] = [];
|
||||
supbooks[supbooks.length-1].push(val);
|
||||
if(val.Name == "\r" && val.itab > 0)
|
||||
if(val.Name == "_xlnm._FilterDatabase" && val.itab > 0)
|
||||
if(val.rgce && val.rgce[0] && val.rgce[0][0] && val.rgce[0][0][0] == 'PtgArea3d')
|
||||
FilterDatabases[val.itab - 1] = { ref: encode_range(val.rgce[0][0][1][2]) };
|
||||
break;
|
||||
@ -16121,7 +16143,7 @@ function write_biff_ws(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts,
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
if(R === range.s.r) cols[C] = encode_col(C);
|
||||
ref = cols[C] + rr;
|
||||
var cell = dense ? ws[R][C] : ws[ref];
|
||||
var cell = dense ? (ws[R]||[])[C] : ws[ref];
|
||||
if(!cell) continue;
|
||||
/* write cell */
|
||||
write_ws_biff_cell(ba, cell, R, C, opts);
|
||||
@ -16220,21 +16242,29 @@ var HTML_ = (function() {
|
||||
if(RS > 1) sp.rowspan = RS;
|
||||
if(CS > 1) sp.colspan = CS;
|
||||
if(o.editable) sp.contenteditable = "true";
|
||||
sp.id = "sjs-" + coord;
|
||||
oo.push(writextag('td', w, sp));
|
||||
}
|
||||
return "<tr>" + oo.join("") + "</tr>";
|
||||
var preamble = "<tr>";
|
||||
return preamble + oo.join("") + "</tr>";
|
||||
}
|
||||
var _BEGIN = "<html><head><title>SheetJS Table Export</title></head><body><table>";
|
||||
var _END = "</table></body></html>";
|
||||
function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/)/*:string*/ {
|
||||
function make_html_preamble(ws/*:Worksheet*/, R/*:Range*/, o/*:Sheet2HTMLOpts*/)/*:string*/ {
|
||||
var out = [];
|
||||
return out.join("") + '<table>';
|
||||
}
|
||||
var _BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
|
||||
var _END = '</body></html>';
|
||||
function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/, wb/*:?Workbook*/)/*:string*/ {
|
||||
var o = opts || {};
|
||||
var out/*:Array<string>*/ = [];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
var header = o.header != null ? o.header : _BEGIN;
|
||||
var footer = o.footer != null ? o.footer : _END;
|
||||
return header + out.join("") + footer ;
|
||||
var out/*:Array<string>*/ = [header];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
out.push(make_html_preamble(ws, r, o));
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
out.push("</table>" + footer);
|
||||
return out.join("");
|
||||
}
|
||||
|
||||
return {
|
||||
@ -16243,6 +16273,7 @@ var HTML_ = (function() {
|
||||
_row: make_html_row,
|
||||
BEGIN: _BEGIN,
|
||||
END: _END,
|
||||
_preamble: make_html_preamble,
|
||||
from_sheet: sheet_to_html
|
||||
};
|
||||
})();
|
||||
@ -16946,7 +16977,7 @@ function write_obj_str(factory/*:WriteObjStrFactory*/) {
|
||||
var idx = 0;
|
||||
for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
|
||||
if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o, wb);
|
||||
};
|
||||
}
|
||||
|
||||
@ -17886,23 +17917,25 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
return stream;
|
||||
};
|
||||
|
||||
var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) {
|
||||
var write_html_stream = function(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) {
|
||||
var stream = Readable();
|
||||
|
||||
var o = opts == null ? {} : opts;
|
||||
var r = decode_range(sheet['!ref']), cell/*:Cell*/;
|
||||
o.dense = Array.isArray(sheet);
|
||||
stream.push(HTML_.BEGIN);
|
||||
|
||||
var o = opts || {};
|
||||
var header = o.header != null ? o.header : HTML_.BEGIN;
|
||||
var footer = o.footer != null ? o.footer : HTML_.END;
|
||||
stream.push(header);
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
stream.push(HTML_._preamble(ws, r, o));
|
||||
var R = r.s.r;
|
||||
var end = false;
|
||||
stream._read = function() {
|
||||
if(R > r.e.r) {
|
||||
if(!end) { end = true; stream.push(HTML_.END); }
|
||||
if(!end) { end = true; stream.push("</table>" + footer); }
|
||||
return stream.push(null);
|
||||
}
|
||||
while(R <= r.e.r) {
|
||||
stream.push(HTML_._row(sheet, r, R, o));
|
||||
stream.push(HTML_._row(ws, r, R, o));
|
||||
++R;
|
||||
break;
|
||||
}
|
||||
|
95
xlsx.js
95
xlsx.js
@ -6,7 +6,7 @@
|
||||
/*global global, exports, module, require:false, process:false, Buffer:false */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.10.4';
|
||||
XLSX.version = '0.10.5';
|
||||
var current_codepage = 1200;
|
||||
/*global cptable:true */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -4433,10 +4433,11 @@ function parse_SupBook(blob, length, opts) {
|
||||
var end = blob.l + length;
|
||||
var ctab = blob.read_shift(2);
|
||||
var cch = blob.read_shift(2);
|
||||
var virtPath;
|
||||
if(cch >=0x01 && cch <=0xff) virtPath = parse_XLUnicodeStringNoCch(blob, cch);
|
||||
var rgst = blob.read_shift(end - blob.l);
|
||||
opts.sbcch = cch;
|
||||
if(cch == 0x0401 || cch == 0x3A01) return [cch, ctab];
|
||||
if(cch < 0x01 || cch >0xff) throw new Error("Unexpected SupBook type: "+cch);
|
||||
var virtPath = parse_XLUnicodeStringNoCch(blob, cch);
|
||||
var rgst = blob.read_shift(end - blob.l);
|
||||
return [cch, ctab, virtPath, rgst];
|
||||
}
|
||||
|
||||
@ -4461,6 +4462,22 @@ function parse_ExternName(blob, length, opts) {
|
||||
}
|
||||
|
||||
/* 2.4.150 TODO */
|
||||
var XLSLblBuiltIn = [
|
||||
"_xlnm.Consolidate_Area",
|
||||
"_xlnm.Auto_Open",
|
||||
"_xlnm.Auto_Close",
|
||||
"_xlnm.Extract",
|
||||
"_xlnm.Database",
|
||||
"_xlnm.Criteria",
|
||||
"_xlnm.Print_Area",
|
||||
"_xlnm.Print_Titles",
|
||||
"_xlnm.Recorder",
|
||||
"_xlnm.Data_Form",
|
||||
"_xlnm.Auto_Activate",
|
||||
"_xlnm.Auto_Deactivate",
|
||||
"_xlnm.Sheet_Title",
|
||||
"_xlnm._FilterDatabase"
|
||||
];
|
||||
function parse_Lbl(blob, length, opts) {
|
||||
var target = blob.l + length;
|
||||
var flags = blob.read_shift(2);
|
||||
@ -4474,6 +4491,7 @@ function parse_Lbl(blob, length, opts) {
|
||||
blob.l += 4;
|
||||
}
|
||||
var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
|
||||
if(flags & 0x20) name = XLSLblBuiltIn[name.charCodeAt(0)];
|
||||
var npflen = target - blob.l; if(opts && opts.biff == 2) --npflen;
|
||||
var rgce = target == blob.l || cce == 0 ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
|
||||
return {
|
||||
@ -6706,8 +6724,8 @@ function char2width_(chr) { return (((chr * MDW + 5)/MDW*256))/256; }
|
||||
function cycle_width(collw) { return char2width(px2char(width2px(collw))); }
|
||||
/* XLSX/XLSB/XLS specify width in units of MDW */
|
||||
function find_mdw_colw(collw) {
|
||||
var delta = Infinity, _MDW = MIN_MDW;
|
||||
for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
|
||||
var delta = Math.abs(collw - cycle_width(collw)), _MDW = MDW;
|
||||
if(delta > 0.005) for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
|
||||
MDW = _MDW;
|
||||
}
|
||||
/* XLML specifies width in terms of pixels */
|
||||
@ -7024,11 +7042,13 @@ function write_numFmts(NF, opts) {
|
||||
}
|
||||
|
||||
/* 18.8.10 cellXfs CT_CellXfs */
|
||||
var cellXF_uint = [ "numFmtId", "fillId", "fontId", "borderId", "xfId" ];
|
||||
var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "applyNumberFormat", "applyProtection", "pivotButton", "quotePrefix" ];
|
||||
function parse_cellXfs(t, styles, opts) {
|
||||
styles.CellXf = [];
|
||||
var xf;
|
||||
t[0].match(tagregex).forEach(function(x) {
|
||||
var y = parsexmltag(x);
|
||||
var y = parsexmltag(x), i = 0;
|
||||
switch(y[0]) {
|
||||
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
|
||||
|
||||
@ -7036,8 +7056,10 @@ function parse_cellXfs(t, styles, opts) {
|
||||
case '<xf':
|
||||
xf = y;
|
||||
delete xf[0];
|
||||
if(xf.numFmtId) xf.numFmtId = parseInt(xf.numFmtId, 10);
|
||||
if(xf.fillId) xf.fillId = parseInt(xf.fillId, 10);
|
||||
for(i = 0; i < cellXF_uint.length; ++i) if(xf[cellXF_uint[i]])
|
||||
xf[cellXF_uint[i]] = parseInt(xf[cellXF_uint[i]], 10);
|
||||
for(i = 0; i < cellXF_bool.length; ++i) if(xf[cellXF_bool[i]])
|
||||
xf[cellXF_bool[i]] = parsexmlbool(xf[cellXF_bool[i]], "");
|
||||
styles.CellXf.push(xf); break;
|
||||
case '</xf>': break;
|
||||
|
||||
@ -10639,7 +10661,7 @@ function parse_ws_xml(data, opts, rels, wb, themes, styles) {
|
||||
var refguess = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} });
|
||||
|
||||
var data1 = "", data2 = "";
|
||||
var mtch =data.match(sheetdataregex);
|
||||
var mtch = data.match(sheetdataregex);
|
||||
if(mtch) {
|
||||
data1 = data.substr(0, mtch.index);
|
||||
data2 = data.substr(mtch.index + mtch[0].length);
|
||||
@ -13051,7 +13073,7 @@ for(var cma = c; cma <= cc; ++cma) {
|
||||
row = xlml_parsexmltag(Rn[0]);
|
||||
if(row.Index) r = +row.Index - 1;
|
||||
rowobj = {};
|
||||
if(row.AutoFitHeight == "0") {
|
||||
if(row.AutoFitHeight == "0" || row.Height) {
|
||||
rowobj.hpx = parseInt(row.Height, 10); rowobj.hpt = px2pt(rowobj.hpx);
|
||||
rowinfo[r] = rowobj;
|
||||
}
|
||||
@ -14149,7 +14171,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
|
||||
supbooks.names.push(last_lbl);
|
||||
if(!supbooks[0]) supbooks[0] = [];
|
||||
supbooks[supbooks.length-1].push(val);
|
||||
if(val.Name == "\r" && val.itab > 0)
|
||||
if(val.Name == "_xlnm._FilterDatabase" && val.itab > 0)
|
||||
if(val.rgce && val.rgce[0] && val.rgce[0][0] && val.rgce[0][0][0] == 'PtgArea3d')
|
||||
FilterDatabases[val.itab - 1] = { ref: encode_range(val.rgce[0][0][1][2]) };
|
||||
break;
|
||||
@ -16047,7 +16069,7 @@ function write_biff_ws(ba, ws, idx, opts, wb) {
|
||||
for(var C = range.s.c; C <= range.e.c; ++C) {
|
||||
if(R === range.s.r) cols[C] = encode_col(C);
|
||||
ref = cols[C] + rr;
|
||||
var cell = dense ? ws[R][C] : ws[ref];
|
||||
var cell = dense ? (ws[R]||[])[C] : ws[ref];
|
||||
if(!cell) continue;
|
||||
/* write cell */
|
||||
write_ws_biff_cell(ba, cell, R, C, opts);
|
||||
@ -16146,21 +16168,29 @@ var HTML_ = (function() {
|
||||
if(RS > 1) sp.rowspan = RS;
|
||||
if(CS > 1) sp.colspan = CS;
|
||||
if(o.editable) sp.contenteditable = "true";
|
||||
sp.id = "sjs-" + coord;
|
||||
oo.push(writextag('td', w, sp));
|
||||
}
|
||||
return "<tr>" + oo.join("") + "</tr>";
|
||||
var preamble = "<tr>";
|
||||
return preamble + oo.join("") + "</tr>";
|
||||
}
|
||||
var _BEGIN = "<html><head><title>SheetJS Table Export</title></head><body><table>";
|
||||
var _END = "</table></body></html>";
|
||||
function sheet_to_html(ws, opts) {
|
||||
var o = opts || {};
|
||||
function make_html_preamble(ws, R, o) {
|
||||
var out = [];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
return out.join("") + '<table>';
|
||||
}
|
||||
var _BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
|
||||
var _END = '</body></html>';
|
||||
function sheet_to_html(ws, opts, wb) {
|
||||
var o = opts || {};
|
||||
var header = o.header != null ? o.header : _BEGIN;
|
||||
var footer = o.footer != null ? o.footer : _END;
|
||||
return header + out.join("") + footer ;
|
||||
var out = [header];
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
out.push(make_html_preamble(ws, r, o));
|
||||
for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
|
||||
out.push("</table>" + footer);
|
||||
return out.join("");
|
||||
}
|
||||
|
||||
return {
|
||||
@ -16169,6 +16199,7 @@ var HTML_ = (function() {
|
||||
_row: make_html_row,
|
||||
BEGIN: _BEGIN,
|
||||
END: _END,
|
||||
_preamble: make_html_preamble,
|
||||
from_sheet: sheet_to_html
|
||||
};
|
||||
})();
|
||||
@ -16871,7 +16902,7 @@ function write_obj_str(factory) {
|
||||
var idx = 0;
|
||||
for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
|
||||
if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o);
|
||||
return factory.from_sheet(wb.Sheets[wb.SheetNames[idx]], o, wb);
|
||||
};
|
||||
}
|
||||
|
||||
@ -17808,23 +17839,25 @@ if(has_buf && typeof require != 'undefined') (function() {
|
||||
return stream;
|
||||
};
|
||||
|
||||
var write_html_stream = function(sheet, opts) {
|
||||
var write_html_stream = function(ws, opts) {
|
||||
var stream = Readable();
|
||||
|
||||
var o = opts == null ? {} : opts;
|
||||
var r = decode_range(sheet['!ref']), cell;
|
||||
o.dense = Array.isArray(sheet);
|
||||
stream.push(HTML_.BEGIN);
|
||||
|
||||
var o = opts || {};
|
||||
var header = o.header != null ? o.header : HTML_.BEGIN;
|
||||
var footer = o.footer != null ? o.footer : HTML_.END;
|
||||
stream.push(header);
|
||||
var r = decode_range(ws['!ref']);
|
||||
o.dense = Array.isArray(ws);
|
||||
stream.push(HTML_._preamble(ws, r, o));
|
||||
var R = r.s.r;
|
||||
var end = false;
|
||||
stream._read = function() {
|
||||
if(R > r.e.r) {
|
||||
if(!end) { end = true; stream.push(HTML_.END); }
|
||||
if(!end) { end = true; stream.push("</table>" + footer); }
|
||||
return stream.push(null);
|
||||
}
|
||||
while(R <= r.e.r) {
|
||||
stream.push(HTML_._row(sheet, r, R, o));
|
||||
stream.push(HTML_._row(ws, r, R, o));
|
||||
++R;
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user