Permalink
Browse files

version bump 0.6.6: updates

- updated SSF to 0.5.6
- updated CSV output (h/t @vratiu)
- some cell types now include .w formatted text
  • Loading branch information...
1 parent d453e12 commit 6a8df59fb81beea14dad6519126fe9dc1ad10dc0 @SheetJSDev SheetJSDev committed Feb 11, 2014
Showing with 134 additions and 29 deletions.
  1. +61 −0 CONTRIBUTING.md
  2. +26 −14 README.md
  3. +1 −1 bits/01_version.js
  4. +12 −5 bits/10_ssf.js
  5. +9 −0 bits/80_xls.js
  6. +2 −2 package.json
  7. +1 −1 test_files
  8. +22 −6 xls.js
View
@@ -0,0 +1,61 @@
+# Contributing
+
+The SheetJS Libraries should be free and clear to use in your projects. In
+order to maintain that, every contributor must be vigilant.
+
+There have been many projects in the past that have been very lax regarding
+licensing, and we are of the opinion that those are ticking timebombs and that
+no corporate product should depend on them.
+
+
+# Required Reading
+
+These are pretty short reads and emphasize the importance of proper licensing:
+
+- https://github.com/kennethreitz/tablib/issues/114 (discussion of other tools)
+
+- http://www.codinghorror.com/blog/2007/04/pick-a-license-any-license.html
+
+
+# Raising Issues
+
+Issues should generally be accompanied by test files. Since github does not
+support attachments, the best method is to send files to <sheetjs@gmail.com>
+(subject line should contain issue number or message) or to share using some
+storage service. Unless expressly permitted, any attachments will not be
+shared or included in a test suite (although I will ask :)
+
+# Pre-Contribution Checklist
+
+Before thinking about contributing, make sure that:
+
+- You are not, nor have ever been, an employee of Microsoft Corporation.
+
+- You have not signed any NDAs or Shared Source Agreements with Microsoft
+ Corporation or a subsidiary
+
+- You have not consulted any existing relevant codebase (if you have, please
+take note of which codebases were consulted).
+
+If you cannot attest to each of these items, the best approach is to raise an
+issue. If it is a particularly high-priority issue, please drop an email to
+<sheetjs@gmail.com> and it will be prioritized.
+
+
+# Intra-Contribution
+
+Keep these in mind as you work:
+
+- Your contributions are your original work. Take note of any resources you
+ consult in the process (and be extra careful not to use unlicensed code on
+ the internet.
+
+- You are working on your own time. Unless they explicitly grant permission,
+ your employer may be the ultimate owner of your IP
+
+
+# Post-Contribution
+
+Before contributions are merged, you will receive an email (at the address
+associated with the git commit) and will be asked to confirm the aforementioned
+items.
View
@@ -14,41 +14,48 @@ In the browser:
## Usage
-The node version installs a binary `xls2csv` which can read XLS files and output the contents in various formats. The source is available at `xls2csv.njs` in the bin directory.
-
-See <http://oss.sheetjs.com/js-xls/> for a browser example.
-
-See `bin/xls2csv` for a node example.
-
Simple usage (gets the value of cell A1 of sheet Sheet1):
var XLS = require('xlsjs');
var xls = XLS.readFile('test.xls');
var Sheet1A1 = xls.Sheets['Sheet1']['A1'].v;
+The node version installs a binary `xls2csv` which can read XLS files and output the contents in various formats. The source is available at `xls2csv.njs` in the bin directory.
+
+See <http://oss.sheetjs.com/js-xls/> for a browser example.
+
Some helper functions in `XLS.utils` generate different views of the sheets:
- `XLS.utils.sheet_to_csv` generates CSV
- `XLS.utils.sheet_to_row_object_array` interprets sheets as tables with a header column and generates an array of objects
- `XLS.utils.get_formulae` generates a list of formulae
-## Notes
+For more details:
-`CFB` refers to the Microsoft Compound File Binary Format, a container format for XLS as well as DOC and other pre-OOXML data formats.
+- `bin/xls2csv.njs` is a tool for node
+- `index.html` is the live demo
+- `bits/80_xls.js` contains the logic for generating CSV and JSON from sheets
-The mechanism is split into a CFB parser (which scans through the file and produces concrete data chunks) and a Workbook parser (which does excel-specific parsing).
+## Cell Object Description
`.SheetNames` is an ordered list of the sheets in the workbook
`.Sheets[sheetname]` returns a data structure representing the sheet
-`.Sheets[sheetname][address].v` returns the value of the specified cell and `.Sheets[sheetname][address].t` returns the type of the cell (constrained to the enumeration `ST_CellType` as documented in page 4215 of ISO/IEC 29500-1:2012(E) )
+`.Sheets[sheetname][address]` returns the specified cell:
-For more details:
+- `.v` : the raw value of the cell
+- `.w` : the formatted text of the cell (if applicable)
+- `.t` : the type of the cell (constrained to the enumeration `ST_CellType` as documented in page 4215 of ISO/IEC 29500-1:2012(E) )
+- `.f` : the formula of the cell (if applicable)
-- `bin/xls2csv.njs` is a tool for node
-- `index.html` is the live demo
-- `bits/80_xls.js` contains the logic for generating CSV and JSON from sheets
+For dates, `.v` holds the raw date code from the sheet and `.w` holds the text
+
+## Other Notes
+
+`CFB` refers to the Microsoft Compound File Binary Format, a container format for XLS as well as DOC and other pre-OOXML data formats.
+
+The mechanism is split into a CFB parser (which scans through the file and produces concrete data chunks) and a Workbook parser (which does excel-specific parsing).
## Test Files
@@ -62,6 +69,10 @@ Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:
- <https://travis-ci.org/SheetJS/SheetJS.github.io> for XLS* modules
- <https://saucelabs.com/u/sheetjs> for XLS* modules using Sauce Labs
+## Contributing
+
+Due to the precarious nature of the Open Specifications Promise, it is very important to ensure code is cleanroom. Consult CONTRIBUTING.md
+
## XLSX/XLSM/XLSB Support
XLSX/XLSM/XLSB support is available in [js-xlsx](https://github.com/SheetJS/js-xlsx).
@@ -98,3 +109,4 @@ ISO/IEC 29500:2012(E) "Information technology — Document description and proce
[![Coverage Status](https://coveralls.io/repos/SheetJS/js-xls/badge.png?branch=master)](https://coveralls.io/r/SheetJS/js-xls?branch=master)
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/4ee4284bf2c638cff8ed705c4438a686 "githalytics.com")](http://githalytics.com/SheetJS/js-xls)
+
View
@@ -1 +1 @@
-XLS.version = '0.6.5';
+XLS.version = '0.6.6';
View
@@ -5,7 +5,7 @@ var _strrev = function(x) { return String(x).split("").reverse().join("");};
function fill(c,l) { return new Array(l+1).join(c); }
function pad(v,d,c){var t=String(v);return t.length>=d?t:(fill(c||0,d-t.length)+t);}
function rpad(v,d,c){var t=String(v);return t.length>=d?t:(t+fill(c||0,d-t.length));}
-SSF.version = '0.5.5';
+SSF.version = '0.5.6';
/* Options */
var opts_fmt = {};
function fixopts(o){for(var y in opts_fmt) if(o[y]===undefined) o[y]=opts_fmt[y];}
@@ -212,13 +212,19 @@ var write_num = function(type, fmt, val) {
if(fmt.indexOf("E") > -1) {
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
if(fmt == '##0.0E+0') {
- var period = fmt.length - 5;
+ var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
var ee = (Number(val.toExponential(0).substr(2+(val<0))))%period;
+ if(ee < 0) ee += period;
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
if(!o.match(/[Ee]/)) {
var fakee = (Number(val.toExponential(0).substr(2+(val<0))));
if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
- else throw "missing E |" + o;
+ else o += "E+" + (fakee - ee);
+ while(o.substr(0,2) === "0.") {
+ o = o[0] + o.substr(2,period) + "." + o.substr(2+period);
+ o = o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.");
+ }
+ o = o.replace(/\+-/,"-");
}
o = o.replace(/^([+-]?)([0-9]*)\.([0-9]*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
} else o = val.toExponential(idx);
@@ -233,6 +239,7 @@ var write_num = function(type, fmt, val) {
var myn = (rnd - base*den), myd = den;
return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad(myn,r[1].length," ") + r[2] + "/" + r[3] + pad(myd,r[4].length));
}
+ if(fmt.match(/^#+0+$/)) fmt = fmt.replace(/#/g,"");
if(fmt.match(/^00+$/)) return (val<0?"-":"")+pad(Math.round(aval),fmt.length);
if(fmt.match(/^[#?]+$/)) return String(Math.round(val)).replace(/^0$/,"");
if((r = fmt.match(/^#*0+\.(0+)/))) {
@@ -343,7 +350,7 @@ function eval_fmt(fmt, v, opts, flen) {
out.push({t:'D', v:o}); break;
case ' ': out.push({t:c,v:c}); ++i; break;
default:
- if(",$-+/():!^&'~{}<>=".indexOf(c) === -1)
+ if(",$-+/():!^&'~{}<>=".indexOf(c) === -1)
throw 'unrecognized character ' + fmt[i] + ' in ' + fmt;
out.push({t:'t', v:c}); ++i; break;
}
@@ -367,7 +374,7 @@ function eval_fmt(fmt, v, opts, flen) {
out[i].t = 't'; break;
case 'n': case '(': case '?':
var jj = i+1;
- while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || out[jj].v == '$' || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {
+ while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || '$€'.indexOf(out[jj].v) > -1 || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {
out[i].v += out[jj].v;
delete out[jj]; ++jj;
}
View
@@ -263,14 +263,23 @@ function parse_workbook(blob) {
} break;
case 'Number': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:'n'};
+ if(temp_val.XF) try {
+ temp_val.w=SSF.format(temp_val.XF.ifmt||0, temp_val.v);
+ } catch(e) { }
addline({c:val.c, r:val.r}, temp_val);
} break;
case 'BoolErr': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t};
+ if(temp_val.XF) try {
+ temp_val.w=SSF.format(temp_val.XF.ifmt||0, temp_val.v);
+ } catch(e) { }
addline({c:val.c, r:val.r}, temp_val);
} break;
case 'RK': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'};
+ if(temp_val.XF) try {
+ temp_val.w=SSF.format(temp_val.XF.ifmt||0, temp_val.v);
+ } catch(e) { }
addline({c:val.c, r:val.r}, temp_val);
} break;
case 'MulRk': {
View
@@ -1,6 +1,6 @@
{
"name": "xlsjs",
- "version": "0.6.5",
+ "version": "0.6.6",
"author": "sheetjs",
"description": "(one day) a full-featured XLS parser and writer. For now, primitive parser",
"keywords": [ "xls", "office", "excel", "spreadsheet" ],
@@ -10,7 +10,7 @@
"main": "./xls",
"dependencies": {
"cfb":">=0.8.0",
- "ssf":"",
+ "ssf":"~0.5.6",
"codepage":"",
"commander":""
},
Submodule test_files updated 256 files
View
@@ -3,7 +3,7 @@
/*jshint eqnull:true, funcscope:true */
var XLS = {};
(function(XLS){
-XLS.version = '0.6.5';
+XLS.version = '0.6.6';
if(typeof module !== "undefined" && typeof require !== 'undefined') {
if(typeof cptable === 'undefined') var cptable = require('codepage');
var current_codepage = 1252, current_cptable = cptable[1252];
@@ -216,7 +216,7 @@ var _strrev = function(x) { return String(x).split("").reverse().join("");};
function fill(c,l) { return new Array(l+1).join(c); }
function pad(v,d,c){var t=String(v);return t.length>=d?t:(fill(c||0,d-t.length)+t);}
function rpad(v,d,c){var t=String(v);return t.length>=d?t:(t+fill(c||0,d-t.length));}
-SSF.version = '0.5.5';
+SSF.version = '0.5.6';
/* Options */
var opts_fmt = {};
function fixopts(o){for(var y in opts_fmt) if(o[y]===undefined) o[y]=opts_fmt[y];}
@@ -423,13 +423,19 @@ var write_num = function(type, fmt, val) {
if(fmt.indexOf("E") > -1) {
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
if(fmt == '##0.0E+0') {
- var period = fmt.length - 5;
+ var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
var ee = (Number(val.toExponential(0).substr(2+(val<0))))%period;
+ if(ee < 0) ee += period;
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
if(!o.match(/[Ee]/)) {
var fakee = (Number(val.toExponential(0).substr(2+(val<0))));
if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
- else throw "missing E |" + o;
+ else o += "E+" + (fakee - ee);
+ while(o.substr(0,2) === "0.") {
+ o = o[0] + o.substr(2,period) + "." + o.substr(2+period);
+ o = o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.");
+ }
+ o = o.replace(/\+-/,"-");
}
o = o.replace(/^([+-]?)([0-9]*)\.([0-9]*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
} else o = val.toExponential(idx);
@@ -444,6 +450,7 @@ var write_num = function(type, fmt, val) {
var myn = (rnd - base*den), myd = den;
return sign + (base?base:"") + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad(myn,r[1].length," ") + r[2] + "/" + r[3] + pad(myd,r[4].length));
}
+ if(fmt.match(/^#+0+$/)) fmt = fmt.replace(/#/g,"");
if(fmt.match(/^00+$/)) return (val<0?"-":"")+pad(Math.round(aval),fmt.length);
if(fmt.match(/^[#?]+$/)) return String(Math.round(val)).replace(/^0$/,"");
if((r = fmt.match(/^#*0+\.(0+)/))) {
@@ -554,7 +561,7 @@ function eval_fmt(fmt, v, opts, flen) {
out.push({t:'D', v:o}); break;
case ' ': out.push({t:c,v:c}); ++i; break;
default:
- if(",$-+/():!^&'~{}<>=".indexOf(c) === -1)
+ if(",$-+/():!^&'~{}<>=".indexOf(c) === -1)
throw 'unrecognized character ' + fmt[i] + ' in ' + fmt;
out.push({t:'t', v:c}); ++i; break;
}
@@ -578,7 +585,7 @@ function eval_fmt(fmt, v, opts, flen) {
out[i].t = 't'; break;
case 'n': case '(': case '?':
var jj = i+1;
- while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || out[jj].v == '$' || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {
+ while(out[jj] && ("?D".indexOf(out[jj].t) > -1 || (" t".indexOf(out[jj].t) > -1 && "?t".indexOf((out[jj+1]||{}).t)>-1 && (out[jj+1].t == '?' || out[jj+1].v == '/')) || out[i].t == '(' && (out[jj].t == ')' || out[jj].t == 'n') || out[jj].t == 't' && (out[jj].v == '/' || '$€'.indexOf(out[jj].v) > -1 || (out[jj].v == ' ' && (out[jj+1]||{}).t == '?')))) {
out[i].v += out[jj].v;
delete out[jj]; ++jj;
}
@@ -4796,14 +4803,23 @@ function parse_workbook(blob) {
} break;
case 'Number': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:'n'};
+ if(temp_val.XF) try {
+ temp_val.w=SSF.format(temp_val.XF.ifmt||0, temp_val.v);
+ } catch(e) { }
addline({c:val.c, r:val.r}, temp_val);
} break;
case 'BoolErr': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t};
+ if(temp_val.XF) try {
+ temp_val.w=SSF.format(temp_val.XF.ifmt||0, temp_val.v);
+ } catch(e) { }
addline({c:val.c, r:val.r}, temp_val);
} break;
case 'RK': {
temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'};
+ if(temp_val.XF) try {
+ temp_val.w=SSF.format(temp_val.XF.ifmt||0, temp_val.v);
+ } catch(e) { }
addline({c:val.c, r:val.r}, temp_val);
} break;
case 'MulRk': {

0 comments on commit 6a8df59

Please sign in to comment.