forked from sheetjs/sheetjs
version bump 0.11.4: BIFF8 XLS write
- xlsx bin script takes `-8, --xls` options for writing BIFF8 - updated CFB to 0.12.1, CRC32 to 1.1.1 - test file spelling error (h/t @jsoref) - minified script renames write_shift / read_shift - UTF8 and XML entity processing Issues: - fixes #815 h/t @Neroth - fixes #739 h/t @LittleBreak @PWDream - fixes #553 h/t @keyiis - fixes #492 h/t @FlyingSailor @simonchan2013
This commit is contained in:
parent
f03e32fc9a
commit
d02650055d
1
.gitignore
vendored
1
.gitignore
vendored
@ -20,6 +20,7 @@ tmp
|
||||
*.[uU][oO][sS]
|
||||
*.[wW][kKqQbB][S1234567890]
|
||||
*.[qQ][pP][wW]
|
||||
*.[bB][iI][fF][fF][23458]
|
||||
*.123
|
||||
*.htm
|
||||
*.html
|
||||
|
@ -22,6 +22,7 @@ tmp
|
||||
*.[uU][oO][sS]
|
||||
*.[wW][kKqQbB][S1234567890]
|
||||
*.[qQ][pP][wW]
|
||||
*.[bB][iI][fF][fF][23458]
|
||||
*.123
|
||||
*.htm
|
||||
*.html
|
||||
|
@ -1564,7 +1564,8 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `xlsx` | `.xlsx` | ZIP | multi | Excel 2007+ XML Format |
|
||||
| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet format |
|
||||
| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet |
|
||||
@ -1887,7 +1888,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | :o: | :o: |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | :o: | :o: |
|
||||
| Excel 2003-2004 XML Format (XML "SpreadsheetML") | :o: | :o: |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | :o: |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | |
|
||||
| Excel 4.0 (XLS/XLW BIFF4) | :o: | |
|
||||
| Excel 3.0 (XLS BIFF3) | :o: | |
|
||||
|
38
bin/xlsx.njs
38
bin/xlsx.njs
@ -20,6 +20,10 @@ program
|
||||
.option('-M, --xlsm', 'emit XLSM to <sheetname> or <file>.xlsm')
|
||||
.option('-X, --xlsx', 'emit XLSX to <sheetname> or <file>.xlsx')
|
||||
.option('-Y, --ods', 'emit ODS to <sheetname> or <file>.ods')
|
||||
.option('-8, --xls', 'emit XLS to <sheetname> or <file>.xls (BIFF8)')
|
||||
//.option('-5, --biff5','emit XLS to <sheetname> or <file>.xls (BIFF5)')
|
||||
//.option('-4, --biff4','emit XLS to <sheetname> or <file>.xls (BIFF4)')
|
||||
//.option('-3, --biff3','emit XLS to <sheetname> or <file>.xls (BIFF3)')
|
||||
.option('-2, --biff2','emit XLS to <sheetname> or <file>.xls (BIFF2)')
|
||||
.option('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)')
|
||||
.option('-T, --fods', 'emit FODS to <sheetname> or <file>.fods (Flat ODS)')
|
||||
@ -52,15 +56,22 @@ program.on('--help', function() {
|
||||
console.log(' Web Demo: http://oss.sheetjs.com/js-'+n+'/');
|
||||
});
|
||||
|
||||
/* output formats, update list with full option name */
|
||||
var workbook_formats = ['xlsx', 'xlsm', 'xlsb', 'ods', 'fods'];
|
||||
/* flag, bookType, default ext */
|
||||
var workbook_formats = [
|
||||
['xlsx', 'xlsx', 'xlsx'],
|
||||
['xlsm', 'xlsm', 'xlsm'],
|
||||
['xlsb', 'xlsb', 'xlsb'],
|
||||
['xls', 'xls', 'xls'],
|
||||
//['biff5', 'biff5', 'xls'],
|
||||
['ods', 'ods', 'ods'],
|
||||
['fods', 'fods', 'fods']
|
||||
];
|
||||
var wb_formats_2 = [
|
||||
['xlml', 'xlml', 'xls']
|
||||
['xlml', 'xlml', 'xls']
|
||||
];
|
||||
program.parse(process.argv);
|
||||
|
||||
var filename = "", sheetname = '';
|
||||
var filename = '', sheetname = '';
|
||||
if(program.args[0]) {
|
||||
filename = program.args[0];
|
||||
if(program.args[1]) sheetname = program.args[1];
|
||||
@ -89,13 +100,12 @@ function wb_fmt() {
|
||||
opts.cellNF = true;
|
||||
if(program.output) sheetname = program.output;
|
||||
}
|
||||
function isfmt(m) {
|
||||
function isfmt(m/*:string*/)/*:boolean*/ {
|
||||
if(!program.output) return false;
|
||||
var t = m.charAt(0) == "." ? m : "." + m;
|
||||
console.log(m);
|
||||
return program.output.slice(-m.length) == m;
|
||||
var t = m.charAt(0) === "." ? m : "." + m;
|
||||
return program.output.slice(-t.length) === t;
|
||||
}
|
||||
workbook_formats.forEach(function(m) { if(program[m] || isfmt(m)) { wb_fmt(); } });
|
||||
workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { wb_fmt(); } });
|
||||
wb_formats_2.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { wb_fmt(); } });
|
||||
if(seen) {
|
||||
} else if(program.formulae) opts.cellFormula = true;
|
||||
@ -135,8 +145,9 @@ var wopts = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
|
||||
if(program.compress) wopts.compression = true;
|
||||
|
||||
/* full workbook formats */
|
||||
workbook_formats.forEach(function(m) { if(program[m] || isfmt(m)) {
|
||||
X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m), wopts);
|
||||
workbook_formats.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
|
||||
wopts.bookType = m[1];
|
||||
X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m[2]), wopts);
|
||||
process.exit(0);
|
||||
} });
|
||||
|
||||
@ -169,6 +180,8 @@ if(program.readOnly) process.exit(0);
|
||||
/* single worksheet formats */
|
||||
[
|
||||
['biff2', '.xls'],
|
||||
//['biff3', '.xls'],
|
||||
//['biff4', '.xls'],
|
||||
['sylk', '.slk'],
|
||||
['html', '.html'],
|
||||
['prn', '.prn'],
|
||||
@ -180,8 +193,7 @@ if(program.readOnly) process.exit(0);
|
||||
process.exit(0);
|
||||
} });
|
||||
|
||||
var oo = "";
|
||||
var strm = false;
|
||||
var oo = "", strm = false;
|
||||
if(!program.quiet) console.error(target_sheet);
|
||||
if(program.formulae) oo = X.utils.sheet_to_formulae(ws).join("\n");
|
||||
else if(program.json) oo = JSON.stringify(X.utils.sheet_to_json(ws));
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.11.3';
|
||||
XLSX.version = '0.11.4';
|
||||
|
414
bits/18_cfb.js
414
bits/18_cfb.js
@ -12,10 +12,13 @@ declare var bconcat:any;
|
||||
declare var s2a:any;
|
||||
declare var chr0:any;
|
||||
declare var chr1:any;
|
||||
declare var new_buf:any;
|
||||
*/
|
||||
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*jshint eqnull:true */
|
||||
/*exported CFB */
|
||||
/*global module, require:false, process:false, Buffer:false, Uint8Array:false */
|
||||
|
||||
/*::
|
||||
declare var DO_NOT_EXPORT_CFB:?boolean;
|
||||
@ -35,15 +38,35 @@ type CFBFiles = {[n:string]:CFBEntry};
|
||||
/* [MS-CFB] v20130118 */
|
||||
var CFB = (function _CFB(){
|
||||
var exports/*:CFBModule*/ = /*::(*/{}/*:: :any)*/;
|
||||
exports.version = '0.12.1';
|
||||
exports.version = '0.13.1';
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
|
||||
var L = l.split("/"), R = r.split("/");
|
||||
for(var i = 0, c = 0, Z = Math.min(L.length, R.length); i < Z; ++i) {
|
||||
if((c = L[i].length - R[i].length)) return c;
|
||||
if(L[i] != R[i]) return L[i] < R[i] ? -1 : 1;
|
||||
}
|
||||
return L.length - R.length;
|
||||
}
|
||||
function dirname(p/*:string*/)/*:string*/ {
|
||||
if(p.charAt(p.length - 1) == "/") return (p.slice(0,-1).indexOf("/") === -1) ? p : dirname(p.slice(0, -1));
|
||||
var c = p.lastIndexOf("/");
|
||||
return (c === -1) ? p : p.slice(0, c+1);
|
||||
}
|
||||
|
||||
function filename(p/*:string*/)/*:string*/ {
|
||||
if(p.charAt(p.length - 1) == "/") return filename(p.slice(0, -1));
|
||||
var c = p.lastIndexOf("/");
|
||||
return (c === -1) ? p : p.slice(c+1);
|
||||
}
|
||||
function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ {
|
||||
var mver = 3; // major version
|
||||
var ssz = 512; // sector size
|
||||
var mver = 3;
|
||||
var ssz = 512;
|
||||
var nmfs = 0; // number of mini FAT sectors
|
||||
var ndfs = 0; // number of DIFAT sectors
|
||||
var dir_start = 0; // first directory sector location
|
||||
var minifat_start = 0; // first mini FAT sector location
|
||||
var difat_start = 0; // first mini FAT sector location
|
||||
var difat_sec_cnt = 0;
|
||||
var dir_start = 0;
|
||||
var minifat_start = 0;
|
||||
var difat_start = 0;
|
||||
|
||||
var fat_addrs/*:Array<number>*/ = []; // locations of FAT sectors
|
||||
|
||||
@ -67,11 +90,10 @@ var header/*:RawBytes*/ = file.slice(0,ssz);
|
||||
check_shifts(blob, mver);
|
||||
|
||||
// Number of Directory Sectors
|
||||
var nds/*:number*/ = blob.read_shift(4, 'i');
|
||||
if(mver === 3 && nds !== 0) throw new Error('# Directory Sectors: Expected 0 saw ' + nds);
|
||||
var dir_cnt/*:number*/ = blob.read_shift(4, 'i');
|
||||
if(mver === 3 && dir_cnt !== 0) throw new Error('# Directory Sectors: Expected 0 saw ' + dir_cnt);
|
||||
|
||||
// Number of FAT Sectors
|
||||
//var nfs = blob.read_shift(4, 'i');
|
||||
blob.l += 4;
|
||||
|
||||
// First Directory Sector Location
|
||||
@ -93,7 +115,7 @@ nmfs = blob.read_shift(4, 'i');
|
||||
difat_start = blob.read_shift(4, 'i');
|
||||
|
||||
// Number of DIFAT Sectors
|
||||
ndfs = blob.read_shift(4, 'i');
|
||||
difat_sec_cnt = blob.read_shift(4, 'i');
|
||||
|
||||
// Grab FAT Sector Locations
|
||||
for(var q = -1, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */
|
||||
@ -105,7 +127,7 @@ for(var q = -1, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */
|
||||
/** Break the file up into sectors */
|
||||
var sectors/*:Array<RawBytes>*/ = sectorify(file, ssz);
|
||||
|
||||
sleuth_fat(difat_start, ndfs, sectors, ssz, fat_addrs);
|
||||
sleuth_fat(difat_start, difat_sec_cnt, sectors, ssz, fat_addrs);
|
||||
|
||||
/** Chains */
|
||||
var sector_list/*:SectorList*/ = make_sector_list(sectors, dir_start, fat_addrs, ssz);
|
||||
@ -121,19 +143,17 @@ var files/*:CFBFiles*/ = {}, Paths/*:Array<string>*/ = [], FileIndex/*:CFBFileIn
|
||||
read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex);
|
||||
|
||||
build_full_paths(FileIndex, FullPathDir, FullPaths, Paths);
|
||||
Paths.shift();
|
||||
|
||||
var root_name/*:string*/ = Paths.shift();
|
||||
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
var find_path = make_find_path(FullPaths, Paths, FileIndex, files, root_name);
|
||||
|
||||
return {
|
||||
raw: {header: header, sectors: sectors},
|
||||
var o = {
|
||||
FileIndex: FileIndex,
|
||||
FullPaths: FullPaths,
|
||||
FullPathDir: FullPathDir,
|
||||
find: find_path
|
||||
FullPathDir: FullPathDir
|
||||
};
|
||||
|
||||
// $FlowIgnore
|
||||
if(options && options.raw) o.raw = {header: header, sectors: sectors};
|
||||
return o;
|
||||
} // parse
|
||||
|
||||
/* [MS-CFB] 2.2 Compound File Header -- read up to major version */
|
||||
@ -220,25 +240,8 @@ function build_full_paths(FI/*:CFBFileIndex*/, FPD/*:CFBFullPathDir*/, FP/*:Arra
|
||||
}
|
||||
}
|
||||
|
||||
/* [MS-CFB] 2.6.4 */
|
||||
function make_find_path(FullPaths/*:Array<string>*/, Paths/*:Array<string>*/, FileIndex/*:CFBFileIndex*/, files/*:CFBFiles*/, root_name/*:string*/)/*:CFBFindPath*/ {
|
||||
var UCFullPaths/*:Array<string>*/ = [];
|
||||
var UCPaths/*:Array<string>*/ = [], i = 0;
|
||||
for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase().replace(chr0,'').replace(chr1,'!');
|
||||
for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!');
|
||||
return function find_path(path/*:string*/)/*:?CFBEntry*/ {
|
||||
var k/*:boolean*/ = false;
|
||||
if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; }
|
||||
else k = path.indexOf("/") !== -1;
|
||||
var UCPath/*:string*/ = path.toUpperCase().replace(chr0,'').replace(chr1,'!');
|
||||
var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w === -1) return null;
|
||||
return k === true ? FileIndex[w] : files[Paths[w]];
|
||||
};
|
||||
}
|
||||
|
||||
/** Chase down the rest of the DIFAT chain to build a comprehensive list
|
||||
DIFAT chains by storing the next sector number as the last 32 bytes */
|
||||
DIFAT chains by storing the next sector number as the last 32 bits */
|
||||
function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/, ssz/*:number*/, fat_addrs)/*:void*/ {
|
||||
var q/*:number*/ = ENDOFCHAIN;
|
||||
if(idx === ENDOFCHAIN) {
|
||||
@ -256,7 +259,6 @@ function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/,
|
||||
|
||||
/** Follow the linked list of sectors for a given starting point */
|
||||
function get_sector_list(sectors/*:Array<RawBytes>*/, start/*:number*/, fat_addrs/*:Array<number>*/, ssz/*:number*/, chkd/*:?Array<boolean>*/)/*:SectorEntry*/ {
|
||||
var sl = sectors.length;
|
||||
var buf/*:Array<number>*/ = [], buf_chain/*:Array<any>*/ = [];
|
||||
if(!chkd) chkd = [];
|
||||
var modulus = ssz - 1, j = 0, jj = 0;
|
||||
@ -355,22 +357,259 @@ function read_date(blob/*:RawBytes|CFBlob*/, offset/*:number*/)/*:Date*/ {
|
||||
}
|
||||
|
||||
var fs/*:: = require('fs'); */;
|
||||
function readFileSync(filename/*:string*/, options/*:CFBReadOpts*/) {
|
||||
function read_file(filename/*:string*/, options/*:CFBReadOpts*/) {
|
||||
if(fs == null) fs = require('fs');
|
||||
return parse(fs.readFileSync(filename), options);
|
||||
}
|
||||
|
||||
function readSync(blob/*:RawBytes|string*/, options/*:CFBReadOpts*/) {
|
||||
function read(blob/*:RawBytes|string*/, options/*:CFBReadOpts*/) {
|
||||
switch(options && options.type || "base64") {
|
||||
case "file": /*:: if(typeof blob !== 'string') throw "Must pass a filename when type='file'"; */return readFileSync(blob, options);
|
||||
case "file": /*:: if(typeof blob !== 'string') throw "Must pass a filename when type='file'"; */return read_file(blob, options);
|
||||
case "base64": /*:: if(typeof blob !== 'string') throw "Must pass a base64-encoded binary string when type='file'"; */return parse(s2a(Base64.decode(blob)), options);
|
||||
case "binary": /*:: if(typeof blob !== 'string') throw "Must pass a binary string when type='file'"; */return parse(s2a(blob), options);
|
||||
}
|
||||
return parse(/*::typeof blob == 'string' ? new Buffer(blob, 'utf-8') : */blob, options);
|
||||
}
|
||||
|
||||
function init_cfb(cfb/*:CFBContainer*/, opts/*:?any*/)/*:void*/ {
|
||||
var o = opts || {}, root = o.root || "Root Entry";
|
||||
if(!cfb.FullPaths) cfb.FullPaths = [];
|
||||
if(!cfb.FileIndex) cfb.FileIndex = [];
|
||||
if(cfb.FullPaths.length !== cfb.FileIndex.length) throw new Error("inconsistent CFB structure");
|
||||
if(cfb.FullPaths.length === 0) {
|
||||
cfb.FullPaths[0] = root + "/";
|
||||
cfb.FileIndex[0] = ({ name: root, type: 5 }/*:any*/);
|
||||
}
|
||||
if(o.CLSID) cfb.FileIndex[0].clsid = o.CLSID;
|
||||
seed_cfb(cfb);
|
||||
}
|
||||
function seed_cfb(cfb/*:CFBContainer*/)/*:void*/ {
|
||||
var nm = "\u0001Sh33tJ5";
|
||||
if(CFB.find(cfb, "/" + nm)) return;
|
||||
var p = new_buf(4); p[0] = 55; p[1] = p[3] = 50; p[2] = 54;
|
||||
cfb.FileIndex.push(({ name: nm, type: 2, content:p, size:4, L:69, R:69, C:69 }/*:any*/));
|
||||
cfb.FullPaths.push(cfb.FullPaths[0] + nm);
|
||||
rebuild_cfb(cfb);
|
||||
}
|
||||
function rebuild_cfb(cfb/*:CFBContainer*/, f/*:?boolean*/)/*:void*/ {
|
||||
init_cfb(cfb);
|
||||
var gc = false, s = false;
|
||||
for(var i = cfb.FullPaths.length - 1; i >= 0; --i) {
|
||||
var _file = cfb.FileIndex[i];
|
||||
switch(_file.type) {
|
||||
case 0:
|
||||
if(s) gc = true;
|
||||
else { cfb.FileIndex.pop(); cfb.FullPaths.pop(); }
|
||||
break;
|
||||
case 1: case 2: case 5:
|
||||
s = true;
|
||||
if(isNaN(_file.R * _file.L * _file.C)) gc = true;
|
||||
if(_file.R > -1 && _file.L > -1 && _file.R == _file.L) gc = true;
|
||||
break;
|
||||
default: gc = true; break;
|
||||
}
|
||||
}
|
||||
if(!gc && !f) return;
|
||||
|
||||
var now = new Date(1987, 1, 19), j = 0;
|
||||
var data/*:Array<[string, CFBEntry]>*/ = [];
|
||||
for(i = 0; i < cfb.FullPaths.length; ++i) {
|
||||
if(cfb.FileIndex[i].type === 0) continue;
|
||||
data.push([cfb.FullPaths[i], cfb.FileIndex[i]]);
|
||||
}
|
||||
for(i = 0; i < data.length; ++i) {
|
||||
var dad = dirname(data[i][0]);
|
||||
s = false;
|
||||
for(j = 0; j < data.length; ++j) if(data[j][0] === dad) s = true;
|
||||
if(!s) data.push([dad, ({
|
||||
name: filename(dad).replace("/",""),
|
||||
type: 1,
|
||||
clsid: HEADER_CLSID,
|
||||
ct: now, mt: now,
|
||||
content: null
|
||||
}/*:any*/)]);
|
||||
}
|
||||
|
||||
data.sort(function(x,y) { return namecmp(x[0], y[0]); });
|
||||
cfb.FullPaths = []; cfb.FileIndex = [];
|
||||
for(i = 0; i < data.length; ++i) { cfb.FullPaths[i] = data[i][0]; cfb.FileIndex[i] = data[i][1]; }
|
||||
for(i = 0; i < data.length; ++i) {
|
||||
var elt = cfb.FileIndex[i];
|
||||
var nm = cfb.FullPaths[i];
|
||||
|
||||
elt.name = filename(nm).replace("/","");
|
||||
elt.L = elt.R = elt.C = -(elt.color = 1);
|
||||
elt.size = elt.content ? elt.content.length : 0;
|
||||
elt.start = 0;
|
||||
elt.clsid = (elt.clsid || HEADER_CLSID);
|
||||
if(i === 0) {
|
||||
elt.C = data.length > 1 ? 1 : -1;
|
||||
elt.size = 0;
|
||||
elt.type = 5;
|
||||
} else if(nm.slice(-1) == "/") {
|
||||
for(j=i+1;j < data.length; ++j) if(dirname(cfb.FullPaths[j])==nm) break;
|
||||
elt.C = j >= data.length ? -1 : j;
|
||||
for(j=i+1;j < data.length; ++j) if(dirname(cfb.FullPaths[j])==dirname(nm)) break;
|
||||
elt.R = j >= data.length ? -1 : j;
|
||||
elt.type = 1;
|
||||
} else {
|
||||
if(dirname(cfb.FullPaths[i+1]||"") == dirname(nm)) elt.R = i + 1;
|
||||
elt.type = 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/ {
|
||||
rebuild_cfb(cfb);
|
||||
var L = (function(cfb/*:CFBContainer*/)/*:Array<number>*/{
|
||||
var mini_size = 0, fat_size = 0;
|
||||
for(var i = 0; i < cfb.FileIndex.length; ++i) {
|
||||
var file = cfb.FileIndex[i];
|
||||
if(!file.content) continue;
|
||||
/*:: if(file.content == null) throw new Error("unreachable"); */
|
||||
var flen = file.content.length;
|
||||
if(flen === 0){}
|
||||
else if(flen < 0x1000) mini_size += (flen + 0x3F) >> 6;
|
||||
else fat_size += (flen + 0x01FF) >> 9;
|
||||
}
|
||||
var dir_cnt = (cfb.FullPaths.length +3) >> 2;
|
||||
var mini_cnt = (mini_size + 7) >> 3;
|
||||
var mfat_cnt = (mini_size + 0x7F) >> 7;
|
||||
var fat_base = mini_cnt + fat_size + dir_cnt + mfat_cnt;
|
||||
var fat_cnt = (fat_base + 0x7F) >> 7;
|
||||
var difat_cnt = fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt-109)/0x7F);
|
||||
while(((fat_base + fat_cnt + difat_cnt + 0x7F) >> 7) > fat_cnt) difat_cnt = ++fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt-109)/0x7F);
|
||||
var L = [1, difat_cnt, fat_cnt, mfat_cnt, dir_cnt, fat_size, mini_size, 0];
|
||||
cfb.FileIndex[0].size = mini_size << 6;
|
||||
L[7] = (cfb.FileIndex[0].start=L[0]+L[1]+L[2]+L[3]+L[4]+L[5])+((L[6]+7) >> 3);
|
||||
return L;
|
||||
})(cfb);
|
||||
var o = new_buf(L[7] << 9);
|
||||
var i = 0, T = 0;
|
||||
{
|
||||
for(i = 0; i < 8; ++i) o.write_shift(1, HEADER_SIG[i]);
|
||||
for(i = 0; i < 8; ++i) o.write_shift(2, 0);
|
||||
o.write_shift(2, 0x003E);
|
||||
o.write_shift(2, 0x0003);
|
||||
o.write_shift(2, 0xFFFE);
|
||||
o.write_shift(2, 0x0009);
|
||||
o.write_shift(2, 0x0006);
|
||||
for(i = 0; i < 3; ++i) o.write_shift(2, 0);
|
||||
o.write_shift(4, 0);
|
||||
o.write_shift(4, L[2]);
|
||||
o.write_shift(4, L[0] + L[1] + L[2] + L[3] - 1);
|
||||
o.write_shift(4, 0);
|
||||
o.write_shift(4, 1<<12);
|
||||
o.write_shift(4, L[3] ? L[0] + L[1] + L[2] - 1: ENDOFCHAIN);
|
||||
o.write_shift(4, L[3]);
|
||||
o.write_shift(-4, L[1] ? L[0] - 1: ENDOFCHAIN);
|
||||
o.write_shift(4, L[1]);
|
||||
for(i = 0; i < 109; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);
|
||||
}
|
||||
if(L[1]) {
|
||||
for(T = 0; T < L[1]; ++T) {
|
||||
for(; i < 236 + T * 127; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);
|
||||
o.write_shift(-4, T === L[1] - 1 ? ENDOFCHAIN : T + 1);
|
||||
}
|
||||
}
|
||||
var chainit = function(w/*:number*/)/*:void*/ {
|
||||
for(T += w; i<T-1; ++i) o.write_shift(-4, i+1);
|
||||
if(w) { ++i; o.write_shift(-4, ENDOFCHAIN); }
|
||||
};
|
||||
T = i = 0;
|
||||
for(T+=L[1]; i<T; ++i) o.write_shift(-4, consts.DIFSECT);
|
||||
for(T+=L[2]; i<T; ++i) o.write_shift(-4, consts.FATSECT);
|
||||
chainit(L[3]);
|
||||
chainit(L[4]);
|
||||
var j/*:number*/ = 0, flen/*:number*/ = 0;
|
||||
var file/*:CFBEntry*/ = cfb.FileIndex[0];
|
||||
for(; j < cfb.FileIndex.length; ++j) {
|
||||
file = cfb.FileIndex[j];
|
||||
if(!file.content) continue;
|
||||
/*:: if(file.content == null) throw new Error("unreachable"); */
|
||||
flen = file.content.length;
|
||||
if(flen < 0x1000) continue;
|
||||
file.start = T;
|
||||
chainit((flen + 0x01FF) >> 9);
|
||||
}
|
||||
chainit((L[6] + 7) >> 3);
|
||||
while(o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);
|
||||
T = i = 0;
|
||||
for(j = 0; j < cfb.FileIndex.length; ++j) {
|
||||
file = cfb.FileIndex[j];
|
||||
if(!file.content) continue;
|
||||
/*:: if(file.content == null) throw new Error("unreachable"); */
|
||||
flen = file.content.length;
|
||||
if(!flen || flen >= 0x1000) continue;
|
||||
file.start = T;
|
||||
chainit((flen + 0x3F) >> 6);
|
||||
}
|
||||
while(o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);
|
||||
for(i = 0; i < L[4]<<2; ++i) {
|
||||
var nm = cfb.FullPaths[i];
|
||||
if(!nm || nm.length === 0) {
|
||||
for(j = 0; j < 17; ++j) o.write_shift(4, 0);
|
||||
for(j = 0; j < 3; ++j) o.write_shift(4, -1);
|
||||
for(j = 0; j < 12; ++j) o.write_shift(4, 0);
|
||||
continue;
|
||||
}
|
||||
file = cfb.FileIndex[i];
|
||||
if(i === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;
|
||||
flen = 2*(file.name.length+1);
|
||||
o.write_shift(64, file.name, "utf16le");
|
||||
o.write_shift(2, flen);
|
||||
o.write_shift(1, file.type);
|
||||
o.write_shift(1, file.color);
|
||||
o.write_shift(-4, file.L);
|
||||
o.write_shift(-4, file.R);
|
||||
o.write_shift(-4, file.C);
|
||||
if(!file.clsid) for(j = 0; j < 4; ++j) o.write_shift(4, 0);
|
||||
else o.write_shift(16, file.clsid, "hex");
|
||||
o.write_shift(4, file.state || 0);
|
||||
o.write_shift(4, 0); o.write_shift(4, 0);
|
||||
o.write_shift(4, 0); o.write_shift(4, 0);
|
||||
o.write_shift(4, file.start);
|
||||
o.write_shift(4, file.size); o.write_shift(4, 0);
|
||||
}
|
||||
for(i = 1; i < cfb.FileIndex.length; ++i) {
|
||||
file = cfb.FileIndex[i];
|
||||
/*:: if(!file.content) throw new Error("unreachable"); */
|
||||
if(file.size >= 0x1000) {
|
||||
o.l = (file.start+1) << 9;
|
||||
for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
|
||||
for(; j & 0x1FF; ++j) o.write_shift(1, 0);
|
||||
}
|
||||
}
|
||||
for(i = 1; i < cfb.FileIndex.length; ++i) {
|
||||
file = cfb.FileIndex[i];
|
||||
/*:: if(!file.content) throw new Error("unreachable"); */
|
||||
if(file.size > 0 && file.size < 0x1000) {
|
||||
for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
|
||||
for(; j & 0x3F; ++j) o.write_shift(1, 0);
|
||||
}
|
||||
}
|
||||
while(o.l < o.length) o.write_shift(1, 0);
|
||||
return o;
|
||||
}
|
||||
/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
|
||||
function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
|
||||
return cfb.find(path);
|
||||
//return cfb.find(path);
|
||||
var UCFullPaths/*:Array<string>*/ = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
|
||||
var UCPaths/*:Array<string>*/ = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
|
||||
var k/*:boolean*/ = false;
|
||||
if(path.charCodeAt(0) === 47 /* "/" */) { k = true; path = UCFullPaths[0].slice(0, -1) + path; }
|
||||
else k = path.indexOf("/") !== -1;
|
||||
var UCPath/*:string*/ = path.toUpperCase();
|
||||
var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
|
||||
if(w !== -1) return cfb.FileIndex[w];
|
||||
|
||||
UCPath = UCPath.replace(chr0,'').replace(chr1,'!');
|
||||
for(w = 0; w < UCFullPaths.length; ++w) {
|
||||
if(UCFullPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
if(UCPaths[w].replace(chr0,'').replace(chr1,'!') == UCPath) return cfb.FileIndex[w];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/** CFB Constants */
|
||||
var MSSZ = 64; /* Mini Sector Size = 1<<6 */
|
||||
@ -379,9 +618,10 @@ var MSSZ = 64; /* Mini Sector Size = 1<<6 */
|
||||
var ENDOFCHAIN = -2;
|
||||
/* 2.2 Compound File Header */
|
||||
var HEADER_SIGNATURE = 'd0cf11e0a1b11ae1';
|
||||
var HEADER_SIG = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
|
||||
var HEADER_CLSID = '00000000000000000000000000000000';
|
||||
var consts = {
|
||||
/* 2.1 Compound File Sector Numbers and Types */
|
||||
/* 2.1 Compund File Sector Numbers and Types */
|
||||
MAXREGSECT: -6,
|
||||
DIFSECT: -4,
|
||||
FATSECT: -3,
|
||||
@ -397,10 +637,92 @@ var consts = {
|
||||
EntryTypes: ['unknown','storage','stream','lockbytes','property','root']
|
||||
};
|
||||
|
||||
function write_file(cfb/*:CFBContainer*/, filename/*:string*/, options/*:CFBWriteOpts*/)/*:void*/ {
|
||||
var o = _write(cfb, options);
|
||||
/*:: if(typeof Buffer == 'undefined' || !Buffer.isBuffer(o) || !(o instanceof Buffer)) throw new Error("unreachable"); */
|
||||
fs.writeFileSync(filename, o);
|
||||
}
|
||||
|
||||
function a2s(o/*:RawBytes*/)/*:string*/ {
|
||||
var out = new Array(o.length);
|
||||
for(var i = 0; i < o.length; ++i) out[i] = String.fromCharCode(o[i]);
|
||||
return out.join("");
|
||||
}
|
||||
|
||||
function write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|string*/ {
|
||||
var o = _write(cfb, options);
|
||||
switch(options && options.type) {
|
||||
case "file": fs.writeFileSync(options.filename, (o/*:any*/)); return o;
|
||||
case "binary": return a2s(o);
|
||||
case "base64": return Base64.encode(a2s(o));
|
||||
}
|
||||
return o;
|
||||
}
|
||||
function cfb_new(opts/*:?any*/)/*:CFBContainer*/ {
|
||||
var o/*:CFBContainer*/ = ({}/*:any*/);
|
||||
init_cfb(o, opts);
|
||||
return o;
|
||||
}
|
||||
|
||||
function cfb_add(cfb/*:CFBContainer*/, name/*:string*/, content/*:?RawBytes*/, opts/*:?any*/)/*:CFBEntry*/ {
|
||||
init_cfb(cfb);
|
||||
var file = CFB.find(cfb, name);
|
||||
if(!file) {
|
||||
var fpath = cfb.FullPaths[0];
|
||||
if(name.slice(0, fpath.length) == fpath) fpath = name;
|
||||
else {
|
||||
if(fpath.slice(-1) != "/") fpath += "/";
|
||||
fpath = (fpath + name).replace("//","/");
|
||||
}
|
||||
file = ({name: filename(name)}/*:any*/);
|
||||
cfb.FileIndex.push(file);
|
||||
cfb.FullPaths.push(fpath);
|
||||
CFB.utils.cfb_gc(cfb);
|
||||
}
|
||||
/*:: if(!file) throw new Error("unreachable"); */
|
||||
file.content = (content/*:any*/);
|
||||
file.size = content ? content.length : 0;
|
||||
if(opts) {
|
||||
if(opts.CLSID) file.clsid = opts.CLSID;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
function cfb_del(cfb/*:CFBContainer*/, name/*:string*/)/*:boolean*/ {
|
||||
init_cfb(cfb);
|
||||
var file = CFB.find(cfb, name);
|
||||
if(file) for(var j = 0; j < cfb.FileIndex.length; ++j) if(cfb.FileIndex[j] == file) {
|
||||
cfb.FileIndex.splice(j, 1);
|
||||
cfb.FullPaths.splice(j, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function cfb_mov(cfb/*:CFBContainer*/, old_name/*:string*/, new_name/*:string*/)/*:boolean*/ {
|
||||
init_cfb(cfb);
|
||||
var file = CFB.find(cfb, old_name);
|
||||
if(file) for(var j = 0; j < cfb.FileIndex.length; ++j) if(cfb.FileIndex[j] == file) {
|
||||
cfb.FileIndex[j].name = filename(new_name);
|
||||
cfb.FullPaths[j] = new_name;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function cfb_gc(cfb/*:CFBContainer*/)/*:void*/ { rebuild_cfb(cfb, true); }
|
||||
|
||||
exports.find = find;
|
||||
exports.read = readSync;
|
||||
exports.read = read;
|
||||
exports.parse = parse;
|
||||
exports.write = write;
|
||||
exports.writeFile = write_file;
|
||||
exports.utils = {
|
||||
cfb_new: cfb_new,
|
||||
cfb_add: cfb_add,
|
||||
cfb_del: cfb_del,
|
||||
cfb_mov: cfb_mov,
|
||||
cfb_gc: cfb_gc,
|
||||
ReadShift: ReadShift,
|
||||
CheckField: CheckField,
|
||||
prep_blob: prep_blob,
|
||||
|
@ -1,5 +1,7 @@
|
||||
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
|
||||
var attregexg=/([^"\s?>\/]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
|
||||
var tagregex=/<[\/\?]?[a-zA-Z0-9:]+(?:\s+[^"\s?>\/]+=(?:"[^"]*"|'[^']*'|[^'">\s]+))*\s?[\/\?]?>/g;
|
||||
if(!(XML_HEADER.match(tagregex))) tagregex = /<[^>]*>/g;
|
||||
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
|
||||
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/)/*:any*/ {
|
||||
var z = ({}/*:any*/);
|
||||
@ -174,7 +176,6 @@ function write_vt(s) {
|
||||
throw new Error("Unable to serialize " + s);
|
||||
}
|
||||
|
||||
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
|
||||
var XMLNS = ({
|
||||
'dc': 'http://purl.org/dc/elements/1.1/',
|
||||
'dcterms': 'http://purl.org/dc/terms/',
|
||||
|
@ -13,6 +13,7 @@ function write_double_le(b, v/*:number*/, idx/*:number*/) {
|
||||
var bs = ((v < 0 || 1/v == -Infinity) ? 1 : 0) << 7, e = 0, m = 0;
|
||||
var av = bs ? -v : v;
|
||||
if(!isFinite(av)) { e = 0x7ff; m = isNaN(v) ? 0x6969 : 0; }
|
||||
else if(av == 0) e = m = 0;
|
||||
else {
|
||||
e = Math.floor(Math.log(av) / Math.LN2);
|
||||
m = av * Math.pow(2, 52 - e);
|
||||
@ -164,6 +165,20 @@ function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/) {
|
||||
/*:: if(typeof val !== 'string') throw new Error("unreachable"); */
|
||||
for(i = 0; i != val.length; ++i) this[this.l + i] = val.charCodeAt(i) & 0xFF;
|
||||
size = val.length;
|
||||
} else if(f === 'hex') {
|
||||
for(; i < t; ++i) {
|
||||
/*:: if(typeof val !== "string") throw new Error("unreachable"); */
|
||||
this[this.l++] = parseInt(val.slice(2*i, 2*i+2), 16)||0;
|
||||
} return this;
|
||||
} else if(f === 'utf16le') {
|
||||
var end/*:number*/ = this.l + t;
|
||||
for(i = 0; i < Math.min(val.length, t); ++i) {
|
||||
var cc = val.charCodeAt(i);
|
||||
this[this.l++] = cc & 0xff;
|
||||
this[this.l++] = cc >> 8;
|
||||
}
|
||||
while(this.l < end) this[this.l++] = 0;
|
||||
return this;
|
||||
} else /*:: if(typeof val === 'number') */ switch(t) {
|
||||
case 1: size = 1; this[this.l] = val&0xFF; break;
|
||||
case 2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break;
|
||||
|
@ -12,7 +12,7 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
|
||||
length = tmpbyte & 0x7F;
|
||||
for(cntbyte = 1; cntbyte <4 && (tmpbyte & 0x80); ++cntbyte) length += ((tmpbyte = data.read_shift(1)) & 0x7F)<<(7*cntbyte);
|
||||
tgt = data.l + length;
|
||||
var d = R.f(data, length, opts);
|
||||
var d = (R.f||parsenoop)(data, length, opts);
|
||||
data.l = tgt;
|
||||
if(cb(d, R.n, RT)) return;
|
||||
}
|
||||
@ -53,7 +53,7 @@ function buf_array()/*:BufArray*/ {
|
||||
}
|
||||
|
||||
function write_record(ba/*:BufArray*/, type/*:string*/, payload, length/*:?number*/) {
|
||||
var t/*:number*/ = Number(evert_RE[type]), l;
|
||||
var t/*:number*/ = +XLSBRE[type], l;
|
||||
if(isNaN(t)) return; // TODO: throw something here?
|
||||
if(!length) length = XLSBRecordEnum[t].p || (payload||[]).length || 0;
|
||||
l = 1 + (t >= 0x80 ? 1 : 0) + 1 + length;
|
||||
|
@ -267,6 +267,7 @@ function parse_PropertySetStream(file, PIDSI) {
|
||||
|
||||
|
||||
function parsenoop2(blob, length) { blob.read_shift(length); return null; }
|
||||
function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; }
|
||||
|
||||
function parslurp(blob, length, cb) {
|
||||
var arr = [], target = blob.l + length;
|
||||
@ -275,21 +276,26 @@ function parslurp(blob, length, cb) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
function parsebool(blob, length) { return blob.read_shift(length) === 0x1; }
|
||||
function parsebool(blob, length/*:number*/) { return blob.read_shift(length) === 0x1; }
|
||||
function writebool(v/*:any*/, o) { if(!o) o=new_buf(2); o.write_shift(2, +!!v); return o; }
|
||||
|
||||
function parseuint16(blob/*::, length:?number, opts:?any*/) { return blob.read_shift(2, 'u'); }
|
||||
function writeuint16(v/*:number*/, o) { if(!o) o=new_buf(2); o.write_shift(2, v); return o; }
|
||||
function parseuint16a(blob, length/*:: :?number, opts:?any*/) { return parslurp(blob,length,parseuint16);}
|
||||
|
||||
/* --- 2.5 Structures --- */
|
||||
|
||||
/* [MS-XLS] 2.5.14 Boolean */
|
||||
var parse_Boolean = parsebool;
|
||||
|
||||
/* [MS-XLS] 2.5.10 Bes (boolean or error) */
|
||||
function parse_Bes(blob/*::, length*/) {
|
||||
var v = blob.read_shift(1), t = blob.read_shift(1);
|
||||
return t === 0x01 ? v : v === 0x01;
|
||||
}
|
||||
function write_Bes(v, t/*:string*/, o) {
|
||||
if(!o) o = new_buf(2);
|
||||
o.write_shift(1, +v);
|
||||
o.write_shift(1, t == 'e' ? 1 : 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.5.240 ShortXLUnicodeString */
|
||||
function parse_ShortXLUnicodeString(blob, length, opts) {
|
||||
@ -366,7 +372,7 @@ function parse_ControlInfo(blob, length, opts) {
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.7.6 URLMoniker TODO: flags */
|
||||
var parse_URLMoniker = function(blob/*::, length, opts*/) {
|
||||
function parse_URLMoniker(blob/*::, length, opts*/) {
|
||||
var len = blob.read_shift(4), start = blob.l;
|
||||
var extra = false;
|
||||
if(len > 24) {
|
||||
@ -378,10 +384,10 @@ var parse_URLMoniker = function(blob/*::, length, opts*/) {
|
||||
var url = blob.read_shift((extra?len-24:len)>>1, 'utf16le').replace(chr0,"");
|
||||
if(extra) blob.l += 24;
|
||||
return url;
|
||||
};
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.7.8 FileMoniker TODO: all fields */
|
||||
var parse_FileMoniker = function(blob, length) {
|
||||
function parse_FileMoniker(blob, length) {
|
||||
var cAnti = blob.read_shift(2);
|
||||
var ansiLength = blob.read_shift(4);
|
||||
var ansiPath = blob.read_shift(ansiLength, 'cstr');
|
||||
@ -393,27 +399,27 @@ var parse_FileMoniker = function(blob, length) {
|
||||
var usKeyValue = blob.read_shift(2);
|
||||
var unicodePath = blob.read_shift(cbUnicodePathBytes>>1, 'utf16le').replace(chr0,"");
|
||||
return unicodePath;
|
||||
};
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.7.2 HyperlinkMoniker TODO: all the monikers */
|
||||
var parse_HyperlinkMoniker = function(blob, length) {
|
||||
function parse_HyperlinkMoniker(blob, length) {
|
||||
var clsid = blob.read_shift(16); length -= 16;
|
||||
switch(clsid) {
|
||||
case "e0c9ea79f9bace118c8200aa004ba90b": return parse_URLMoniker(blob, length);
|
||||
case "0303000000000000c000000000000046": return parse_FileMoniker(blob, length);
|
||||
default: throw new Error("Unsupported Moniker " + clsid);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.7.9 HyperlinkString */
|
||||
var parse_HyperlinkString = function(blob, length) {
|
||||
function parse_HyperlinkString(blob, length) {
|
||||
var len = blob.read_shift(4);
|
||||
var o = blob.read_shift(len, 'utf16le').replace(chr0, "");
|
||||
return o;
|
||||
};
|
||||
}
|
||||
|
||||
/* [MS-OSHARED] 2.3.7.1 Hyperlink Object TODO: unify params with XLSX */
|
||||
var parse_Hyperlink = function(blob, length) {
|
||||
function parse_Hyperlink(blob, length) {
|
||||
var end = blob.l + length;
|
||||
var sVer = blob.read_shift(4);
|
||||
if(sVer !== 2) throw new Error("Unrecognized streamVersion: " + sVer);
|
||||
@ -431,7 +437,7 @@ var parse_Hyperlink = function(blob, length) {
|
||||
var target = (targetFrameName||moniker||oleMoniker);
|
||||
if(location) target+="#"+location;
|
||||
return {Target: target};
|
||||
};
|
||||
}
|
||||
|
||||
/* 2.5.178 LongRGBA */
|
||||
function parse_LongRGBA(blob, length) { var r = blob.read_shift(1), g = blob.read_shift(1), b = blob.read_shift(1), a = blob.read_shift(1); return [r,g,b,a]; }
|
||||
|
@ -7,6 +7,13 @@ function parse_XLSCell(blob, length)/*:Cell*/ {
|
||||
var ixfe = blob.read_shift(2);
|
||||
return ({r:rw, c:col, ixfe:ixfe}/*:any*/);
|
||||
}
|
||||
function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:number*/, o) {
|
||||
if(!o) o = new_buf(6);
|
||||
o.write_shift(2, R);
|
||||
o.write_shift(2, C);
|
||||
o.write_shift(2, ixfe||0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.5.134 */
|
||||
function parse_frtHeader(blob) {
|
||||
@ -20,10 +27,6 @@ function parse_frtHeader(blob) {
|
||||
|
||||
function parse_OptXLUnicodeString(blob, length, opts) { return length === 0 ? "" : parse_XLUnicodeString2(blob, length, opts); }
|
||||
|
||||
/* 2.5.158 */
|
||||
//var HIDEOBJENUM = ['SHOWALL', 'SHOWPLACEHOLDER', 'HIDEALL'];
|
||||
var parse_HideObjEnum = parseuint16;
|
||||
|
||||
/* 2.5.344 */
|
||||
function parse_XTI(blob, length, opts) {
|
||||
var w = opts.biff > 8 ? 4 : 2;
|
||||
@ -136,9 +139,6 @@ function parse_FtArray(blob, length, ot) {
|
||||
return fts;
|
||||
}
|
||||
|
||||
/* 2.5.129 */
|
||||
var parse_FontIndex = parseuint16;
|
||||
|
||||
/* --- 2.4 Records --- */
|
||||
|
||||
/* 2.4.21 */
|
||||
@ -157,6 +157,29 @@ function parse_BOF(blob, length) {
|
||||
blob.read_shift(length);
|
||||
return o;
|
||||
}
|
||||
function write_BOF(wb/*:Workbook*/, t/*:number*/, o) {
|
||||
var h = 0x0600, w = 16;
|
||||
switch(o.bookType) {
|
||||
case 'biff8': break;
|
||||
case 'biff5': h = 0x0500; w = 8; break;
|
||||
case 'biff4': h = 0x0004; w = 6; break;
|
||||
case 'biff3': h = 0x0003; w = 6; break;
|
||||
case 'biff2': h = 0x0002; w = 4; break;
|
||||
default: throw new Error("unsupported BIFF version");
|
||||
}
|
||||
var out = new_buf(w);
|
||||
out.write_shift(2, h);
|
||||
out.write_shift(2, t);
|
||||
if(w > 4) out.write_shift(2, 0x7262);
|
||||
if(w > 6) out.write_shift(2, 0x07CD);
|
||||
if(w > 8) {
|
||||
out.write_shift(2, 0xC009);
|
||||
out.write_shift(2, 0x0001);
|
||||
out.write_shift(2, 0x0706);
|
||||
out.write_shift(2, 0x0000);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/* 2.4.146 */
|
||||
@ -177,6 +200,15 @@ function parse_WriteAccess(blob, length, opts) {
|
||||
blob.read_shift(length + l - blob.l);
|
||||
return UserName;
|
||||
}
|
||||
function write_WriteAccess(s/*:string*/, opts) {
|
||||
var o = new_buf(112);
|
||||
o.write_shift(opts.biff == 8 ? 2 : 1, 7);
|
||||
o.write_shift(1, 0);
|
||||
o.write_shift(4, 0x33336853);
|
||||
o.write_shift(4, 0x00534A74);
|
||||
while(o.l < o.length) o.write_shift(1, 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.28 */
|
||||
function parse_BoundSheet8(blob, length, opts) {
|
||||
@ -193,6 +225,16 @@ function parse_BoundSheet8(blob, length, opts) {
|
||||
if(name.length === 0) name = "Sheet1";
|
||||
return { pos:pos, hs:hidden, dt:dt, name:name };
|
||||
}
|
||||
function write_BoundSheet8(data, opts) {
|
||||
var o = new_buf(8 + 2 * data.name.length);
|
||||
o.write_shift(4, data.pos);
|
||||
o.write_shift(1, data.hs || 0);
|
||||
o.write_shift(1, data.dt);
|
||||
o.write_shift(1, data.name.length);
|
||||
o.write_shift(1, 1);
|
||||
o.write_shift(2 * data.name.length, data.name, 'utf16le');
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.265 TODO */
|
||||
function parse_SST(blob, length)/*:SST*/ {
|
||||
@ -243,7 +285,6 @@ function parse_ForceFullCalculation(blob, length) {
|
||||
}
|
||||
|
||||
|
||||
var parse_CompressPictures = parsenoop2; /* 2.4.55 Not interesting */
|
||||
|
||||
|
||||
|
||||
@ -275,6 +316,19 @@ function parse_Window1(blob, length) {
|
||||
return { Pos: [xWn, yWn], Dim: [dxWn, dyWn], Flags: flags, CurTab: iTabCur,
|
||||
FirstTab: iTabFirst, Selected: ctabSel, TabRatio: wTabRatio };
|
||||
}
|
||||
function write_Window1(opts) {
|
||||
var o = new_buf(18);
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(2, 0x7260);
|
||||
o.write_shift(2, 0x44c0);
|
||||
o.write_shift(2, 0x38);
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(2, 0);
|
||||
o.write_shift(2, 1);
|
||||
o.write_shift(2, 0x01f4);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.122 TODO */
|
||||
function parse_Font(blob, length, opts) {
|
||||
@ -307,6 +361,15 @@ function parse_Label(blob, length, opts) {
|
||||
cell.val = str;
|
||||
return cell;
|
||||
}
|
||||
function write_Label(R/*:number*/, C/*:number*/, v/*:string*/, opts) {
|
||||
var o = new_buf(6 + 3 + 2 * v.length);
|
||||
write_XLSCell(R, C, 0, o);
|
||||
o.write_shift(2, v.length);
|
||||
o.write_shift(1, 1);
|
||||
o.write_shift(2 * v.length, v, 'utf16le');
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/* 2.4.126 Number Formats */
|
||||
function parse_Format(blob, length, opts) {
|
||||
@ -325,6 +388,15 @@ function parse_Dimensions(blob, length, opts) {
|
||||
blob.l = end;
|
||||
return {s: {r:r, c:c}, e: {r:R, c:C}};
|
||||
}
|
||||
function write_Dimensions(range, opts) {
|
||||
var o = new_buf(14);
|
||||
o.write_shift(4, range.s.r);
|
||||
o.write_shift(4, range.e.r + 1);
|
||||
o.write_shift(2, range.s.c);
|
||||
o.write_shift(2, range.e.c + 1);
|
||||
o.write_shift(2, 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.220 */
|
||||
function parse_RK(blob, length) {
|
||||
@ -419,6 +491,13 @@ function parse_Guts(blob, length) {
|
||||
if(out[0] > 7 || out[1] > 7) throw new Error("Bad Gutters: " + out.join("|"));
|
||||
return out;
|
||||
}
|
||||
function write_Guts(guts/*:Array<number>*/) {
|
||||
var o = new_buf(8);
|
||||
o.write_shift(4, 0);
|
||||
o.write_shift(2, guts[0] ? guts[0] + 1 : 0);
|
||||
o.write_shift(2, guts[1] ? guts[1] + 1 : 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.24 */
|
||||
function parse_BoolErr(blob, length, opts) {
|
||||
@ -429,6 +508,12 @@ function parse_BoolErr(blob, length, opts) {
|
||||
cell.t = (val === true || val === false) ? 'b' : 'e';
|
||||
return cell;
|
||||
}
|
||||
function write_BoolErr(R/*:number*/, C/*:number*/, v, opts, t/*:string*/) {
|
||||
var o = new_buf(8);
|
||||
write_XLSCell(R, C, 0, o);
|
||||
write_Bes(v, t, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.180 Number */
|
||||
function parse_Number(blob, length) {
|
||||
@ -437,6 +522,12 @@ function parse_Number(blob, length) {
|
||||
cell.val = xnum;
|
||||
return cell;
|
||||
}
|
||||
function write_Number(R/*:number*/, C/*:number*/, v, opts) {
|
||||
var o = new_buf(14);
|
||||
write_XLSCell(R, C, 0, o);
|
||||
write_Xnum(v, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
var parse_XLHeaderFooter = parse_OptXLUnicodeString; // TODO: parse 2.4.136
|
||||
|
||||
@ -530,7 +621,6 @@ function parse_BIFF5ExternSheet(blob, length, opts) {
|
||||
var o = parse_ShortXLUnicodeString(blob, length, opts);
|
||||
return o.charCodeAt(0) == 0x03 ? o.slice(1) : o;
|
||||
}
|
||||
var parse_ExternCount = parseuint16;
|
||||
|
||||
/* 2.4.176 TODO: check older biff */
|
||||
function parse_NameCmt(blob, length, opts) {
|
||||
@ -652,7 +742,7 @@ try {
|
||||
else controlInfo = parse_ControlInfo(blob, 6, opts);
|
||||
var cchText = blob.read_shift(2);
|
||||
var cbRuns = blob.read_shift(2);
|
||||
var ifntEmpty = parse_FontIndex(blob, 2);
|
||||
var ifntEmpty = parseuint16(blob, 2);
|
||||
var len = blob.read_shift(2);
|
||||
blob.l += len;
|
||||
//var fmla = parse_ObjFmla(blob, s + length - blob.l);
|
||||
@ -681,22 +771,22 @@ try {
|
||||
}
|
||||
|
||||
/* 2.4.140 */
|
||||
var parse_HLink = function(blob, length) {
|
||||
function parse_HLink(blob, length) {
|
||||
var ref = parse_Ref8U(blob, 8);
|
||||
blob.l += 16; /* CLSID */
|
||||
var hlink = parse_Hyperlink(blob, length-24);
|
||||
return [ref, hlink];
|
||||
};
|
||||
}
|
||||
|
||||
/* 2.4.141 */
|
||||
var parse_HLinkTooltip = function(blob, length) {
|
||||
function parse_HLinkTooltip(blob, length) {
|
||||
var end = blob.l + length;
|
||||
blob.read_shift(2);
|
||||
var ref = parse_Ref8U(blob, 8);
|
||||
var wzTooltip = blob.read_shift((length-10)/2, 'dbcs-cont');
|
||||
wzTooltip = wzTooltip.replace(chr0,"");
|
||||
return [ref, wzTooltip];
|
||||
};
|
||||
}
|
||||
|
||||
/* 2.4.63 */
|
||||
function parse_Country(blob, length) {
|
||||
@ -705,6 +795,12 @@ function parse_Country(blob, length) {
|
||||
d = blob.read_shift(2); o[1] = CountryEnum[d] || d;
|
||||
return o;
|
||||
}
|
||||
function write_Country(o) {
|
||||
if(!o) o = new_buf(4);
|
||||
o.write_shift(2, 0x01);
|
||||
o.write_shift(2, 0x01);
|
||||
return o;
|
||||
}
|
||||
|
||||
/* 2.4.50 ClrtClient */
|
||||
function parse_ClrtClient(blob, length) {
|
||||
@ -764,315 +860,16 @@ function parse_ShtProps(blob, length, opts) {
|
||||
return def;
|
||||
}
|
||||
|
||||
var parse_Style = parsenoop;
|
||||
var parse_StyleExt = parsenoop;
|
||||
/* 2.4.241 */
|
||||
function write_RRTabId(n/*:number*/) {
|
||||
var out = new_buf(2 * n);
|
||||
for(var i = 0; i < n; ++i) out.write_shift(2, i+1);
|
||||
return out;
|
||||
}
|
||||
|
||||
var parse_Window2 = parsenoop;
|
||||
|
||||
var parse_Backup = parsebool; /* 2.4.14 */
|
||||
var parse_Blank = parse_XLSCell; /* 2.4.20 Just the cell */
|
||||
var parse_BottomMargin = parse_Xnum; /* 2.4.27 */
|
||||
var parse_BuiltInFnGroupCount = parseuint16; /* 2.4.30 0x0E or 0x10 but excel 2011 generates 0x11? */
|
||||
var parse_CalcCount = parseuint16; /* 2.4.31 #Iterations */
|
||||
var parse_CalcDelta = parse_Xnum; /* 2.4.32 */
|
||||
var parse_CalcIter = parsebool; /* 2.4.33 1=iterative calc */
|
||||
var parse_CalcMode = parseuint16; /* 2.4.34 0=manual, 1=auto (def), 2=table */
|
||||
var parse_CalcPrecision = parsebool; /* 2.4.35 */
|
||||
var parse_CalcRefMode = parsenoop2; /* 2.4.36 */
|
||||
var parse_CalcSaveRecalc = parsebool; /* 2.4.37 */
|
||||
var parse_CodePage = parseuint16; /* 2.4.52 */
|
||||
var parse_Compat12 = parsebool; /* 2.4.54 true = no compatibility check */
|
||||
var parse_Date1904 = parsebool; /* 2.4.77 - 1=1904,0=1900 */
|
||||
var parse_DefColWidth = parseuint16; /* 2.4.89 */
|
||||
var parse_DSF = parsenoop2; /* 2.4.94 -- MUST be ignored */
|
||||
var parse_EntExU2 = parsenoop2; /* 2.4.102 -- Explicitly says to ignore */
|
||||
var parse_EOF = parsenoop2; /* 2.4.103 */
|
||||
var parse_Excel9File = parsenoop2; /* 2.4.104 -- Optional and unused */
|
||||
var parse_FeatHdr = parsenoop2; /* 2.4.112 */
|
||||
var parse_FontX = parseuint16; /* 2.4.123 */
|
||||
var parse_Footer = parse_XLHeaderFooter; /* 2.4.124 */
|
||||
var parse_GridSet = parseuint16; /* 2.4.132, =1 */
|
||||
var parse_HCenter = parsebool; /* 2.4.135 sheet centered horizontal on print */
|
||||
var parse_Header = parse_XLHeaderFooter; /* 2.4.136 */
|
||||
var parse_HideObj = parse_HideObjEnum; /* 2.4.139 */
|
||||
var parse_InterfaceEnd = parsenoop2; /* 2.4.145 -- noop */
|
||||
var parse_LeftMargin = parse_Xnum; /* 2.4.151 */
|
||||
var parse_Mms = parsenoop2; /* 2.4.169 -- Explicitly says to ignore */
|
||||
var parse_ObjProtect = parsebool; /* 2.4.183 -- must be 1 if present */
|
||||
var parse_Password = parseuint16; /* 2.4.191 */
|
||||
var parse_PrintGrid = parsebool; /* 2.4.202 */
|
||||
var parse_PrintRowCol = parsebool; /* 2.4.203 */
|
||||
var parse_PrintSize = parseuint16; /* 2.4.204 0:3 */
|
||||
var parse_Prot4Rev = parsebool; /* 2.4.205 */
|
||||
var parse_Prot4RevPass = parseuint16; /* 2.4.206 */
|
||||
var parse_Protect = parsebool; /* 2.4.207 */
|
||||
var parse_RefreshAll = parsebool; /* 2.4.217 -- must be 0 if not template */
|
||||
var parse_RightMargin = parse_Xnum; /* 2.4.219 */
|
||||
var parse_RRTabId = parseuint16a; /* 2.4.241 */
|
||||
var parse_ScenarioProtect = parsebool; /* 2.4.245 */
|
||||
var parse_Scl = parseuint16a; /* 2.4.247 num, den */
|
||||
var parse_String = parse_XLUnicodeString; /* 2.4.268 */
|
||||
var parse_SxBool = parsebool; /* 2.4.274 */
|
||||
var parse_TopMargin = parse_Xnum; /* 2.4.328 */
|
||||
var parse_UsesELFs = parsebool; /* 2.4.337 -- should be 0 */
|
||||
var parse_VCenter = parsebool; /* 2.4.342 */
|
||||
var parse_WinProtect = parsebool; /* 2.4.347 */
|
||||
var parse_WriteProtect = parsenoop; /* 2.4.350 empty record */
|
||||
|
||||
|
||||
/* ---- */
|
||||
var parse_VerticalPageBreaks = parsenoop;
|
||||
var parse_HorizontalPageBreaks = parsenoop;
|
||||
var parse_Selection = parsenoop;
|
||||
var parse_Continue = parsenoop;
|
||||
var parse_Pane = parsenoop;
|
||||
var parse_Pls = parsenoop;
|
||||
var parse_DCon = parsenoop;
|
||||
var parse_DConRef = parsenoop;
|
||||
var parse_DConName = parsenoop;
|
||||
var parse_XCT = parsenoop;
|
||||
var parse_CRN = parsenoop;
|
||||
var parse_FileSharing = parsenoop;
|
||||
var parse_Uncalced = parsenoop;
|
||||
var parse_Template = parsenoop;
|
||||
var parse_Intl = parsenoop;
|
||||
var parse_WsBool = parsenoop;
|
||||
var parse_Sort = parsenoop;
|
||||
var parse_Sync = parsenoop;
|
||||
var parse_LPr = parsenoop;
|
||||
var parse_DxGCol = parsenoop;
|
||||
var parse_FnGroupName = parsenoop;
|
||||
var parse_FilterMode = parsenoop;
|
||||
var parse_AutoFilterInfo = parsenoop;
|
||||
var parse_AutoFilter = parsenoop;
|
||||
var parse_ScenMan = parsenoop;
|
||||
var parse_SCENARIO = parsenoop;
|
||||
var parse_SxView = parsenoop;
|
||||
var parse_Sxvd = parsenoop;
|
||||
var parse_SXVI = parsenoop;
|
||||
var parse_SxIvd = parsenoop;
|
||||
var parse_SXLI = parsenoop;
|
||||
var parse_SXPI = parsenoop;
|
||||
var parse_DocRoute = parsenoop;
|
||||
var parse_RecipName = parsenoop;
|
||||
var parse_SXDI = parsenoop;
|
||||
var parse_SXDB = parsenoop;
|
||||
var parse_SXFDB = parsenoop;
|
||||
var parse_SXDBB = parsenoop;
|
||||
var parse_SXNum = parsenoop;
|
||||
var parse_SxErr = parsenoop;
|
||||
var parse_SXInt = parsenoop;
|
||||
var parse_SXString = parsenoop;
|
||||
var parse_SXDtr = parsenoop;
|
||||
var parse_SxNil = parsenoop;
|
||||
var parse_SXTbl = parsenoop;
|
||||
var parse_SXTBRGIITM = parsenoop;
|
||||
var parse_SxTbpg = parsenoop;
|
||||
var parse_ObProj = parsenoop;
|
||||
var parse_SXStreamID = parsenoop;
|
||||
var parse_DBCell = parsenoop;
|
||||
var parse_SXRng = parsenoop;
|
||||
var parse_SxIsxoper = parsenoop;
|
||||
var parse_BookBool = parsenoop;
|
||||
var parse_DbOrParamQry = parsenoop;
|
||||
var parse_OleObjectSize = parsenoop;
|
||||
var parse_SXVS = parsenoop;
|
||||
var parse_BkHim = parsenoop;
|
||||
var parse_MsoDrawingGroup = parsenoop;
|
||||
var parse_MsoDrawing = parsenoop;
|
||||
var parse_MsoDrawingSelection = parsenoop;
|
||||
var parse_PhoneticInfo = parsenoop;
|
||||
var parse_SxRule = parsenoop;
|
||||
var parse_SXEx = parsenoop;
|
||||
var parse_SxFilt = parsenoop;
|
||||
var parse_SxDXF = parsenoop;
|
||||
var parse_SxItm = parsenoop;
|
||||
var parse_SxName = parsenoop;
|
||||
var parse_SxSelect = parsenoop;
|
||||
var parse_SXPair = parsenoop;
|
||||
var parse_SxFmla = parsenoop;
|
||||
var parse_SxFormat = parsenoop;
|
||||
var parse_SXVDEx = parsenoop;
|
||||
var parse_SXFormula = parsenoop;
|
||||
var parse_SXDBEx = parsenoop;
|
||||
var parse_RRDInsDel = parsenoop;
|
||||
var parse_RRDHead = parsenoop;
|
||||
var parse_RRDChgCell = parsenoop;
|
||||
var parse_RRDRenSheet = parsenoop;
|
||||
var parse_RRSort = parsenoop;
|
||||
var parse_RRDMove = parsenoop;
|
||||
var parse_RRFormat = parsenoop;
|
||||
var parse_RRAutoFmt = parsenoop;
|
||||
var parse_RRInsertSh = parsenoop;
|
||||
var parse_RRDMoveBegin = parsenoop;
|
||||
var parse_RRDMoveEnd = parsenoop;
|
||||
var parse_RRDInsDelBegin = parsenoop;
|
||||
var parse_RRDInsDelEnd = parsenoop;
|
||||
var parse_RRDConflict = parsenoop;
|
||||
var parse_RRDDefName = parsenoop;
|
||||
var parse_RRDRstEtxp = parsenoop;
|
||||
var parse_LRng = parsenoop;
|
||||
var parse_CUsr = parsenoop;
|
||||
var parse_CbUsr = parsenoop;
|
||||
var parse_UsrInfo = parsenoop;
|
||||
var parse_UsrExcl = parsenoop;
|
||||
var parse_FileLock = parsenoop;
|
||||
var parse_RRDInfo = parsenoop;
|
||||
var parse_BCUsrs = parsenoop;
|
||||
var parse_UsrChk = parsenoop;
|
||||
var parse_UserBView = parsenoop;
|
||||
var parse_UserSViewBegin = parsenoop; // overloaded
|
||||
var parse_UserSViewEnd = parsenoop;
|
||||
var parse_RRDUserView = parsenoop;
|
||||
var parse_Qsi = parsenoop;
|
||||
var parse_CondFmt = parsenoop;
|
||||
var parse_CF = parsenoop;
|
||||
var parse_DVal = parsenoop;
|
||||
var parse_DConBin = parsenoop;
|
||||
var parse_Lel = parsenoop;
|
||||
var parse_XLSCodeName = parse_XLUnicodeString;
|
||||
var parse_SXFDBType = parsenoop;
|
||||
var parse_ObNoMacros = parsenoop;
|
||||
var parse_Dv = parsenoop;
|
||||
var parse_Index = parsenoop;
|
||||
var parse_Table = parsenoop;
|
||||
var parse_BigName = parsenoop;
|
||||
var parse_ContinueBigName = parsenoop;
|
||||
var parse_WebPub = parsenoop;
|
||||
var parse_QsiSXTag = parsenoop;
|
||||
var parse_DBQueryExt = parsenoop;
|
||||
var parse_ExtString = parsenoop;
|
||||
var parse_TxtQry = parsenoop;
|
||||
var parse_Qsir = parsenoop;
|
||||
var parse_Qsif = parsenoop;
|
||||
var parse_RRDTQSIF = parsenoop;
|
||||
var parse_OleDbConn = parsenoop;
|
||||
var parse_WOpt = parsenoop;
|
||||
var parse_SXViewEx = parsenoop;
|
||||
var parse_SXTH = parsenoop;
|
||||
var parse_SXPIEx = parsenoop;
|
||||
var parse_SXVDTEx = parsenoop;
|
||||
var parse_SXViewEx9 = parsenoop;
|
||||
var parse_ContinueFrt = parsenoop;
|
||||
var parse_RealTimeData = parsenoop;
|
||||
var parse_ChartFrtInfo = parsenoop;
|
||||
var parse_FrtWrapper = parsenoop;
|
||||
var parse_StartBlock = parsenoop;
|
||||
var parse_EndBlock = parsenoop;
|
||||
var parse_StartObject = parsenoop;
|
||||
var parse_EndObject = parsenoop;
|
||||
var parse_CatLab = parsenoop;
|
||||
var parse_YMult = parsenoop;
|
||||
var parse_SXViewLink = parsenoop;
|
||||
var parse_PivotChartBits = parsenoop;
|
||||
var parse_FrtFontList = parsenoop;
|
||||
var parse_SheetExt = parsenoop;
|
||||
var parse_BookExt = parsenoop;
|
||||
var parse_SXAddl = parsenoop;
|
||||
var parse_CrErr = parsenoop;
|
||||
var parse_HFPicture = parsenoop;
|
||||
var parse_Feat = parsenoop;
|
||||
var parse_DataLabExt = parsenoop;
|
||||
var parse_DataLabExtContents = parsenoop;
|
||||
var parse_CellWatch = parsenoop;
|
||||
var parse_FeatHdr11 = parsenoop;
|
||||
var parse_Feature11 = parsenoop;
|
||||
var parse_DropDownObjIds = parsenoop;
|
||||
var parse_ContinueFrt11 = parsenoop;
|
||||
var parse_DConn = parsenoop;
|
||||
var parse_List12 = parsenoop;
|
||||
var parse_Feature12 = parsenoop;
|
||||
var parse_CondFmt12 = parsenoop;
|
||||
var parse_CF12 = parsenoop;
|
||||
var parse_CFEx = parsenoop;
|
||||
var parse_AutoFilter12 = parsenoop;
|
||||
var parse_ContinueFrt12 = parsenoop;
|
||||
var parse_MDTInfo = parsenoop;
|
||||
var parse_MDXStr = parsenoop;
|
||||
var parse_MDXTuple = parsenoop;
|
||||
var parse_MDXSet = parsenoop;
|
||||
var parse_MDXProp = parsenoop;
|
||||
var parse_MDXKPI = parsenoop;
|
||||
var parse_MDB = parsenoop;
|
||||
var parse_PLV = parsenoop;
|
||||
var parse_DXF = parsenoop;
|
||||
var parse_TableStyles = parsenoop;
|
||||
var parse_TableStyle = parsenoop;
|
||||
var parse_TableStyleElement = parsenoop;
|
||||
var parse_NamePublish = parsenoop;
|
||||
var parse_SortData = parsenoop;
|
||||
var parse_GUIDTypeLib = parsenoop;
|
||||
var parse_FnGrp12 = parsenoop;
|
||||
var parse_NameFnGrp12 = parsenoop;
|
||||
var parse_HeaderFooter = parsenoop;
|
||||
var parse_CrtLayout12 = parsenoop;
|
||||
var parse_CrtMlFrt = parsenoop;
|
||||
var parse_CrtMlFrtContinue = parsenoop;
|
||||
var parse_ShapePropsStream = parsenoop;
|
||||
var parse_TextPropsStream = parsenoop;
|
||||
var parse_RichTextStream = parsenoop;
|
||||
var parse_CrtLayout12A = parsenoop;
|
||||
var parse_Units = parsenoop;
|
||||
var parse_Chart = parsenoop;
|
||||
var parse_Series = parsenoop;
|
||||
var parse_DataFormat = parsenoop;
|
||||
var parse_LineFormat = parsenoop;
|
||||
var parse_MarkerFormat = parsenoop;
|
||||
var parse_AreaFormat = parsenoop;
|
||||
var parse_PieFormat = parsenoop;
|
||||
var parse_AttachedLabel = parsenoop;
|
||||
var parse_SeriesText = parsenoop;
|
||||
var parse_ChartFormat = parsenoop;
|
||||
var parse_Legend = parsenoop;
|
||||
var parse_SeriesList = parsenoop;
|
||||
var parse_Bar = parsenoop;
|
||||
var parse_Line = parsenoop;
|
||||
var parse_Pie = parsenoop;
|
||||
var parse_Area = parsenoop;
|
||||
var parse_Scatter = parsenoop;
|
||||
var parse_CrtLine = parsenoop;
|
||||
var parse_Axis = parsenoop;
|
||||
var parse_Tick = parsenoop;
|
||||
var parse_ValueRange = parsenoop;
|
||||
var parse_CatSerRange = parsenoop;
|
||||
var parse_AxisLine = parsenoop;
|
||||
var parse_CrtLink = parsenoop;
|
||||
var parse_DefaultText = parsenoop;
|
||||
var parse_Text = parsenoop;
|
||||
var parse_ObjectLink = parsenoop;
|
||||
var parse_Frame = parsenoop;
|
||||
var parse_Begin = parsenoop;
|
||||
var parse_End = parsenoop;
|
||||
var parse_PlotArea = parsenoop;
|
||||
var parse_Chart3d = parsenoop;
|
||||
var parse_PicF = parsenoop;
|
||||
var parse_DropBar = parsenoop;
|
||||
var parse_Radar = parsenoop;
|
||||
var parse_Surf = parsenoop;
|
||||
var parse_RadarArea = parsenoop;
|
||||
var parse_AxisParent = parsenoop;
|
||||
var parse_LegendException = parsenoop;
|
||||
var parse_SerToCrt = parsenoop;
|
||||
var parse_AxesUsed = parsenoop;
|
||||
var parse_SBaseRef = parsenoop;
|
||||
var parse_SerParent = parsenoop;
|
||||
var parse_SerAuxTrend = parsenoop;
|
||||
var parse_IFmtRecord = parsenoop;
|
||||
var parse_Pos = parsenoop;
|
||||
var parse_AlRuns = parsenoop;
|
||||
var parse_BRAI = parsenoop;
|
||||
var parse_SerAuxErrBar = parsenoop;
|
||||
var parse_SerFmt = parsenoop;
|
||||
var parse_Chart3DBarShape = parsenoop;
|
||||
var parse_Fbi = parsenoop;
|
||||
var parse_BopPop = parsenoop;
|
||||
var parse_AxcExt = parsenoop;
|
||||
var parse_Dat = parsenoop;
|
||||
var parse_PlotGrowth = parsenoop;
|
||||
var parse_SIIndex = parsenoop;
|
||||
var parse_GelFrame = parsenoop;
|
||||
var parse_BopPopCustom = parsenoop;
|
||||
var parse_Fbi2 = parsenoop;
|
||||
|
||||
/* --- Specific to versions before BIFF8 --- */
|
||||
function parse_ImData(blob, length, opts) {
|
||||
@ -1108,6 +905,12 @@ function parse_BIFF2NUM(blob, length, opts) {
|
||||
cell.val = num;
|
||||
return cell;
|
||||
}
|
||||
function write_BIFF2NUM(r/*:number*/, c/*:number*/, val/*:number*/) {
|
||||
var out = new_buf(15);
|
||||
write_BIFF2Cell(out, r, c);
|
||||
out.write_shift(8, val, 'f');
|
||||
return out;
|
||||
}
|
||||
|
||||
function parse_BIFF2INT(blob, length) {
|
||||
var cell = parse_XLSCell(blob, 6);
|
||||
@ -1117,6 +920,12 @@ function parse_BIFF2INT(blob, length) {
|
||||
cell.val = num;
|
||||
return cell;
|
||||
}
|
||||
function write_BIFF2INT(r/*:number*/, c/*:number*/, val/*:number*/) {
|
||||
var out = new_buf(9);
|
||||
write_BIFF2Cell(out, r, c);
|
||||
out.write_shift(2, val);
|
||||
return out;
|
||||
}
|
||||
|
||||
function parse_BIFF2STRING(blob, length) {
|
||||
var cch = blob.read_shift(1);
|
||||
|
@ -172,14 +172,14 @@ function parse_si(x, opts) {
|
||||
/* 18.4.12 t ST_Xstring (Plaintext String) */
|
||||
// TODO: is whitespace actually valid here?
|
||||
if(x.match(/^\s*<(?:\w+:)?t[^>]*>/)) {
|
||||
z.t = utf8read(unescapexml(x.substr(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]));
|
||||
z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""));
|
||||
z.r = utf8read(x);
|
||||
if(html) z.h = escapehtml(z.t);
|
||||
}
|
||||
/* 18.4.4 r CT_RElt (Rich Text Run) */
|
||||
else if((y = x.match(sirregex))) {
|
||||
z.r = utf8read(x);
|
||||
z.t = utf8read(unescapexml((x.replace(sirphregex, '').match(sitregex)||[]).join("").replace(tagregex,"")));
|
||||
z.t = unescapexml(utf8read((x.replace(sirphregex, '').match(sitregex)||[]).join("").replace(tagregex,"")));
|
||||
if(html) z.h = parse_rs(z.r);
|
||||
}
|
||||
/* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
|
||||
|
@ -16,7 +16,7 @@ function parse_comments_xml(data/*:string*/, opts)/*:Array<Comment>*/ {
|
||||
var cm = x.match(/<(?:\w+:)?comment[^>]*>/);
|
||||
if(!cm) return;
|
||||
var y = parsexmltag(cm[0]);
|
||||
var comment/*:Comment*/ = ({ author: y.authorId && authors[y.authorId] ? authors[y.authorId] : "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
|
||||
var comment/*:Comment*/ = ({ author: y.authorId && authors[y.authorId] || "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
|
||||
var cell = decode_cell(y.ref);
|
||||
if(opts.sheetRows && opts.sheetRows <= cell.r) return;
|
||||
var textMatch = x.match(/<(?:\w+:)?text>([\s\S]*)<\/(?:\w+:)?text>/);
|
||||
|
@ -21,7 +21,7 @@ function write_BrtBeginComment(data, o) {
|
||||
|
||||
/* [MS-XLSB] 2.4.324 BrtCommentAuthor */
|
||||
var parse_BrtCommentAuthor = parse_XLWideString;
|
||||
function write_BrtCommentAuthor(data) { return write_XLWideString(data.substr(0, 54)); }
|
||||
function write_BrtCommentAuthor(data) { return write_XLWideString(data.slice(0, 54)); }
|
||||
|
||||
/* [MS-XLSB] 2.1.7.8 Comments */
|
||||
function parse_comments_bin(data, opts) {
|
||||
@ -72,7 +72,7 @@ function write_comments_bin(data, opts) {
|
||||
data.forEach(function(comment) {
|
||||
comment[1].forEach(function(c) {
|
||||
if(iauthor.indexOf(c.a) > -1) return;
|
||||
iauthor.push(c.a.substr(0,54));
|
||||
iauthor.push(c.a.slice(0,54));
|
||||
write_record(ba, "BrtCommentAuthor", write_BrtCommentAuthor(c.a));
|
||||
});
|
||||
});
|
||||
|
@ -329,14 +329,16 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
out = ((options.dense ? [] : {})/*:any*/);
|
||||
} break;
|
||||
case 'BOF': {
|
||||
if(opts.biff !== 8){/* empty */}
|
||||
else if(RecordType === 0x0009) opts.biff = 2;
|
||||
else if(RecordType === 0x0209) opts.biff = 3;
|
||||
else if(RecordType === 0x0409) opts.biff = 4;
|
||||
else if(val.BIFFVer === 0x0500) opts.biff = 5;
|
||||
else if(val.BIFFVer === 0x0600) opts.biff = 8;
|
||||
else if(val.BIFFVer === 0x0002) opts.biff = 2;
|
||||
else if(val.BIFFVer === 0x0007) opts.biff = 2;
|
||||
if(opts.biff === 8) switch(RecordType) {
|
||||
case 0x0009: opts.biff = 2; break;
|
||||
case 0x0209: opts.biff = 3; break;
|
||||
case 0x0409: opts.biff = 4; break;
|
||||
default: switch(val.BIFFVer) {
|
||||
case 0x0500: opts.biff = 5; break;
|
||||
case 0x0600: opts.biff = 8; break;
|
||||
case 0x0002: opts.biff = 2; break;
|
||||
case 0x0007: opts.biff = 2; break;
|
||||
}}
|
||||
if(file_depth++) break;
|
||||
cell_valid = true;
|
||||
out = ((options.dense ? [] : {})/*:any*/);
|
||||
@ -692,7 +694,8 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
/* Explicitly Ignored */
|
||||
case 'Excel9File': break;
|
||||
case 'Units': break;
|
||||
case 'InterfaceHdr': case 'Mms': case 'InterfaceEnd': case 'DSF': case 'BuiltInFnGroupCount': break;
|
||||
case 'InterfaceHdr': case 'Mms': case 'InterfaceEnd': case 'DSF': break;
|
||||
case 'BuiltInFnGroupCount': /* 2.4.30 0x0E or 0x10 but excel 2011 generates 0x11? */ break;
|
||||
/* View Stuff */
|
||||
case 'Window1': case 'Window2': case 'HideObj': case 'GridSet': case 'Guts':
|
||||
case 'UserBView': case 'UserSViewBegin': case 'UserSViewEnd':
|
||||
@ -791,6 +794,9 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
|
||||
case 'ListObj': case 'ListField': break;
|
||||
case 'RRSort': break;
|
||||
case 'BigName': break;
|
||||
case 'ToolbarHdr': case 'ToolbarEnd': break;
|
||||
case 'DDEObjName': break;
|
||||
case 'FRTArchId$': break;
|
||||
default: if(options.WTF) throw 'Unrecognized Record ' + R.n;
|
||||
}}}}
|
||||
} else blob.l += length;
|
||||
@ -842,7 +848,6 @@ if(cfb.FullPaths) {
|
||||
prep_blob(cfb, 0);
|
||||
WB = ({content: cfb}/*:any*/);
|
||||
}
|
||||
|
||||
if(!WB) WB = CFB.find(cfb, '/Book');
|
||||
var CompObjP, SummaryP, WorkbookP/*:Workbook*/;
|
||||
|
||||
@ -869,3 +874,19 @@ if(options.bookFiles) WorkbookP.cfb = cfb;
|
||||
return WorkbookP;
|
||||
}
|
||||
|
||||
|
||||
function write_xlscfb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:CFBContainer*/ {
|
||||
var o = opts || {};
|
||||
var cfb = CFB.utils.cfb_new({root:"R"});
|
||||
var wbpath = "/Workbook";
|
||||
switch(o.bookType || "xls") {
|
||||
case "xls": o.bookType = "biff8";
|
||||
/* falls through */
|
||||
case "biff8": wbpath = "/Workbook"; o.biff = 8; break;
|
||||
case "biff5": wbpath = "/Book"; o.biff = 5; break;
|
||||
default: throw new Error("invalid type " + o.bookType + " for XLS CFB");
|
||||
}
|
||||
CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
|
||||
// TODO: SI, DSI, CO
|
||||
return cfb;
|
||||
}
|
||||
|
2260
bits/77_parsetab.js
2260
bits/77_parsetab.js
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,13 @@
|
||||
/* BIFF2-4 single-sheet workbooks */
|
||||
function write_biff_rec(ba/*:BufArray*/, t/*:number*/, payload, length/*:?number*/) {
|
||||
var len = (length || (payload||[]).length);
|
||||
function write_biff_rec(ba/*:BufArray*/, type/*:number|string*/, payload, length/*:?number*/) {
|
||||
var t/*:number*/ = +type || +XLSRE[type];
|
||||
if(isNaN(t)) return;
|
||||
var len = length || (payload||[]).length || 0;
|
||||
var o = ba.next(4 + len);
|
||||
o.write_shift(2, t);
|
||||
o.write_shift(2, len);
|
||||
if(/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload);
|
||||
}
|
||||
|
||||
function write_BOF(wb/*:Workbook*/, o) {
|
||||
if(o.bookType != 'biff2') throw "unsupported BIFF version";
|
||||
var out = new_buf(4);
|
||||
out.write_shift(2, 0x0002); // "unused"
|
||||
out.write_shift(2, 0x0010); // Sheet
|
||||
return out;
|
||||
}
|
||||
|
||||
function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) {
|
||||
if(!out) out = new_buf(7);
|
||||
out.write_shift(2, r);
|
||||
@ -25,20 +18,6 @@ function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) {
|
||||
return out;
|
||||
}
|
||||
|
||||
function write_BIFF2INT(r/*:number*/, c/*:number*/, val/*:number*/) {
|
||||
var out = new_buf(9);
|
||||
write_BIFF2Cell(out, r, c);
|
||||
out.write_shift(2, val);
|
||||
return out;
|
||||
}
|
||||
|
||||
function write_BIFF2NUMBER(r/*:number*/, c/*:number*/, val/*:number*/) {
|
||||
var out = new_buf(15);
|
||||
write_BIFF2Cell(out, r, c);
|
||||
out.write_shift(8, val, 'f');
|
||||
return out;
|
||||
}
|
||||
|
||||
function write_BIFF2BERR(r/*:number*/, c/*:number*/, val, t/*:?string*/) {
|
||||
var out = new_buf(9);
|
||||
write_BIFF2Cell(out, r, c);
|
||||
@ -56,14 +35,14 @@ function write_BIFF2LABEL(r/*:number*/, c/*:number*/, val) {
|
||||
return out.l < out.length ? out.slice(0, out.l) : out;
|
||||
}
|
||||
|
||||
function write_ws_biff_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
|
||||
function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
|
||||
if(cell.v != null) switch(cell.t) {
|
||||
case 'd': case 'n':
|
||||
var v = cell.t == 'd' ? datenum(cell.v) : cell.v;
|
||||
if((v == (v|0)) && (v >= 0) && (v < 65536))
|
||||
write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, v));
|
||||
else
|
||||
write_biff_rec(ba, 0x0003, write_BIFF2NUMBER(R,C, v));
|
||||
write_biff_rec(ba, 0x0003, write_BIFF2NUM(R,C, v));
|
||||
return;
|
||||
case 'b': case 'e': write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, cell.v, cell.t)); return;
|
||||
/* TODO: codepage, sst */
|
||||
@ -74,7 +53,7 @@ function write_ws_biff_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:nu
|
||||
write_biff_rec(ba, 0x0001, write_BIFF2Cell(null, R, C));
|
||||
}
|
||||
|
||||
function write_biff_ws(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
var dense = Array.isArray(ws);
|
||||
var range = safe_decode_range(ws['!ref'] || "A1"), ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
@ -85,24 +64,155 @@ function write_biff_ws(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts,
|
||||
var cell = dense ? (ws[R]||[])[C] : ws[ref];
|
||||
if(!cell) continue;
|
||||
/* write cell */
|
||||
write_ws_biff_cell(ba, cell, R, C, opts);
|
||||
write_ws_biff2_cell(ba, cell, R, C, opts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Based on test files */
|
||||
function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
var o = opts || {};
|
||||
if(DENSE != null && o.dense == null) o.dense = DENSE;
|
||||
var ba = buf_array();
|
||||
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);
|
||||
write_biff_rec(ba, 0x0009, write_BOF(wb, o));
|
||||
write_biff_rec(ba, 0x0009, write_BOF(wb, 0x10, o));
|
||||
/* ... */
|
||||
write_biff_ws(ba, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
|
||||
write_ws_biff2(ba, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
|
||||
/* ... */
|
||||
write_biff_rec(ba, 0x000a);
|
||||
// TODO
|
||||
write_biff_rec(ba, 0x000A);
|
||||
return ba.end();
|
||||
}
|
||||
|
||||
function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
|
||||
if(cell.v != null) switch(cell.t) {
|
||||
case 'd': case 'n':
|
||||
var v = cell.t == 'd' ? datenum(cell.v) : cell.v;
|
||||
/* TODO: emit RK as appropriate */
|
||||
write_biff_rec(ba, "Number", write_Number(R, C, v, opts));
|
||||
return;
|
||||
case 'b': case 'e': write_biff_rec(ba, "BoolErr", write_BoolErr(R, C, cell.v, opts, cell.t)); return;
|
||||
/* TODO: codepage, sst */
|
||||
case 's': case 'str':
|
||||
write_biff_rec(ba, "Label", write_Label(R, C, cell.v, opts));
|
||||
return;
|
||||
}
|
||||
write_biff_rec(ba, "Blank", write_XLSCell(R, C));
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.1.7.20.5 */
|
||||
function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
|
||||
var ba = buf_array();
|
||||
var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
|
||||
var dense = Array.isArray(ws);
|
||||
var ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
|
||||
var range = safe_decode_range(ws['!ref'] || "A1");
|
||||
write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "CalcMode", writeuint16(1));
|
||||
write_biff_rec(ba, "CalcCount", writeuint16(100));
|
||||
write_biff_rec(ba, "CalcRefMode", writebool(true));
|
||||
write_biff_rec(ba, "CalcIter", writebool(false));
|
||||
write_biff_rec(ba, "CalcDelta", write_Xnum(0.001));
|
||||
write_biff_rec(ba, "CalcSaveRecalc", writebool(true));
|
||||
write_biff_rec(ba, "PrintRowCol", writebool(false));
|
||||
write_biff_rec(ba, "PrintGrid", writebool(false));
|
||||
write_biff_rec(ba, "GridSet", writeuint16(1));
|
||||
write_biff_rec(ba, "Guts", write_Guts([0,0]));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "HCenter", writebool(false));
|
||||
write_biff_rec(ba, "VCenter", writebool(false));
|
||||
/* ... */
|
||||
write_biff_rec(ba, "Dimensions", write_Dimensions(range, opts));
|
||||
/* ... */
|
||||
|
||||
for(var R = range.s.r; R <= range.e.r; ++R) {
|
||||
rr = encode_row(R);
|
||||
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];
|
||||
if(!cell) continue;
|
||||
/* write cell */
|
||||
write_ws_biff8_cell(ba, cell, R, C, opts);
|
||||
}
|
||||
}
|
||||
/* ... */
|
||||
write_biff_rec(ba, "EOF");
|
||||
return ba.end();
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.1.7.20.3 */
|
||||
function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) {
|
||||
var A = buf_array();
|
||||
var b8 = opts.biff == 8, b5 = opts.biff == 5;
|
||||
write_biff_rec(A, 0x0809, write_BOF(wb, 0x05, opts));
|
||||
write_biff_rec(A, "InterfaceHdr", writeuint16(0x04b0));
|
||||
write_biff_rec(A, "Mms", writezeroes(2));
|
||||
if(b5) write_biff_rec(A, "ToolbarHdr");
|
||||
if(b5) write_biff_rec(A, "ToolbarEnd");
|
||||
write_biff_rec(A, "InterfaceEnd");
|
||||
write_biff_rec(A, "WriteAccess", write_WriteAccess("SheetJS", opts));
|
||||
write_biff_rec(A, "CodePage", writeuint16(0x04b0));
|
||||
if(b8) write_biff_rec(A, "DSF", writeuint16(0));
|
||||
if(b8) write_biff_rec(A, "RRTabId", write_RRTabId(wb.SheetNames.length));
|
||||
if(b8) write_biff_rec(A, "BuiltInFnGroupCount", writeuint16(0x11));
|
||||
write_biff_rec(A, "WinProtect", writebool(false));
|
||||
write_biff_rec(A, "Protect", writebool(false));
|
||||
write_biff_rec(A, "Password", writeuint16(0));
|
||||
if(b8) write_biff_rec(A, "Prot4Rev", writebool(false));
|
||||
if(b8) write_biff_rec(A, "Prot4RevPass", writeuint16(0));
|
||||
write_biff_rec(A, "Window1", write_Window1(opts));
|
||||
write_biff_rec(A, "Backup", writebool(false));
|
||||
write_biff_rec(A, "HideObj", writeuint16(0));
|
||||
write_biff_rec(A, "Date1904", writebool(safe1904(wb)=="true"));
|
||||
write_biff_rec(A, "CalcPrecision", writebool(true));
|
||||
write_biff_rec(A, "RefreshAll", writebool(false));
|
||||
write_biff_rec(A, "BookBool", writeuint16(0));
|
||||
/* ... */
|
||||
write_biff_rec(A, "UsesELFs", writebool(false));
|
||||
var a = A.end();
|
||||
|
||||
var C = buf_array();
|
||||
write_biff_rec(C, "Country", write_Country());
|
||||
/* BIFF8: [SST *Continue] ExtSST */
|
||||
write_biff_rec(C, "EOF");
|
||||
var c = C.end();
|
||||
|
||||
var B = buf_array();
|
||||
var blen = 0, j = 0;
|
||||
for(j = 0; j < wb.SheetNames.length; ++j) blen += 12 + (b8 ? 2 : 1) * wb.SheetNames[j].length;
|
||||
var start = a.length + blen + c.length;
|
||||
for(j = 0; j < wb.SheetNames.length; ++j) {
|
||||
write_biff_rec(B, "BoundSheet8", write_BoundSheet8({pos:start, hs:0, dt:0, name:wb.SheetNames[j]}, opts));
|
||||
start += bufs[j].length;
|
||||
}
|
||||
/* 1*BoundSheet8 */
|
||||
var b = B.end();
|
||||
if(blen != b.length) throw new Error("BS8 " + blen + " != " + b.length);
|
||||
|
||||
var out = [];
|
||||
if(a.length) out.push(a);
|
||||
if(b.length) out.push(b);
|
||||
if(c.length) out.push(c);
|
||||
return __toBuffer([out]);
|
||||
}
|
||||
|
||||
/* [MS-XLS] 2.1.7.20 Workbook Stream */
|
||||
function write_biff8_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
var o = opts || {};
|
||||
var bufs = [];
|
||||
for(var i = 0; i < wb.SheetNames.length; ++i) bufs[bufs.length] = write_ws_biff8(i, o, wb);
|
||||
bufs.unshift(write_biff8_global(wb, bufs, o));
|
||||
return __toBuffer([bufs]);
|
||||
}
|
||||
|
||||
function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
|
||||
var o = opts || {};
|
||||
switch(o.biff || 2) {
|
||||
case 8: case 5: return write_biff8_buf(wb, opts);
|
||||
case 4: case 3: case 2: return write_biff2_buf(wb, opts);
|
||||
}
|
||||
throw new Error("invalid type " + o.bookType + " for BIFF");
|
||||
}
|
||||
|
@ -14,6 +14,18 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
function write_cfb_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
var o = opts||{};
|
||||
var cfb/*:CFBContainer*/ = write_xlscfb(wb, o);
|
||||
switch(o.type) {
|
||||
case "base64": case "binary": break;
|
||||
case "buffer": case "array": o.type = ""; break;
|
||||
case "file": return _fs.writeFileSync(o.file, CFB.write(cfb, {type:'buffer'}));
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
return CFB.write(cfb, o);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
function write_bstr_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
@ -71,7 +83,12 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
case 'prn': return write_string_type(write_prn_str(wb, o), o);
|
||||
case 'rtf': return write_string_type(write_rtf_str(wb, o), o);
|
||||
case 'fods': return write_string_type(write_ods(wb, o), o);
|
||||
case 'biff2': return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff2': if(!o.biff) o.biff = 2; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff3': if(!o.biff) o.biff = 3; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff4': if(!o.biff) o.biff = 4; return write_binary_type(write_biff_buf(wb, o), o);
|
||||
case 'biff5': if(!o.biff) o.biff = 5; return write_cfb_type(wb, o);
|
||||
case 'biff8':
|
||||
case 'xls': if(!o.biff) o.biff = 8; return write_cfb_type(wb, o);
|
||||
case 'xlsx':
|
||||
case 'xlsm':
|
||||
case 'xlsb':
|
||||
@ -89,7 +106,7 @@ function resolve_book_type(o/*?WriteFileOpts*/) {
|
||||
case '.xlml': o.bookType = 'xlml'; break;
|
||||
case '.sylk': o.bookType = 'sylk'; break;
|
||||
case '.html': o.bookType = 'html'; break;
|
||||
case '.xls': o.bookType = 'biff2'; break;
|
||||
case '.xls': o.bookType = 'biff8'; break;
|
||||
case '.xml': o.bookType = 'xml'; break;
|
||||
case '.ods': o.bookType = 'ods'; break;
|
||||
case '.csv': o.bookType = 'csv'; break;
|
||||
|
@ -43,7 +43,9 @@ the module can be omitted by aliasing the dependency:
|
||||
|
||||
## Bower and minified versions
|
||||
|
||||
The minified versions, used in Bower, require `module.noParse` configuration:
|
||||
Webpack may show a message like "This seems to be a pre-built javascript file"
|
||||
when processing minified files (like the default Bower script). The message is
|
||||
harmless. To suppress the message, set `module.noParse` in the webpack config:
|
||||
|
||||
```js
|
||||
module: {
|
||||
|
28
dist/xlsx.core.min.js
vendored
28
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
3424
dist/xlsx.js
vendored
3424
dist/xlsx.js
vendored
File diff suppressed because it is too large
Load Diff
23
dist/xlsx.min.js
vendored
23
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
@ -35,7 +35,8 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `xlsx` | `.xlsx` | ZIP | multi | Excel 2007+ XML Format |
|
||||
| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet format |
|
||||
| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet |
|
||||
|
@ -8,7 +8,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | :o: | :o: |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | :o: | :o: |
|
||||
| Excel 2003-2004 XML Format (XML "SpreadsheetML") | :o: | :o: |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | :o: |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | |
|
||||
| Excel 4.0 (XLS/XLW BIFF4) | :o: | |
|
||||
| Excel 3.0 (XLS BIFF3) | :o: | |
|
||||
|
@ -40,6 +40,7 @@ digraph G {
|
||||
csf -> xlml
|
||||
xlml -> csf
|
||||
xls5 -> csf
|
||||
csf -> xls8
|
||||
xls8 -> csf
|
||||
ods -> csf
|
||||
csf -> ods
|
||||
|
BIN
formats.png
BIN
formats.png
Binary file not shown.
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 170 KiB |
@ -54,7 +54,6 @@ Use readAsBinaryString: (when available) <input type="checkbox" name="userabs" c
|
||||
<script>
|
||||
/*jshint browser:true */
|
||||
/* eslint-env browser */
|
||||
/* eslint no-use-before-define:0 */
|
||||
/*global Uint8Array, Uint16Array, ArrayBuffer */
|
||||
/*global XLSX */
|
||||
var X = XLSX;
|
||||
@ -215,6 +214,7 @@ var do_file = (function() {
|
||||
})();
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
/* eslint no-use-before-define:0 */
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-36810333-1']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
@ -1444,7 +1444,8 @@ output formats. The specific file type is controlled with `bookType` option:
|
||||
| `xlsx` | `.xlsx` | ZIP | multi | Excel 2007+ XML Format |
|
||||
| `xlsm` | `.xlsm` | ZIP | multi | Excel 2007+ Macro XML Format |
|
||||
| `xlsb` | `.xlsb` | ZIP | multi | Excel 2007+ Binary Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet format |
|
||||
| `biff8` | `.xls` | CFB | multi | Excel 97-2004 Workbook Format |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet Format |
|
||||
| `xlml` | `.xls` | none | multi | Excel 2003-2004 (SpreadsheetML) |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet |
|
||||
@ -1746,7 +1747,7 @@ Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
| Excel 2007+ XML Formats (XLSX/XLSM) | :o: | :o: |
|
||||
| Excel 2007+ Binary Format (XLSB BIFF12) | :o: | :o: |
|
||||
| Excel 2003-2004 XML Format (XML "SpreadsheetML") | :o: | :o: |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | :o: |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | |
|
||||
| Excel 4.0 (XLS/XLW BIFF4) | :o: | |
|
||||
| Excel 3.0 (XLS BIFF3) | :o: | |
|
||||
|
@ -101,6 +101,7 @@ type RowInfo = {
|
||||
|
||||
hpx?:number; // height in screen pixels
|
||||
hpt?:number; // height in points
|
||||
level?:number; // outline / group level
|
||||
};
|
||||
|
||||
type ColInfo = {
|
||||
|
@ -1,11 +1,13 @@
|
||||
#!/bin/bash
|
||||
# strip_sourcemap.sh -- strip sourcemaps from a JS file (missing from uglifyjs)
|
||||
# Copyright (C) 2014-present SheetJS
|
||||
# note: this version also renames write_shift / read_shift to _W / _R
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
if [ -e "$1" ]; then
|
||||
sed -i.sheetjs '/sourceMappingURL/d' "$1"
|
||||
sed -i.sheetjs 's/write_shift/_W/g; s/read_shift/_R/g' "$1"
|
||||
fi
|
||||
else
|
||||
cat - | sed '/sourceMappingURL/d'
|
||||
cat - | sed '/sourceMappingURL/d' | sed 's/write_shift/_W/g; s/read_shift/_R/g'
|
||||
fi
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.11.3",
|
||||
"version": "0.11.4",
|
||||
"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" ],
|
||||
@ -20,8 +20,8 @@
|
||||
"exit-on-epipe":"~1.0.1",
|
||||
"ssf":"~0.10.1",
|
||||
"codepage":"~1.11.0",
|
||||
"cfb":"~0.12.1",
|
||||
"crc-32":"~1.1.0",
|
||||
"cfb":"~0.13.1",
|
||||
"crc-32":"~1.1.1",
|
||||
"adler-32":"~1.1.0",
|
||||
"commander":"~2.11.0"
|
||||
},
|
||||
|
7
test.js
7
test.js
@ -13,7 +13,7 @@ var opts = {cellNF: true};
|
||||
var TYPE = browser ? "binary" : "buffer";
|
||||
opts.type = TYPE;
|
||||
var fullex = [".xlsb", /*".xlsm",*/ ".xlsx"/*, ".xlml"*/];
|
||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "xlml", "sylk", "dif"];
|
||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "biff8", "xlml", "sylk", "dif"];
|
||||
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
|
||||
if(typeof process != 'undefined' && ((process||{}).env)) {
|
||||
opts.WTF = true;
|
||||
@ -1458,7 +1458,7 @@ describe('roundtrip features', function() {
|
||||
});
|
||||
|
||||
describe('should preserve column properties', function() { [
|
||||
'xlml', /*'biff2', */ 'xlsx', 'xlsb', 'slk'
|
||||
'xlml', /*'biff2', 'biff8', */ 'xlsx', 'xlsb', 'slk'
|
||||
].forEach(function(w) { it(w, function() {
|
||||
var ws1 = X.utils.aoa_to_sheet([["hpx12", "hpt24", "hpx48", "hidden"]]);
|
||||
ws1['!cols'] = [{wch:9},{wpx:100},{width:80},{hidden:true}];
|
||||
@ -1477,7 +1477,7 @@ describe('roundtrip features', function() {
|
||||
|
||||
/* TODO: ODS and BIFF5/8 */
|
||||
describe('should preserve row properties', function() { [
|
||||
'xlml', /*'biff2', */ 'xlsx', 'xlsb', 'slk'
|
||||
'xlml', /*'biff2', 'biff8', */ 'xlsx', 'xlsb', 'slk'
|
||||
].forEach(function(w) { it(w, function() {
|
||||
var ws1 = X.utils.aoa_to_sheet([["hpx12"],["hpt24"],["hpx48"],["hidden"]]);
|
||||
ws1['!rows'] = [{hpx:12},{hpt:24},{hpx:48},{hidden:true}];
|
||||
@ -1979,6 +1979,7 @@ describe('corner cases', function() {
|
||||
X.write(wb, {type: "base64", bookType: 'xlsb'});
|
||||
X.write(wb, {type: "binary", bookType: 'ods'});
|
||||
X.write(wb, {type: "binary", bookType: 'biff2'});
|
||||
X.write(wb, {type: "binary", bookType: 'biff8'});
|
||||
get_cell(ws,"A2").t = "f";
|
||||
assert.throws(function() { X.utils.make_json(ws); });
|
||||
});
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d0f58a9e4b0519a513a1e44d1b28109fd4a8e13e
|
||||
Subproject commit a9c6bbb161ca45a077779ecbe434d8c5d614ee37
|
@ -1078,7 +1078,7 @@ jxls-examples_basictags.xls
|
||||
jxls-examples_chart.xls
|
||||
jxls-examples_colouring.xls
|
||||
jxls-examples_department.xls
|
||||
jxls-examples_dynamicolumns.xls
|
||||
jxls-examples_dynamiccolumns.xls
|
||||
jxls-examples_employees.xls
|
||||
jxls-examples_ex_temp.xls
|
||||
jxls-examples_grouping.xls
|
||||
|
@ -13,7 +13,7 @@ var opts = {cellNF: true};
|
||||
var TYPE = browser ? "binary" : "buffer";
|
||||
opts.type = TYPE;
|
||||
var fullex = [".xlsb", /*".xlsm",*/ ".xlsx"/*, ".xlml"*/];
|
||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "xlml", "sylk", "dif"];
|
||||
var ofmt = ["xlsb", "xlsm", "xlsx", "ods", "biff2", "biff8", "xlml", "sylk", "dif"];
|
||||
var ex = fullex.slice(); ex = ex.concat([".ods", ".xls", ".xml", ".fods"]);
|
||||
if(typeof process != 'undefined' && ((process||{}).env)) {
|
||||
opts.WTF = true;
|
||||
@ -1253,19 +1253,19 @@ describe('write features', function() {
|
||||
X = require(modp);
|
||||
ws = X.utils.aoa_to_sheet([["a","b","c"],[1,2,3]]);
|
||||
baseprops = {
|
||||
Category: "C4tegory",
|
||||
ContentStatus: "C0ntentStatus",
|
||||
Keywords: "K3ywords",
|
||||
LastAuthor: "L4stAuthor",
|
||||
LastPrinted: "L4stPrinted",
|
||||
Category: "Newspaper",
|
||||
ContentStatus: "Published",
|
||||
Keywords: "print",
|
||||
LastAuthor: "Perry White",
|
||||
LastPrinted: "1978-12-15",
|
||||
RevNumber: 6969,
|
||||
AppVersion: 69,
|
||||
Author: "4uth0r",
|
||||
Comments: "C0mments",
|
||||
Author: "Lois Lane",
|
||||
Comments: "Needs work",
|
||||
Identifier: "1d",
|
||||
Language: "L4nguage",
|
||||
Subject: "Subj3ct",
|
||||
Title: "T1tle"
|
||||
Language: "English",
|
||||
Subject: "Superman",
|
||||
Title: "Man of Steel"
|
||||
};
|
||||
});
|
||||
if(typeof before != 'undefined') before(bef);
|
||||
@ -1458,7 +1458,7 @@ describe('roundtrip features', function() {
|
||||
});
|
||||
|
||||
describe('should preserve column properties', function() { [
|
||||
'xlml', /*'biff2', */ 'xlsx', 'xlsb', 'slk'
|
||||
'xlml', /*'biff2', 'biff8', */ 'xlsx', 'xlsb', 'slk'
|
||||
].forEach(function(w) { it(w, function() {
|
||||
var ws1 = X.utils.aoa_to_sheet([["hpx12", "hpt24", "hpx48", "hidden"]]);
|
||||
ws1['!cols'] = [{wch:9},{wpx:100},{width:80},{hidden:true}];
|
||||
@ -1477,7 +1477,7 @@ describe('roundtrip features', function() {
|
||||
|
||||
/* TODO: ODS and BIFF5/8 */
|
||||
describe('should preserve row properties', function() { [
|
||||
'xlml', /*'biff2', */ 'xlsx', 'xlsb', 'slk'
|
||||
'xlml', /*'biff2', 'biff8', */ 'xlsx', 'xlsb', 'slk'
|
||||
].forEach(function(w) { it(w, function() {
|
||||
var ws1 = X.utils.aoa_to_sheet([["hpx12"],["hpt24"],["hpx48"],["hidden"]]);
|
||||
ws1['!rows'] = [{hpx:12},{hpt:24},{hpx:48},{hidden:true}];
|
||||
@ -1979,6 +1979,7 @@ describe('corner cases', function() {
|
||||
X.write(wb, {type: "base64", bookType: 'xlsb'});
|
||||
X.write(wb, {type: "binary", bookType: 'ods'});
|
||||
X.write(wb, {type: "binary", bookType: 'biff2'});
|
||||
X.write(wb, {type: "binary", bookType: 'biff8'});
|
||||
get_cell(ws,"A2").t = "f";
|
||||
assert.throws(function() { X.utils.make_json(ws); });
|
||||
});
|
||||
|
@ -14,10 +14,10 @@ var data = [
|
||||
var ws_name = "SheetJS";
|
||||
|
||||
var wscols = [
|
||||
{wch:6}, // "characters"
|
||||
{wpx:50}, // "pixels"
|
||||
{wch: 6}, // "characters"
|
||||
{wpx: 50}, // "pixels"
|
||||
,
|
||||
{hidden:true} // hide column
|
||||
{hidden: true} // hide column
|
||||
];
|
||||
|
||||
/* At 96 PPI, 1 pt = 1 px */
|
||||
@ -162,7 +162,8 @@ var filenames = [
|
||||
['sheetjs.xlsx', {bookSST:true}],
|
||||
['sheetjs.xlsm'],
|
||||
['sheetjs.xlsb'],
|
||||
['sheetjs.xls', {bookType:'biff2'}],
|
||||
['sheetjs.xls', {bookType:'xls'}],
|
||||
['sheetjs.biff2', {bookType:'biff2'}],
|
||||
['sheetjs.xml.xls', {bookType:'xlml'}],
|
||||
['sheetjs.ods'],
|
||||
['sheetjs.fods'],
|
||||
|
@ -2,12 +2,12 @@
|
||||
/* eslint-env node */
|
||||
const n = "xlsx";
|
||||
/* vim: set ts=2 ft=javascript: */
|
||||
import XLSX = require("xlsx");
|
||||
import X = require("xlsx");
|
||||
import 'exit-on-epipe';
|
||||
import * as fs from 'fs';
|
||||
import program = require('commander');
|
||||
program
|
||||
.version(XLSX.version)
|
||||
.version(X.version)
|
||||
.usage('[options] <file> [sheetname]')
|
||||
.option('-f, --file <file>', 'use specified workbook')
|
||||
.option('-s, --sheet <sheet>', 'print specified sheet (default first sheet)')
|
||||
@ -42,6 +42,7 @@ program
|
||||
.option('--read-only', 'do not generate output')
|
||||
.option('--all', 'parse everything; write as much as possible')
|
||||
.option('--dev', 'development mode')
|
||||
.option('--sparse', 'sparse mode')
|
||||
.option('--read', 'read but do not print out contents')
|
||||
.option('-q, --quiet', 'quiet mode');
|
||||
|
||||
@ -77,8 +78,7 @@ if(!fs.existsSync(filename)) {
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
let opts: XLSX.ParsingOptions = {};
|
||||
let wb: XLSX.WorkBook;
|
||||
let opts: X.ParsingOptions = {}, wb: X.WorkBook;
|
||||
if(program.listSheets) opts.bookSheets = true;
|
||||
if(program.sheetRows) opts.sheetRows = program.sheetRows;
|
||||
if(program.password) opts.password = program.password;
|
||||
@ -89,8 +89,13 @@ function wb_fmt() {
|
||||
opts.cellNF = true;
|
||||
if(program.output) sheetname = program.output;
|
||||
}
|
||||
workbook_formats.forEach(function(m) { if(program[m]) { wb_fmt(); } });
|
||||
wb_formats_2.forEach(function(m) { if(program[m[0]]) { wb_fmt(); } });
|
||||
function isfmt(m: string): boolean {
|
||||
if(!program.output) return false;
|
||||
const t = m.charAt(0) === "." ? m : "." + m;
|
||||
return program.output.slice(-t.length) === t;
|
||||
}
|
||||
workbook_formats.forEach(function(m) { if(program[m] || isfmt(m)) { wb_fmt(); } });
|
||||
wb_formats_2.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { wb_fmt(); } });
|
||||
if(seen) {
|
||||
} else if(program.formulae) opts.cellFormula = true;
|
||||
else opts.cellFormula = false;
|
||||
@ -104,12 +109,13 @@ if(program.all) {
|
||||
opts.sheetStubs = true;
|
||||
opts.cellDates = true;
|
||||
}
|
||||
if(program.sparse) opts.dense = false; else opts.dense = true;
|
||||
|
||||
if(program.dev) {
|
||||
opts.WTF = true;
|
||||
wb = XLSX.readFile(filename, opts);
|
||||
wb = X.readFile(filename, opts);
|
||||
} else try {
|
||||
wb = XLSX.readFile(filename, opts);
|
||||
wb = X.readFile(filename, opts);
|
||||
} catch(e) {
|
||||
let msg = (program.quiet) ? "" : n + ": error parsing ";
|
||||
msg += filename + ": " + e;
|
||||
@ -124,18 +130,18 @@ if(program.listSheets) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
let wopts: XLSX.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
|
||||
let wopts: X.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
|
||||
if(program.compress) wopts.compression = true;
|
||||
|
||||
/* full workbook formats */
|
||||
workbook_formats.forEach(function(m) { if(program[m]) {
|
||||
XLSX.writeFile(wb, sheetname || ((filename || "") + "." + m), wopts);
|
||||
workbook_formats.forEach(function(m) { if(program[m] || isfmt(m)) {
|
||||
X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m), wopts);
|
||||
process.exit(0);
|
||||
} });
|
||||
|
||||
wb_formats_2.forEach(function(m) { if(program[m[0]]) {
|
||||
wopts.bookType = <XLSX.BookType>(m[1]);
|
||||
XLSX.writeFile(wb, sheetname || ((filename || "") + "." + m[2]), wopts);
|
||||
wb_formats_2.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) {
|
||||
wopts.bookType = <X.BookType>(m[1]);
|
||||
X.writeFile(wb, program.output || sheetname || ((filename || "") + "." + m[2]), wopts);
|
||||
process.exit(0);
|
||||
} });
|
||||
|
||||
@ -145,7 +151,7 @@ if(target_sheet === '') {
|
||||
else target_sheet = (wb.SheetNames||[""])[0];
|
||||
}
|
||||
|
||||
let ws: XLSX.WorkSheet;
|
||||
let ws: X.WorkSheet;
|
||||
try {
|
||||
ws = wb.Sheets[target_sheet];
|
||||
if(!ws) {
|
||||
@ -167,22 +173,21 @@ if(program.readOnly) process.exit(0);
|
||||
['prn', '.prn'],
|
||||
['txt', '.txt'],
|
||||
['dif', '.dif']
|
||||
].forEach(function(m) { if(program[m[0]]) {
|
||||
wopts.bookType = <XLSX.BookType>(m[1]);
|
||||
XLSX.writeFile(wb, sheetname || ((filename || "") + m[1]), wopts);
|
||||
].forEach(function(m) { if(program[m[0]] || isfmt(m[1])) {
|
||||
wopts.bookType = <X.BookType>(m[0]);
|
||||
X.writeFile(wb, program.output || sheetname || ((filename || "") + m[1]), wopts);
|
||||
process.exit(0);
|
||||
} });
|
||||
|
||||
let oo = "";
|
||||
let strm = false;
|
||||
let oo = "", strm = false;
|
||||
if(!program.quiet) console.error(target_sheet);
|
||||
if(program.formulae) oo = XLSX.utils.sheet_to_formulae(ws).join("\n");
|
||||
else if(program.json) oo = JSON.stringify(XLSX.utils.sheet_to_json(ws));
|
||||
else if(program.rawJs) oo = JSON.stringify(XLSX.utils.sheet_to_json(ws,{raw:true}));
|
||||
else if(program.arrays) oo = JSON.stringify(XLSX.utils.sheet_to_json(ws,{raw:true, header:1}));
|
||||
if(program.formulae) oo = X.utils.sheet_to_formulae(ws).join("\n");
|
||||
else if(program.json) oo = JSON.stringify(X.utils.sheet_to_json(ws));
|
||||
else if(program.rawJs) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true}));
|
||||
else if(program.arrays) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true, header:1}));
|
||||
else {
|
||||
strm = true;
|
||||
let stream: NodeJS.ReadableStream = XLSX.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep});
|
||||
let stream: NodeJS.ReadableStream = X.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep});
|
||||
if(program.output) stream.pipe(fs.createWriteStream(program.output));
|
||||
else stream.pipe(process.stdout);
|
||||
}
|
||||
|
7
types/index.d.ts
vendored
7
types/index.d.ts
vendored
@ -176,6 +176,8 @@ export interface ParsingOptions extends CommonOptions {
|
||||
|
||||
/* If true, plaintext parsing will not parse values */
|
||||
raw?: boolean;
|
||||
|
||||
dense?: boolean;
|
||||
}
|
||||
|
||||
/** Options for write and writeFile */
|
||||
@ -308,6 +310,9 @@ export interface RowInfo {
|
||||
|
||||
/** height in points */
|
||||
hpt?: number;
|
||||
|
||||
/** outline / group level */
|
||||
level?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -472,7 +477,7 @@ export type ExcelDataType = 'b' | 'n' | 'e' | 's' | 'd' | 'z';
|
||||
* Type of generated workbook
|
||||
* @default 'xlsx'
|
||||
*/
|
||||
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'prn';
|
||||
export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'xls' | 'biff8' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'prn';
|
||||
|
||||
/** Comment element */
|
||||
export interface Comment {
|
||||
|
@ -25,7 +25,7 @@ let wsrows: XLSX.RowInfo[] = [
|
||||
{hpt: 12}, // "points"
|
||||
{hpx: 16}, // "pixels"
|
||||
,
|
||||
{hpx: 24},
|
||||
{hpx: 24, level:3},
|
||||
{hidden: true}, // hide row
|
||||
{hidden: false}
|
||||
];
|
||||
@ -150,15 +150,17 @@ const filenames: Array<[string]|[string, XLSX.WritingOptions]> = [
|
||||
['sheetjs.xlsx', {bookSST:true}],
|
||||
['sheetjs.xlsm'],
|
||||
['sheetjs.xlsb'],
|
||||
['sheetjs.xls', {bookType:'biff2'}],
|
||||
['sheetjs.xls', {bookType:'xls'}],
|
||||
['sheetjs.biff2', {bookType:'biff2'}],
|
||||
['sheetjs.xml.xls', {bookType:'xlml'}],
|
||||
['sheetjs.ods'],
|
||||
['sheetjs.fods'],
|
||||
['sheetjs.slk'],
|
||||
['sheetjs.csv'],
|
||||
['sheetjs.txt'],
|
||||
['sheetjs.prn'],
|
||||
['sheetjs.dif']
|
||||
['sheetjs.slk'],
|
||||
['sheetjs.htm'],
|
||||
['sheetjs.dif'],
|
||||
['sheetjs.prn']
|
||||
];
|
||||
|
||||
filenames.forEach((r) => {
|
||||
|
3429
xlsx.flow.js
3429
xlsx.flow.js
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user