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
|
@ -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: {
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
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);
|
||||
}
|
||||
|
|
|
@ -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