forked from sheetjs/sheetjs
version bump 0.5.9: sheetRows partial processing
- opts.sheetRows limits parsing; default (0) parses all rows - added -n mode to xlsx2csv to control number of rows - !ref will be adjusted; !fullref holds full range
This commit is contained in:
parent
509f7bf9c7
commit
5c4b5827b5
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
|||||||
LIB=xlsx
|
LIB=xlsx
|
||||||
DEPS=$(wildcard bits/*.js)
|
DEPS=$(wildcard bits/*.js)
|
||||||
TARGET=$(LIB).js
|
TARGET=$(LIB).js
|
||||||
FMT=xlsx xlsm xlsb
|
FMT=xlsx xlsm xlsb misc
|
||||||
|
|
||||||
$(TARGET): $(DEPS)
|
$(TARGET): $(DEPS)
|
||||||
cat $^ > $@
|
cat $^ > $@
|
||||||
|
@ -79,7 +79,9 @@ The exported `read` and `readFile` functions accept an options argument:
|
|||||||
| cellHTML | true | Parse rich text and save HTML to the .h field |
|
| cellHTML | true | Parse rich text and save HTML to the .h field |
|
||||||
| cellNF | false | Save number format string to the .z field |
|
| cellNF | false | Save number format string to the .z field |
|
||||||
| sheetStubs | false | Create cell objects for stub cells |
|
| sheetStubs | false | Create cell objects for stub cells |
|
||||||
|
| sheetRows | 0 | If >0, read the first `sheetRows` rows ** |
|
||||||
| bookDeps | false | If true, parse calculation chains |
|
| bookDeps | false | If true, parse calculation chains |
|
||||||
|
| bookFiles | false | If true, add raw files to book object ** |
|
||||||
| bookProps | false | If true, only parse enough to get book metadata ** |
|
| bookProps | false | If true, only parse enough to get book metadata ** |
|
||||||
| bookSheets | false | If true, only parse enough to get the sheet names |
|
| bookSheets | false | If true, only parse enough to get the sheet names |
|
||||||
|
|
||||||
@ -89,13 +91,17 @@ The exported `read` and `readFile` functions accept an options argument:
|
|||||||
- In some cases, sheets may be parsed even if `bookSheets` is false.
|
- In some cases, sheets may be parsed even if `bookSheets` is false.
|
||||||
- `bookSheets` and `bookProps` combine to give both sets of information
|
- `bookSheets` and `bookProps` combine to give both sets of information
|
||||||
- `Deps` will be an empty object if `bookDeps` is falsy
|
- `Deps` will be an empty object if `bookDeps` is falsy
|
||||||
|
- `bookFiles` adds a `keys` array (paths in the ZIP) and a `files` hash (whose
|
||||||
|
keys are paths and values are objects representing the files)
|
||||||
|
- `sheetRows-1` rows will be generated when looking at the JSON object output
|
||||||
|
(since the header row is counted as a row when parsing the data)
|
||||||
|
|
||||||
The defaults are enumerated in bits/84_defaults.js
|
The defaults are enumerated in bits/84_defaults.js
|
||||||
|
|
||||||
## Tested Environments
|
## Tested Environments
|
||||||
|
|
||||||
- Node 0.8.14, 0.10.1
|
- Node 0.8.14, 0.10.1
|
||||||
- IE 6/7/8/9/10 using Base64 mode (IE10 using HTML5 mode)
|
- IE 6/7/8/9/10 using Base64 mode (IE10/11 using HTML5 mode)
|
||||||
- FF 18 using Base64 or HTML5 mode
|
- FF 18 using Base64 or HTML5 mode
|
||||||
- Chrome 24 using Base64 or HTML5 mode
|
- Chrome 24 using Base64 or HTML5 mode
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ program
|
|||||||
.option('-J, --raw-js', 'emit raw JS object rather than CSV (raw numbers)')
|
.option('-J, --raw-js', 'emit raw JS object rather than CSV (raw numbers)')
|
||||||
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
|
.option('-F, --field-sep <sep>', 'CSV field separator', ",")
|
||||||
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
|
.option('-R, --row-sep <sep>', 'CSV row separator', "\n")
|
||||||
|
.option('-n, --sheet-rows <num>', 'Number of rows to process (0=all rows)')
|
||||||
.option('--dev', 'development mode')
|
.option('--dev', 'development mode')
|
||||||
.option('--read', 'read but do not print out contents')
|
.option('--read', 'read but do not print out contents')
|
||||||
.option('-q, --quiet', 'quiet mode');
|
.option('-q, --quiet', 'quiet mode');
|
||||||
@ -46,6 +47,7 @@ if(!fs.existsSync(filename)) {
|
|||||||
|
|
||||||
var opts = {}, wb;
|
var opts = {}, wb;
|
||||||
if(program.listSheets) opts.bookSheets = true;
|
if(program.listSheets) opts.bookSheets = true;
|
||||||
|
if(program.sheetRows) opts.sheetRows = program.sheetRows;
|
||||||
|
|
||||||
if(program.dev) {
|
if(program.dev) {
|
||||||
X.verbose = 2;
|
X.verbose = 2;
|
||||||
|
@ -1 +1 @@
|
|||||||
XLSX.version = '0.5.8';
|
XLSX.version = '0.5.9';
|
||||||
|
@ -11,6 +11,8 @@ function parse_comments_xml(data, opts) {
|
|||||||
if(x === "" || x.trim() === "") return;
|
if(x === "" || x.trim() === "") return;
|
||||||
var y = parsexmltag(x.match(/<comment[^>]*>/)[0]);
|
var y = parsexmltag(x.match(/<comment[^>]*>/)[0]);
|
||||||
var comment = { author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, ref: y.ref, guid: y.guid };
|
var comment = { author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, ref: y.ref, guid: y.guid };
|
||||||
|
var cell = decode_cell(y.ref);
|
||||||
|
if(opts.sheetRows && opts.sheetRows <= cell.r) return;
|
||||||
var textMatch = x.match(/<text>([^\u2603]*)<\/text>/m);
|
var textMatch = x.match(/<text>([^\u2603]*)<\/text>/m);
|
||||||
if (!textMatch || !textMatch[1]) return; // a comment may contain an empty text tag.
|
if (!textMatch || !textMatch[1]) return; // a comment may contain an empty text tag.
|
||||||
var rt = parse_si(textMatch[1]);
|
var rt = parse_si(textMatch[1]);
|
||||||
@ -26,7 +28,7 @@ function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
|
|||||||
for(var i = 0; i != dirComments.length; ++i) {
|
for(var i = 0; i != dirComments.length; ++i) {
|
||||||
var canonicalpath=dirComments[i];
|
var canonicalpath=dirComments[i];
|
||||||
var comments=parse_comments_xml(getzipdata(zip, canonicalpath.replace(/^\//,''), true), opts);
|
var comments=parse_comments_xml(getzipdata(zip, canonicalpath.replace(/^\//,''), true), opts);
|
||||||
if(!comments || !comments.length) return;
|
if(!comments || !comments.length) continue;
|
||||||
// find the sheets targeted by these comments
|
// find the sheets targeted by these comments
|
||||||
var sheetNames = Object.keys(sheets);
|
var sheetNames = Object.keys(sheets);
|
||||||
for(var j = 0; j != sheetNames.length; ++j) {
|
for(var j = 0; j != sheetNames.length; ++j) {
|
||||||
|
@ -18,9 +18,9 @@ function parse_ws_xml(data, opts) {
|
|||||||
|
|
||||||
/* 18.3.1.73 row CT_Row */
|
/* 18.3.1.73 row CT_Row */
|
||||||
var row = parsexmltag(x.match(/<row[^>]*>/)[0]);
|
var row = parsexmltag(x.match(/<row[^>]*>/)[0]);
|
||||||
|
if(opts.sheetRows && opts.sheetRows < +row.r) return;
|
||||||
if(refguess.s.r > row.r - 1) refguess.s.r = row.r - 1;
|
if(refguess.s.r > row.r - 1) refguess.s.r = row.r - 1;
|
||||||
if(refguess.e.r < row.r - 1) refguess.e.r = row.r - 1;
|
if(refguess.e.r < row.r - 1) refguess.e.r = row.r - 1;
|
||||||
|
|
||||||
/* 18.3.1.4 c CT_Cell */
|
/* 18.3.1.4 c CT_Cell */
|
||||||
var cells = x.substr(x.indexOf('>')+1).split(/<c /);
|
var cells = x.substr(x.indexOf('>')+1).split(/<c /);
|
||||||
cells.forEach(function(c, idx) { if(c === "" || c.trim() === "") return;
|
cells.forEach(function(c, idx) { if(c === "" || c.trim() === "") return;
|
||||||
@ -82,6 +82,18 @@ function parse_ws_xml(data, opts) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
if(!s["!ref"]) s["!ref"] = encode_range(refguess);
|
if(!s["!ref"]) s["!ref"] = encode_range(refguess);
|
||||||
|
if(opts.sheetRows) {
|
||||||
|
var tmpref = decode_range(s["!ref"]);
|
||||||
|
if(opts.sheetRows < +tmpref.e.r) {
|
||||||
|
tmpref.e.r = opts.sheetRows - 1;
|
||||||
|
if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
|
||||||
|
if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
|
||||||
|
if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
|
||||||
|
if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
|
||||||
|
s["!fullref"] = s["!ref"];
|
||||||
|
s["!ref"] = encode_range(tmpref);
|
||||||
|
}
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,13 +123,18 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
var s = {};
|
var s = {};
|
||||||
|
|
||||||
var ref;
|
var ref;
|
||||||
|
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||||
|
|
||||||
var pass = false;
|
var pass = false, end = false;
|
||||||
var row, p, cf;
|
var row, p, cf;
|
||||||
recordhopper(data, function(val, R) {
|
recordhopper(data, function(val, R) {
|
||||||
|
if(end) return;
|
||||||
switch(R.n) {
|
switch(R.n) {
|
||||||
case 'BrtWsDim': ref = val; break;
|
case 'BrtWsDim': ref = val; break;
|
||||||
case 'BrtRowHdr': row = val; break;
|
case 'BrtRowHdr':
|
||||||
|
row = val;
|
||||||
|
if(opts.sheetRows && opts.sheetRows <= row.r) end=true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'BrtFmlaBool':
|
case 'BrtFmlaBool':
|
||||||
case 'BrtFmlaError':
|
case 'BrtFmlaError':
|
||||||
@ -154,7 +159,11 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
if(opts.cellNF) p.z = SSF._table[cf.ifmt];
|
if(opts.cellNF) p.z = SSF._table[cf.ifmt];
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
s[encode_cell({c:val[0].c,r:row.r})] = p;
|
s[encode_cell({c:val[0].c,r:row.r})] = p;
|
||||||
break; // TODO
|
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
||||||
|
if(refguess.s.c > val[0].c) refguess.s.c = val[0].c;
|
||||||
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
|
if(refguess.e.c < val[0].c) refguess.e.c = val[0].c;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'BrtCellBlank': break; // (blank cell)
|
case 'BrtCellBlank': break; // (blank cell)
|
||||||
|
|
||||||
@ -192,6 +201,18 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
}
|
}
|
||||||
}, opts);
|
}, opts);
|
||||||
s["!ref"] = encode_range(ref);
|
s["!ref"] = encode_range(ref);
|
||||||
|
if(opts.sheetRows) {
|
||||||
|
var tmpref = decode_range(s["!ref"]);
|
||||||
|
if(opts.sheetRows < +tmpref.e.r) {
|
||||||
|
tmpref.e.r = opts.sheetRows - 1;
|
||||||
|
if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
|
||||||
|
if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
|
||||||
|
if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
|
||||||
|
if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
|
||||||
|
s["!fullref"] = s["!ref"];
|
||||||
|
s["!ref"] = encode_range(tmpref);
|
||||||
|
}
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ function fixopts(opts) {
|
|||||||
['cellFormula', true], /* emit formulae as .h */
|
['cellFormula', true], /* emit formulae as .h */
|
||||||
|
|
||||||
['sheetStubs', false], /* emit empty cells */
|
['sheetStubs', false], /* emit empty cells */
|
||||||
|
['sheetRows', 0, 'n'], /* read n rows (0 = read all rows) */
|
||||||
['bookDeps', false], /* parse calculation chains */
|
['bookDeps', false], /* parse calculation chains */
|
||||||
['bookSheets', false], /* only try to get sheet names (no Sheets) */
|
['bookSheets', false], /* only try to get sheet names (no Sheets) */
|
||||||
['bookProps', false], /* only try to get properties (no Sheets) */
|
['bookProps', false], /* only try to get properties (no Sheets) */
|
||||||
@ -13,5 +13,8 @@ function fixopts(opts) {
|
|||||||
|
|
||||||
['WTF', false] /* WTF mode (throws errors) */
|
['WTF', false] /* WTF mode (throws errors) */
|
||||||
];
|
];
|
||||||
defaults.forEach(function(d) { if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1]; });
|
defaults.forEach(function(d) {
|
||||||
|
if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1];
|
||||||
|
if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xlsx",
|
"name": "xlsx",
|
||||||
"version": "0.5.8",
|
"version": "0.5.9",
|
||||||
"author": "sheetjs",
|
"author": "sheetjs",
|
||||||
"description": "XLSB / XLSX / XLSM parser",
|
"description": "XLSB / XLSX / XLSM parser",
|
||||||
"keywords": [ "xlsx", "xlsb", "xlsm", "office", "excel", "spreadsheet" ],
|
"keywords": [ "xlsx", "xlsb", "xlsm", "office", "excel", "spreadsheet" ],
|
||||||
|
66
test.js
66
test.js
@ -5,7 +5,6 @@ describe('source',function(){it('should load',function(){XLSX=require('./');});}
|
|||||||
|
|
||||||
var opts = {};
|
var opts = {};
|
||||||
if(process.env.WTF) opts.WTF = true;
|
if(process.env.WTF) opts.WTF = true;
|
||||||
|
|
||||||
var ex = [".xlsb", ".xlsm", ".xlsx"];
|
var ex = [".xlsb", ".xlsm", ".xlsx"];
|
||||||
if(process.env.FMTS) ex=process.env.FMTS.split(":").map(function(x){return x[0]==="."?x:"."+x;});
|
if(process.env.FMTS) ex=process.env.FMTS.split(":").map(function(x){return x[0]==="."?x:"."+x;});
|
||||||
var exp = ex.map(function(x){ return x + ".pending"; });
|
var exp = ex.map(function(x){ return x + ".pending"; });
|
||||||
@ -154,6 +153,42 @@ describe('options', function() {
|
|||||||
var wb = XLSX.readFile(dir+'merge_cells.xlsx', {sheetStubs:true});
|
var wb = XLSX.readFile(dir+'merge_cells.xlsx', {sheetStubs:true});
|
||||||
assert(typeof wb.Sheets.Merge.A2.t !== 'undefined');
|
assert(typeof wb.Sheets.Merge.A2.t !== 'undefined');
|
||||||
});
|
});
|
||||||
|
it('should read all cells by default', function() {
|
||||||
|
var wb = XLSX.readFile(dir+'formula_stress_test.xlsb');
|
||||||
|
assert(typeof wb.Sheets.Text.A46 !== 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.B26 !== 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.C16 !== 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.D2 !== 'undefined');
|
||||||
|
wb = XLSX.readFile(dir+'formula_stress_test.xlsx');
|
||||||
|
assert(typeof wb.Sheets.Text.A46 !== 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.B26 !== 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.C16 !== 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.D2 !== 'undefined');
|
||||||
|
});
|
||||||
|
it('sheetRows n=20', function() {
|
||||||
|
var wb = XLSX.readFile(dir+'formula_stress_test.xlsx', {sheetRows:20});
|
||||||
|
assert(typeof wb.Sheets.Text.A46 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.B26 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.C16 !== 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.D2 !== 'undefined');
|
||||||
|
wb = XLSX.readFile(dir+'formula_stress_test.xlsb', {sheetRows:20});
|
||||||
|
assert(typeof wb.Sheets.Text.A46 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.B26 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.C16 !== 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.D2 !== 'undefined');
|
||||||
|
});
|
||||||
|
it('sheetRows n=10', function() {
|
||||||
|
var wb = XLSX.readFile(dir+'formula_stress_test.xlsb', {sheetRows:10});
|
||||||
|
assert(typeof wb.Sheets.Text.A46 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.B26 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.C16 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.D2 !== 'undefined');
|
||||||
|
wb = XLSX.readFile(dir+'formula_stress_test.xlsx', {sheetRows:10});
|
||||||
|
assert(typeof wb.Sheets.Text.A46 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.B26 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.C16 === 'undefined');
|
||||||
|
assert(typeof wb.Sheets.Text.D2 !== 'undefined');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('book', function() {
|
describe('book', function() {
|
||||||
it('bookSheets should not generate sheets', function() {
|
it('bookSheets should not generate sheets', function() {
|
||||||
@ -224,7 +259,7 @@ describe('features', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should have core properties and custom properties parsed', function() {
|
describe('should parse core properties and custom properties', function() {
|
||||||
var wb;
|
var wb;
|
||||||
before(function() {
|
before(function() {
|
||||||
XLSX = require('./');
|
XLSX = require('./');
|
||||||
@ -242,7 +277,7 @@ describe('features', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should parse cells with date type', function() {
|
describe('should parse cells with date type (XLSX/XLSB)', function() {
|
||||||
var wb, ws;
|
var wb, ws;
|
||||||
before(function() {
|
before(function() {
|
||||||
XLSX = require('./');
|
XLSX = require('./');
|
||||||
@ -255,4 +290,29 @@ describe('features', function() {
|
|||||||
assert.equal(sheet[3]['てすと'], '2/14/14');
|
assert.equal(sheet[3]['てすと'], '2/14/14');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('sheetRows', function() {
|
||||||
|
it('should use original range if not set', function() {
|
||||||
|
var wb = XLSX.readFile(dir+'formula_stress_test.xlsb');
|
||||||
|
assert.equal(wb.Sheets.Text["!ref"],"A1:F49");
|
||||||
|
wb = XLSX.readFile(dir+'formula_stress_test.xlsx');
|
||||||
|
assert.equal(wb.Sheets.Text["!ref"],"A1:F49");
|
||||||
|
});
|
||||||
|
it('should adjust range if set', function() {
|
||||||
|
var wb = XLSX.readFile(dir+'formula_stress_test.xlsx', {sheetRows:10});
|
||||||
|
assert.equal(wb.Sheets.Text["!fullref"],"A1:F49");
|
||||||
|
assert.equal(wb.Sheets.Text["!ref"],"A1:F10");
|
||||||
|
wb = XLSX.readFile(dir+'formula_stress_test.xlsb', {sheetRows:10});
|
||||||
|
assert.equal(wb.Sheets.Text["!fullref"],"A1:F49");
|
||||||
|
assert.equal(wb.Sheets.Text["!ref"],"A1:F10");
|
||||||
|
});
|
||||||
|
it('should not generate comment cells', function() {
|
||||||
|
var wb = XLSX.readFile(dir+'comments_stress_test.xlsx', {sheetRows:10});
|
||||||
|
assert.equal(wb.Sheets.Sheet7["!fullref"],"A1:N34");
|
||||||
|
assert.equal(wb.Sheets.Sheet7["!ref"],"A1:A1");
|
||||||
|
wb = XLSX.readFile(dir+'comments_stress_test.xlsb', {sheetRows:10});
|
||||||
|
assert.equal(wb.Sheets.Sheet7["!fullref"],"A1:N34");
|
||||||
|
assert.equal(wb.Sheets.Sheet7["!ref"],"A1:A1");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,7 @@ named_ranges_2011.xlsb
|
|||||||
number_format.xlsb
|
number_format.xlsb
|
||||||
rich_text_stress.xlsb
|
rich_text_stress.xlsb
|
||||||
time_stress_test_1.xlsb
|
time_stress_test_1.xlsb
|
||||||
|
xlsx-stream-d-date-cell.xlsb
|
||||||
LONumbers-2010.xlsx
|
LONumbers-2010.xlsx
|
||||||
LONumbers-2011.xlsx
|
LONumbers-2011.xlsx
|
||||||
LONumbers.xlsx
|
LONumbers.xlsx
|
||||||
@ -233,6 +234,7 @@ xlrd_test_comments_excel.xlsx
|
|||||||
xlrd_test_comments_gdocs.xlsx
|
xlrd_test_comments_gdocs.xlsx
|
||||||
xlrd_text_bar.xlsx
|
xlrd_text_bar.xlsx
|
||||||
חישוב_נקודות_זיכוי.xlsx
|
חישוב_נקודות_זיכוי.xlsx
|
||||||
|
xlsx-stream-d-date-cell.xlsx
|
||||||
apachepoi_45431.xlsm
|
apachepoi_45431.xlsm
|
||||||
apachepoi_47026.xlsm
|
apachepoi_47026.xlsm
|
||||||
apachepoi_47089.xlsm
|
apachepoi_47089.xlsm
|
||||||
|
54
xlsx.js
54
xlsx.js
@ -423,7 +423,7 @@ SSF.load_table = function(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i]) SSF.loa
|
|||||||
make_ssf(SSF);
|
make_ssf(SSF);
|
||||||
var XLSX = {};
|
var XLSX = {};
|
||||||
(function(XLSX){
|
(function(XLSX){
|
||||||
XLSX.version = '0.5.8';
|
XLSX.version = '0.5.9';
|
||||||
var current_codepage, current_cptable, cptable;
|
var current_codepage, current_cptable, cptable;
|
||||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||||
if(typeof cptable === 'undefined') cptable = require('codepage');
|
if(typeof cptable === 'undefined') cptable = require('codepage');
|
||||||
@ -1242,6 +1242,8 @@ function parse_comments_xml(data, opts) {
|
|||||||
if(x === "" || x.trim() === "") return;
|
if(x === "" || x.trim() === "") return;
|
||||||
var y = parsexmltag(x.match(/<comment[^>]*>/)[0]);
|
var y = parsexmltag(x.match(/<comment[^>]*>/)[0]);
|
||||||
var comment = { author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, ref: y.ref, guid: y.guid };
|
var comment = { author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, ref: y.ref, guid: y.guid };
|
||||||
|
var cell = decode_cell(y.ref);
|
||||||
|
if(opts.sheetRows && opts.sheetRows <= cell.r) return;
|
||||||
var textMatch = x.match(/<text>([^\u2603]*)<\/text>/m);
|
var textMatch = x.match(/<text>([^\u2603]*)<\/text>/m);
|
||||||
if (!textMatch || !textMatch[1]) return; // a comment may contain an empty text tag.
|
if (!textMatch || !textMatch[1]) return; // a comment may contain an empty text tag.
|
||||||
var rt = parse_si(textMatch[1]);
|
var rt = parse_si(textMatch[1]);
|
||||||
@ -1257,7 +1259,7 @@ function parse_comments(zip, dirComments, sheets, sheetRels, opts) {
|
|||||||
for(var i = 0; i != dirComments.length; ++i) {
|
for(var i = 0; i != dirComments.length; ++i) {
|
||||||
var canonicalpath=dirComments[i];
|
var canonicalpath=dirComments[i];
|
||||||
var comments=parse_comments_xml(getzipdata(zip, canonicalpath.replace(/^\//,''), true), opts);
|
var comments=parse_comments_xml(getzipdata(zip, canonicalpath.replace(/^\//,''), true), opts);
|
||||||
if(!comments || !comments.length) return;
|
if(!comments || !comments.length) continue;
|
||||||
// find the sheets targeted by these comments
|
// find the sheets targeted by these comments
|
||||||
var sheetNames = Object.keys(sheets);
|
var sheetNames = Object.keys(sheets);
|
||||||
for(var j = 0; j != sheetNames.length; ++j) {
|
for(var j = 0; j != sheetNames.length; ++j) {
|
||||||
@ -1322,9 +1324,9 @@ function parse_ws_xml(data, opts) {
|
|||||||
|
|
||||||
/* 18.3.1.73 row CT_Row */
|
/* 18.3.1.73 row CT_Row */
|
||||||
var row = parsexmltag(x.match(/<row[^>]*>/)[0]);
|
var row = parsexmltag(x.match(/<row[^>]*>/)[0]);
|
||||||
|
if(opts.sheetRows && opts.sheetRows < +row.r) return;
|
||||||
if(refguess.s.r > row.r - 1) refguess.s.r = row.r - 1;
|
if(refguess.s.r > row.r - 1) refguess.s.r = row.r - 1;
|
||||||
if(refguess.e.r < row.r - 1) refguess.e.r = row.r - 1;
|
if(refguess.e.r < row.r - 1) refguess.e.r = row.r - 1;
|
||||||
|
|
||||||
/* 18.3.1.4 c CT_Cell */
|
/* 18.3.1.4 c CT_Cell */
|
||||||
var cells = x.substr(x.indexOf('>')+1).split(/<c /);
|
var cells = x.substr(x.indexOf('>')+1).split(/<c /);
|
||||||
cells.forEach(function(c, idx) { if(c === "" || c.trim() === "") return;
|
cells.forEach(function(c, idx) { if(c === "" || c.trim() === "") return;
|
||||||
@ -1386,6 +1388,18 @@ function parse_ws_xml(data, opts) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
if(!s["!ref"]) s["!ref"] = encode_range(refguess);
|
if(!s["!ref"]) s["!ref"] = encode_range(refguess);
|
||||||
|
if(opts.sheetRows) {
|
||||||
|
var tmpref = decode_range(s["!ref"]);
|
||||||
|
if(opts.sheetRows < +tmpref.e.r) {
|
||||||
|
tmpref.e.r = opts.sheetRows - 1;
|
||||||
|
if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
|
||||||
|
if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
|
||||||
|
if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
|
||||||
|
if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
|
||||||
|
s["!fullref"] = s["!ref"];
|
||||||
|
s["!ref"] = encode_range(tmpref);
|
||||||
|
}
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1514,13 +1528,18 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
var s = {};
|
var s = {};
|
||||||
|
|
||||||
var ref;
|
var ref;
|
||||||
|
var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} };
|
||||||
|
|
||||||
var pass = false;
|
var pass = false, end = false;
|
||||||
var row, p, cf;
|
var row, p, cf;
|
||||||
recordhopper(data, function(val, R) {
|
recordhopper(data, function(val, R) {
|
||||||
|
if(end) return;
|
||||||
switch(R.n) {
|
switch(R.n) {
|
||||||
case 'BrtWsDim': ref = val; break;
|
case 'BrtWsDim': ref = val; break;
|
||||||
case 'BrtRowHdr': row = val; break;
|
case 'BrtRowHdr':
|
||||||
|
row = val;
|
||||||
|
if(opts.sheetRows && opts.sheetRows <= row.r) end=true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'BrtFmlaBool':
|
case 'BrtFmlaBool':
|
||||||
case 'BrtFmlaError':
|
case 'BrtFmlaError':
|
||||||
@ -1545,7 +1564,11 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
if(opts.cellNF) p.z = SSF._table[cf.ifmt];
|
if(opts.cellNF) p.z = SSF._table[cf.ifmt];
|
||||||
} catch(e) { if(opts.WTF) throw e; }
|
} catch(e) { if(opts.WTF) throw e; }
|
||||||
s[encode_cell({c:val[0].c,r:row.r})] = p;
|
s[encode_cell({c:val[0].c,r:row.r})] = p;
|
||||||
break; // TODO
|
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
||||||
|
if(refguess.s.c > val[0].c) refguess.s.c = val[0].c;
|
||||||
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
|
if(refguess.e.c < val[0].c) refguess.e.c = val[0].c;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'BrtCellBlank': break; // (blank cell)
|
case 'BrtCellBlank': break; // (blank cell)
|
||||||
|
|
||||||
@ -1583,6 +1606,18 @@ var parse_ws_bin = function(data, opts) {
|
|||||||
}
|
}
|
||||||
}, opts);
|
}, opts);
|
||||||
s["!ref"] = encode_range(ref);
|
s["!ref"] = encode_range(ref);
|
||||||
|
if(opts.sheetRows) {
|
||||||
|
var tmpref = decode_range(s["!ref"]);
|
||||||
|
if(opts.sheetRows < +tmpref.e.r) {
|
||||||
|
tmpref.e.r = opts.sheetRows - 1;
|
||||||
|
if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
|
||||||
|
if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
|
||||||
|
if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
|
||||||
|
if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
|
||||||
|
s["!fullref"] = s["!ref"];
|
||||||
|
s["!ref"] = encode_range(tmpref);
|
||||||
|
}
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2698,7 +2733,7 @@ function fixopts(opts) {
|
|||||||
['cellFormula', true], /* emit formulae as .h */
|
['cellFormula', true], /* emit formulae as .h */
|
||||||
|
|
||||||
['sheetStubs', false], /* emit empty cells */
|
['sheetStubs', false], /* emit empty cells */
|
||||||
|
['sheetRows', 0, 'n'], /* read n rows (0 = read all rows) */
|
||||||
['bookDeps', false], /* parse calculation chains */
|
['bookDeps', false], /* parse calculation chains */
|
||||||
['bookSheets', false], /* only try to get sheet names (no Sheets) */
|
['bookSheets', false], /* only try to get sheet names (no Sheets) */
|
||||||
['bookProps', false], /* only try to get properties (no Sheets) */
|
['bookProps', false], /* only try to get properties (no Sheets) */
|
||||||
@ -2706,7 +2741,10 @@ function fixopts(opts) {
|
|||||||
|
|
||||||
['WTF', false] /* WTF mode (throws errors) */
|
['WTF', false] /* WTF mode (throws errors) */
|
||||||
];
|
];
|
||||||
defaults.forEach(function(d) { if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1]; });
|
defaults.forEach(function(d) {
|
||||||
|
if(typeof opts[d[0]] === 'undefined') opts[d[0]] = d[1];
|
||||||
|
if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function parseZip(zip, opts) {
|
function parseZip(zip, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
Loading…
Reference in New Issue
Block a user