version bump 0.6.1: dist cleanup

- XLSX format strings properly handles literal UTF8 chars (test apachepoi_49273)
- codepage updated to 1.0.0
- jszip updated to 2.2.0 (node-only)
- dist now contains jszip and codepage dependencies
- updated test_files
This commit is contained in:
SheetJS 2014-04-22 18:37:08 -07:00
parent dc2d391fbc
commit 6801958327
20 changed files with 3698 additions and 38 deletions

@ -2,6 +2,8 @@ LIB=xlsx
DEPS=$(wildcard bits/*.js)
TARGET=$(LIB).js
FMT=xlsx xlsm xlsb misc
REQS=jszip.js
ADDONS=dist/cpexcel.js
$(TARGET): $(DEPS)
cat $^ > $@
@ -51,7 +53,14 @@ coveralls-spin:
make coveralls & bash misc/spin.sh $$!
.PHONY: dist
dist: $(TARGET)
dist: dist-deps $(TARGET)
cp $(TARGET) dist/
cp LICENSE dist/
uglifyjs $(TARGET) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(REQS) $(TARGET) -o dist/$(LIB).core.min.js --source-map dist/$(LIB).core.min.map --preamble "$$(head -n 1 bits/00_header.js)"
uglifyjs $(REQS) $(ADDONS) $(TARGET) -o dist/$(LIB).full.min.js --source-map dist/$(LIB).full.min.map --preamble "$$(head -n 1 bits/00_header.js)"
.PHONY: dist-deps
dist-deps:
cp node_modules/codepage/dist/cpexcel.full.js dist/cpexcel.js
cp jszip.js dist/jszip.js

@ -11,21 +11,45 @@ In node:
In the browser:
<!-- This is the only file you need (includes xlsx.js and jszip) -->
<script lang="javascript" src="dist/xlsx.core.min.js"></script>
In [bower](http://bower.io/):
bower install js-xlsx
CDNjs automatically pulls the latest version and makes all versions available at
<http://cdnjs.com/libraries/xlsx>
Older versions of this README recommended a more explicit approach:
<!-- JSZip must be included before xlsx.js -->
<script lang="javascript" src="/path/to/jszip.js"></script>
<script lang="javascript" src="/path/to/xlsx.js"></script>
## Optional Modules
The node version automatically requires modules for additional features. Some of these modules are rather large in size and are only needed in special circumstances, so they do not ship with the core. For browser use, they must be included directly:
<!-- international support from https://github.com/sheetjs/js-codepage -->
<script src="dist/cpexcel.js"></script>
An appropriate version for each dependency is included in the dist/ directory.
The complete single-file version is generated at `dist/xlsx.full.min.js`
## Usage
Simple usage (walks through every cell of every sheet and dumps the values):
var XLSX = require('xlsx')
var xlsx = XLSX.readFile('test.xlsx');
var XLSX = require('xlsx');
var workbook = XLSX.readFile('test.xlsx');
var sheet_name_list = xlsx.SheetNames;
xlsx.SheetNames.forEach(function(y) {
for (z in xlsx.Sheets[y]) {
sheet_name_list.forEach(function(y) {
var worksheet = workbook.Sheets[y];
for (z in worksheet) {
if(z[0] === '!') continue;
console.log(y + "!" + z + "=" + JSON.stringify(xlsx.Sheets[y][z].v));
console.log(y + "!" + z + "=" + JSON.stringify(worksheet[z].v));
}
});

@ -1 +1 @@
XLSX.version = '0.6.0';
XLSX.version = '0.6.1';

@ -105,7 +105,7 @@ var general_fmt = function(v) {
}
else {
o = v.toFixed(11).replace(/(\.[0-9]*[1-9])0*$/,"$1");
if(o.length > 11 + (v<0?1:0)) o = v.toPrecision(6);
if(o.length > 11 + (v<0?1:0)) o = v.toPrecision(6);
}
o = o.replace(/(\.[0-9]*[1-9])0+e/,"$1e").replace(/\.0*e/,"e");
return o.replace("e","E").replace(/\.0*$/,"").replace(/\.([0-9]*[^0])0*$/,".$1").replace(/(E[+-])([0-9])$/,"$1"+"0"+"$2");
@ -217,7 +217,7 @@ var write_num = function(type, fmt, val) {
if(fmt.indexOf("E") > -1) {
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
if(fmt.match(/^#+0.0E\+0$/)) {
var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
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);

@ -1,9 +1,33 @@
/* 18.4.1 charset to codepage mapping */
var CS2CP = {
0: 1252, /* ANSI */
1: 65001, /* DEFAULT */
2: 65001, /* SYMBOL */
77: 10000, /* MAC */
128: 932, /* SHIFTJIS */
129: 949, /* HANGUL */
130: 1361, /* JOHAB */
134: 936, /* GB2312 */
136: 950, /* CHINESEBIG5 */
161: 1253, /* GREEK */
162: 1254, /* TURKISH */
163: 1258, /* VIETNAMESE */
177: 1255, /* HEBREW */
178: 1256, /* ARABIC */
186: 1257, /* BALTIC */
204: 1251, /* RUSSIAN */
222: 874, /* THAI */
238: 1250, /* EASTEUROPE */
255: 1252, /* OEM */
69: 6969 /* MISC */
};
/* Parse a list of <r> tags */
var parse_rs = (function() {
var tregex = matchtag("t"), rpregex = matchtag("rPr");
/* 18.4.7 rPr CT_RPrElt */
var parse_rpr = function(rpr, intro, outro) {
var font = {};
var font = {}, cp = 65001;
(rpr.match(/<[^>]*>/g)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
@ -20,7 +44,10 @@ var parse_rs = (function() {
case '<shadow/>': break;
/* 18.4.1 charset CT_IntProperty TODO */
case '<charset': break;
case '<charset':
if(y.val == '1') break;
cp = CS2CP[parseInt(y.val, 10)];
break;
/* 18.4.2 outline CT_BooleanProperty TODO */
case '<outline':
@ -85,18 +112,20 @@ var parse_rs = (function() {
if(font.i) style.push("font-style: italic;");
intro.push('<span style="' + style.join("") + '">');
outro.push("</span>");
return cp;
};
/* 18.4.4 r CT_RElt */
function parse_r(r) {
var terms = [[],"",[]];
/* 18.4.12 t ST_Xstring */
var t = r.match(tregex);
var t = r.match(tregex), cp = 65001;
if(!isval(t)) return "";
terms[1] = t[1];
var rpr = r.match(rpregex);
if(isval(rpr)) parse_rpr(rpr[1], terms[0], terms[2]);
if(isval(rpr)) cp = parse_rpr(rpr[1], terms[0], terms[2]);
return terms[0].join("") + terms[1].replace(/\r\n/g,'<br/>') + terms[2].join("");
}
return function(rs) {

@ -7,7 +7,7 @@ function parseNumFmts(t, opts) {
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': break;
case '<numFmt': {
var f=unescapexml(y.formatCode), i=parseInt(y.numFmtId,10);
var f=utf8read(unescapexml(y.formatCode)), i=parseInt(y.numFmtId,10);
styles.NumberFmt[i] = f; if(i>0) SSF.load(f,i);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';

1185
dist/cpexcel.js vendored Normal file

File diff suppressed because it is too large Load Diff

2315
dist/jszip.js vendored Normal file

File diff suppressed because it is too large Load Diff

7
dist/xlsx.core.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/xlsx.core.min.map vendored Normal file

File diff suppressed because one or more lines are too long

12
dist/xlsx.full.min.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/xlsx.full.min.map vendored Normal file

File diff suppressed because one or more lines are too long

45
dist/xlsx.js vendored

@ -3,7 +3,7 @@
/*jshint eqnull:true */
var XLSX = {};
(function(XLSX){
XLSX.version = '0.6.0';
XLSX.version = '0.6.1';
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
var SSF = {};
var make_ssf = function(SSF){
@ -111,7 +111,7 @@ var general_fmt = function(v) {
}
else {
o = v.toFixed(11).replace(/(\.[0-9]*[1-9])0*$/,"$1");
if(o.length > 11 + (v<0?1:0)) o = v.toPrecision(6);
if(o.length > 11 + (v<0?1:0)) o = v.toPrecision(6);
}
o = o.replace(/(\.[0-9]*[1-9])0+e/,"$1e").replace(/\.0*e/,"e");
return o.replace("e","E").replace(/\.0*$/,"").replace(/\.([0-9]*[^0])0*$/,".$1").replace(/(E[+-])([0-9])$/,"$1"+"0"+"$2");
@ -223,7 +223,7 @@ var write_num = function(type, fmt, val) {
if(fmt.indexOf("E") > -1) {
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
if(fmt.match(/^#+0.0E\+0$/)) {
var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
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);
@ -841,12 +841,36 @@ function parse_FontFlags(data, length) {
};
return out;
}
/* 18.4.1 charset to codepage mapping */
var CS2CP = {
0: 1252, /* ANSI */
1: 65001, /* DEFAULT */
2: 65001, /* SYMBOL */
77: 10000, /* MAC */
128: 932, /* SHIFTJIS */
129: 949, /* HANGUL */
130: 1361, /* JOHAB */
134: 936, /* GB2312 */
136: 950, /* CHINESEBIG5 */
161: 1253, /* GREEK */
162: 1254, /* TURKISH */
163: 1258, /* VIETNAMESE */
177: 1255, /* HEBREW */
178: 1256, /* ARABIC */
186: 1257, /* BALTIC */
204: 1251, /* RUSSIAN */
222: 874, /* THAI */
238: 1250, /* EASTEUROPE */
255: 1252, /* OEM */
69: 6969 /* MISC */
};
/* Parse a list of <r> tags */
var parse_rs = (function() {
var tregex = matchtag("t"), rpregex = matchtag("rPr");
/* 18.4.7 rPr CT_RPrElt */
var parse_rpr = function(rpr, intro, outro) {
var font = {};
var font = {}, cp = 65001;
(rpr.match(/<[^>]*>/g)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
@ -863,7 +887,10 @@ var parse_rs = (function() {
case '<shadow/>': break;
/* 18.4.1 charset CT_IntProperty TODO */
case '<charset': break;
case '<charset':
if(y.val == '1') break;
cp = CS2CP[parseInt(y.val, 10)];
break;
/* 18.4.2 outline CT_BooleanProperty TODO */
case '<outline':
@ -928,18 +955,20 @@ var parse_rs = (function() {
if(font.i) style.push("font-style: italic;");
intro.push('<span style="' + style.join("") + '">');
outro.push("</span>");
return cp;
};
/* 18.4.4 r CT_RElt */
function parse_r(r) {
var terms = [[],"",[]];
/* 18.4.12 t ST_Xstring */
var t = r.match(tregex);
var t = r.match(tregex), cp = 65001;
if(!isval(t)) return "";
terms[1] = t[1];
var rpr = r.match(rpregex);
if(isval(rpr)) parse_rpr(rpr[1], terms[0], terms[2]);
if(isval(rpr)) cp = parse_rpr(rpr[1], terms[0], terms[2]);
return terms[0].join("") + terms[1].replace(/\r\n/g,'<br/>') + terms[2].join("");
}
return function(rs) {
@ -1016,7 +1045,7 @@ function parseNumFmts(t, opts) {
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': break;
case '<numFmt': {
var f=unescapexml(y.formatCode), i=parseInt(y.numFmtId,10);
var f=utf8read(unescapexml(y.formatCode)), i=parseInt(y.numFmtId,10);
styles.NumberFmt[i] = f; if(i>0) SSF.load(f,i);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';

2
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

@ -1,6 +1,6 @@
{
"name": "xlsx",
"version": "0.6.0",
"version": "0.6.1",
"author": "sheetjs",
"description": "XLSB / XLSX / XLSM (Excel 2007+ Spreadsheet) parser",
"keywords": [ "xlsx", "xlsb", "xlsm", "office", "excel", "spreadsheet" ],
@ -10,9 +10,9 @@
"main": "./xlsx",
"dependencies": {
"ssf":"~0.6.4",
"codepage":"",
"codepage":"1.x",
"cfb":"",
"jszip":"~2.1.0",
"jszip":"~2.2.0",
"commander":""
},
"devDependencies": {
@ -23,7 +23,7 @@
"repository": { "type":"git", "url":"git://github.com/SheetJS/js-xlsx.git" },
"scripts": {
"pretest": "git submodule init && git submodule update",
"test": "make mocha",
"test": "make test",
"test-jasmine": "jasmine-node --verbose tests/"
},
"config": {

@ -298,7 +298,7 @@ describe('features', function() {
[wb1,wb2].map(function(wb) { return wb.Sheets[sheet]; }).forEach(function(ws, i) {
assert.equal(ws.B1.c.length, 1,"must have 1 comment");
assert.equal(ws.B1.c[0].a, "Yegor Kozlov","must have the same author");
assert.equal(ws.B1.c[0].t.replace(/\r\n/g,"\n"), "Yegor Kozlov:\nfirst cell", "must have the concatenated texts");
assert.equal(ws.B1.c[0].t.replace(/\r\n/g,"\n").replace(/\r/g,"\n"), "Yegor Kozlov:\nfirst cell", "must have the concatenated texts");
if(i > 0) return;
assert.equal(ws.B1.c[0].r, '<r><rPr><b/><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t>Yegor Kozlov:</t></r><r><rPr><sz val="8"/><color indexed="81"/><rFont val="Tahoma"/></rPr><t xml:space="preserve">\r\nfirst cell</t></r>', "must have the rich text representation");
assert.equal(ws.B1.c[0].h, '<span style="font-weight: bold;">Yegor Kozlov:</span><span style=""><br/>first cell</span>', "must have the html representation");

@ -103,6 +103,7 @@ apachepoi_56011.xlsx
apachepoi_56017.xlsx
apachepoi_56169.xlsx
apachepoi_56278.xlsx
apachepoi_56315.xlsx
apachepoi_AverageTaxRates.xlsx
apachepoi_Booleans.xlsx
apachepoi_BrNotClosed.xlsx
@ -187,6 +188,24 @@ jxls-examples_stress1.xlsx
jxls-examples_stress2.xlsx
jxls-reader_departmentData.xlsx
large_strings.xlsx.pending
libreoffice_calc_cjk-text_cell-justify-distributed-single.xlsx
libreoffice_calc_conditional-formatting.xlsx
libreoffice_calc_conditional-formatting_all_icon_sets.xlsx
libreoffice_calc_drawing-object_shapes.xlsx
libreoffice_calc_export-millon-rows.xlsx
libreoffice_calc_external-ref_access-basic.xlsx
libreoffice_calc_external-ref_extdata.xlsx
libreoffice_calc_tab-color.xlsx
libreoffice_calc_text-angled-with-border.xlsx
libreoffice_calc_xlsx-export-single-cell-at-last-row.xlsx
libreoffice_calc_xlsx-import_encryption_simple-encryption-2007.xlsx.pending
libreoffice_calc_xlsx-import_encryption_simple-encryption-2010.xlsx.pending
libreoffice_calc_xlsx-import_format-as-table.xlsx
libreoffice_calc_xlsx-import_named-range.xlsx
libreoffice_calc_xlsx-import_perf_300000_line_sample.xlsx.pending
libreoffice_calc_xlsx-import_perf_8-by-300000-cells.xlsx.pending
libreoffice_calc_xlsx-import_perf_pivot-table-with-large-unique-entries.xlsx
libreoffice_calc_xlsx-import_shared-formula_1.xlsx
merge_cells.xlsx
mixed_sheets.xlsx
named_ranges_2011.xlsx

@ -1 +1 @@
Subproject commit b422ac319612c2b54c9d46eeed78acde901eda7c
Subproject commit 42ff3701227761dc8e5dca11642a6e43dd846325

45
xlsx.js

@ -3,7 +3,7 @@
/*jshint eqnull:true */
var XLSX = {};
(function(XLSX){
XLSX.version = '0.6.0';
XLSX.version = '0.6.1';
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
var SSF = {};
var make_ssf = function(SSF){
@ -111,7 +111,7 @@ var general_fmt = function(v) {
}
else {
o = v.toFixed(11).replace(/(\.[0-9]*[1-9])0*$/,"$1");
if(o.length > 11 + (v<0?1:0)) o = v.toPrecision(6);
if(o.length > 11 + (v<0?1:0)) o = v.toPrecision(6);
}
o = o.replace(/(\.[0-9]*[1-9])0+e/,"$1e").replace(/\.0*e/,"e");
return o.replace("e","E").replace(/\.0*$/,"").replace(/\.([0-9]*[^0])0*$/,".$1").replace(/(E[+-])([0-9])$/,"$1"+"0"+"$2");
@ -223,7 +223,7 @@ var write_num = function(type, fmt, val) {
if(fmt.indexOf("E") > -1) {
var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
if(fmt.match(/^#+0.0E\+0$/)) {
var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
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);
@ -841,12 +841,36 @@ function parse_FontFlags(data, length) {
};
return out;
}
/* 18.4.1 charset to codepage mapping */
var CS2CP = {
0: 1252, /* ANSI */
1: 65001, /* DEFAULT */
2: 65001, /* SYMBOL */
77: 10000, /* MAC */
128: 932, /* SHIFTJIS */
129: 949, /* HANGUL */
130: 1361, /* JOHAB */
134: 936, /* GB2312 */
136: 950, /* CHINESEBIG5 */
161: 1253, /* GREEK */
162: 1254, /* TURKISH */
163: 1258, /* VIETNAMESE */
177: 1255, /* HEBREW */
178: 1256, /* ARABIC */
186: 1257, /* BALTIC */
204: 1251, /* RUSSIAN */
222: 874, /* THAI */
238: 1250, /* EASTEUROPE */
255: 1252, /* OEM */
69: 6969 /* MISC */
};
/* Parse a list of <r> tags */
var parse_rs = (function() {
var tregex = matchtag("t"), rpregex = matchtag("rPr");
/* 18.4.7 rPr CT_RPrElt */
var parse_rpr = function(rpr, intro, outro) {
var font = {};
var font = {}, cp = 65001;
(rpr.match(/<[^>]*>/g)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
@ -863,7 +887,10 @@ var parse_rs = (function() {
case '<shadow/>': break;
/* 18.4.1 charset CT_IntProperty TODO */
case '<charset': break;
case '<charset':
if(y.val == '1') break;
cp = CS2CP[parseInt(y.val, 10)];
break;
/* 18.4.2 outline CT_BooleanProperty TODO */
case '<outline':
@ -928,18 +955,20 @@ var parse_rs = (function() {
if(font.i) style.push("font-style: italic;");
intro.push('<span style="' + style.join("") + '">');
outro.push("</span>");
return cp;
};
/* 18.4.4 r CT_RElt */
function parse_r(r) {
var terms = [[],"",[]];
/* 18.4.12 t ST_Xstring */
var t = r.match(tregex);
var t = r.match(tregex), cp = 65001;
if(!isval(t)) return "";
terms[1] = t[1];
var rpr = r.match(rpregex);
if(isval(rpr)) parse_rpr(rpr[1], terms[0], terms[2]);
if(isval(rpr)) cp = parse_rpr(rpr[1], terms[0], terms[2]);
return terms[0].join("") + terms[1].replace(/\r\n/g,'<br/>') + terms[2].join("");
}
return function(rs) {
@ -1016,7 +1045,7 @@ function parseNumFmts(t, opts) {
switch(y[0]) {
case '<numFmts': case '</numFmts>': case '<numFmts/>': break;
case '<numFmt': {
var f=unescapexml(y.formatCode), i=parseInt(y.numFmtId,10);
var f=utf8read(unescapexml(y.formatCode)), i=parseInt(y.numFmtId,10);
styles.NumberFmt[i] = f; if(i>0) SSF.load(f,i);
} break;
default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts';