forked from sheetjs/sheetjs
version bump 0.8.5: FODS/UOS and IE6+ support
- read and write support for Flat ODS files - read support for Uniform Office Spreadsheet (UOS) - IE6-8 cell regex split fix (fixes #350 #140 #268 h/t @Aymkdn @C0d3ine) - replace substr negative index with slices (fixes #351 h/t @Aymkdn) - ODS parsexmltag ignores ext overrides (fixes #548 h/t @lgodard) - csv can be written using write/writeFile with csv type - added `type` to README (fixes #432 h/t @tomkel)
This commit is contained in:
parent
d7ecca0e8b
commit
7408679252
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,7 +12,9 @@ tmp
|
||||
*.[xX][lL][sSwW]
|
||||
*.[xX][lL][sS][xXmMbB]
|
||||
*.[oO][dD][sS]
|
||||
*.[fF][oO][dD][sS]
|
||||
*.[xX][mM][lL]
|
||||
*.[uU][oO][sS]
|
||||
*.htm
|
||||
*.html
|
||||
*.sheetjs
|
||||
|
@ -13,7 +13,9 @@ tmp
|
||||
*.[xX][lL][sSwW]
|
||||
*.[xX][lL][sS][xXmMbB]
|
||||
*.[oO][dD][sS]
|
||||
*.[fF][oO][dD][sS]
|
||||
*.[xX][mM][lL]
|
||||
*.[uU][oO][sS]
|
||||
*.htm
|
||||
*.html
|
||||
*.sheetjs
|
||||
|
178
README.md
178
README.md
@ -1,26 +1,29 @@
|
||||
# xlsx
|
||||
|
||||
Parser and writer for various spreadsheet formats. Pure-JS cleanroom
|
||||
implementation from official specifications and related documents.
|
||||
implementation from official specifications, related documents, and test files.
|
||||
Emphasis on parsing and writing robustness, cross-format feature compatibility
|
||||
with a unified JS representation, and ES3/ES5 browser compatibility back to IE6.
|
||||
|
||||
Supported read formats:
|
||||
File format support for known spreadsheet data formats:
|
||||
|
||||
- Excel 2007+ XML Formats (XLSX/XLSM)
|
||||
- Excel 2007+ Binary Format (XLSB BIFF12)
|
||||
- Excel 2003-2004 XML Format (XML "SpreadsheetML")
|
||||
- Excel 97-2004 (XLS BIFF8)
|
||||
- Excel 5.0/95 (XLS BIFF5)
|
||||
- Excel 2.0/3.0/4.0 (XLS BIFF2/BIFF3/BIFF4)
|
||||
- OpenDocument Spreadsheet (ODS)
|
||||
|
||||
Supported write formats:
|
||||
|
||||
- Excel 2.0 (XLS BIFF2, compatible with *every version* of Excel)
|
||||
- Excel 2007+ XML Formats (XLSX/XLSM, compatible with Excel 2007+)
|
||||
- Excel 2007+ Binary Format (XLSB, compatible with Excel 2007+)
|
||||
- CSV (and general DSV)
|
||||
- JSON and JS objects (various styles)
|
||||
- OpenDocument Spreadsheet (ODS)
|
||||
| Format | Read | Write |
|
||||
|:-------------------------------------------------------------|:-----:|:-----:|
|
||||
| **Excel Worksheet/Workbook 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: | |
|
||||
| Excel 97-2004 (XLS BIFF8) | :o: | |
|
||||
| Excel 5.0/95 (XLS BIFF5) | :o: | |
|
||||
| Excel 4.0 (XLS/XLW BIFF4) | :o: | |
|
||||
| Excel 3.0 (XLS BIFF3) | :o: | |
|
||||
| Excel 2.0/2.1 (XLS BIFF2) | :o: | :o: |
|
||||
| **Excel Supported Text Formats** |:-----:|:-----:|
|
||||
| Delimiter-Separated Values (CSV/TSV/DSV) | | :o: |
|
||||
| **Other Workbook/Worksheet Formats** |:-----:|:-----:|
|
||||
| OpenDocument Spreadsheet (ODS) | :o: | :o: |
|
||||
| Flat XML ODF Spreadsheet (FODS) | :o: | :o: |
|
||||
| Uniform Office Format Spreadsheet (标文通 UOS1/UOS2) | :o: | |
|
||||
|
||||
Demo: <http://oss.sheetjs.com/js-xlsx>
|
||||
|
||||
@ -52,7 +55,7 @@ $ bower install js-xlsx
|
||||
CDNjs automatically pulls the latest version and makes all versions available at
|
||||
<http://cdnjs.com/libraries/xlsx>
|
||||
|
||||
## Optional Modules
|
||||
### Optional Modules
|
||||
|
||||
The node version automatically requires modules for additional features. Some
|
||||
of these modules are rather large in size and are only needed in special
|
||||
@ -70,7 +73,7 @@ An appropriate version for each dependency is included in the dist/ directory.
|
||||
|
||||
The complete single-file version is generated at `dist/xlsx.full.min.js`
|
||||
|
||||
## ECMAScript 5 Compatibility
|
||||
### ECMAScript 5 Compatibility
|
||||
|
||||
Since xlsx.js uses ES5 functions like `Array#forEach`, older browsers require
|
||||
[Polyfills](http://git.io/QVh77g). This repo and the gh-pages branch include
|
||||
@ -239,13 +242,21 @@ Complete examples:
|
||||
|
||||
- <http://oss.sheetjs.com/js-xlsx/> HTML5 File API / Base64 Text / Web Workers
|
||||
|
||||
Note that older versions of IE does not support HTML5 File API, so the base64
|
||||
mode is provided for testing. On OSX you can get the base64 encoding with:
|
||||
Note that older versions of IE do not support HTML5 File API, so the base64 mode
|
||||
is used for testing. On OSX you can get the base64 encoding with:
|
||||
|
||||
```bash
|
||||
$ <target_file.xlsx base64 | pbcopy
|
||||
$ <target_file base64 | pbcopy
|
||||
```
|
||||
|
||||
On Windows XP and up you can get the base64 encoding using `certutil`:
|
||||
|
||||
```cmd
|
||||
> certutil -encode target_file target_file.b64
|
||||
```
|
||||
|
||||
(note: You have to open the file and remove the header and footer lines)
|
||||
|
||||
- <http://oss.sheetjs.com/js-xlsx/ajax.html> XMLHttpRequest
|
||||
|
||||
- <https://github.com/SheetJS/js-xlsx/blob/master/bin/xlsx.njs> node
|
||||
@ -488,6 +499,7 @@ The exported `read` and `readFile` functions accept an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | ------: | :--------------------------------------------------- |
|
||||
| type | | Input data encoding (see Input Type below) |
|
||||
| cellFormula | true | Save formulae to the .f field ** |
|
||||
| cellHTML | true | Parse rich text and save HTML to the .h field |
|
||||
| cellNF | false | Save number format string to the .z field |
|
||||
@ -521,12 +533,40 @@ The exported `read` and `readFile` functions accept an options argument:
|
||||
|
||||
The defaults are enumerated in bits/84\_defaults.js
|
||||
|
||||
### Input Type
|
||||
|
||||
Strings can be interpreted in multiple ways. The `type` parameter for `read`
|
||||
tells the library how to parse the data argument:
|
||||
|
||||
| `type` | expected input |
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (`n`-th byte is `data.charCodeAt(n)`) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"array"` | array: array of 8-bit unsigned int (`n`-th byte is `data[n]`) |
|
||||
| `"file"` | string: filename that will be read and processed (nodejs only) |
|
||||
|
||||
### Guessing File Type
|
||||
|
||||
Excel and other spreadsheet tools read the first few bytes and apply other
|
||||
heuristics to determine a file type. This enables file type punning: renaming
|
||||
files with the `.xls` extension will tell your computer to use Excel to open the
|
||||
file but Excel will know how to handle it. This library applies similar logic:
|
||||
|
||||
| Byte 0 | Raw File Type | Spreadsheet Types |
|
||||
|:-------|:--------------------------------------------------------------------|
|
||||
| `0xD0` | CFB Container | BIFF 5/8 or password-protected XLSX/XLSB |
|
||||
| `0x09` | BIFF Stream | BIFF 2/3/4/5 |
|
||||
| `0x3C` | XML | SpreadsheetML or Flat ODS or UOS1 |
|
||||
| `0x50` | ZIP Archive | XLSB or XLSX/M or ODS or UOS2 |
|
||||
|
||||
## Writing Options
|
||||
|
||||
The exported `write` and `writeFile` functions accept an options argument:
|
||||
|
||||
| Option Name | Default | Description |
|
||||
| :---------- | -------: | :-------------------------------------------------- |
|
||||
| type | | Output data encoding (see Output Type below) |
|
||||
| cellDates | `false` | Store dates as type `d` (default is `n`) |
|
||||
| bookSST | `false` | Generate Shared String Table ** |
|
||||
| bookType | `"xlsx"` | Type of Workbook (see below for supported formats) |
|
||||
@ -541,20 +581,96 @@ The exported `write` and `writeFile` functions accept an options argument:
|
||||
third-party readers. Excel itself does not usually write cells with type `d`
|
||||
so non-Excel tools may ignore the data or blow up in the presence of dates.
|
||||
|
||||
Supported output formats (`bookType`):
|
||||
### Supported Output Formats
|
||||
|
||||
| bookType | file ext | container | sheets | Description |
|
||||
| :------- | -------: | :-------: | :----- |:---------------------------- |
|
||||
| `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 |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet format |
|
||||
For broad compatibility with third-party tools, this library supports many
|
||||
output formats. The specific file type is controlled with `bookType` option:
|
||||
|
||||
| bookType | file ext | container | sheets | Description |
|
||||
| :------- | -------: | :-------: | :----- |:--------------------------------- |
|
||||
| `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 |
|
||||
| `ods` | `.ods` | ZIP | multi | OpenDocument Spreadsheet |
|
||||
| `biff2` | `.xls` | none | single | Excel 2.0 Worksheet format |
|
||||
| `fods` | `.fods` | none | multi | Flat OpenDocument Spreadsheet |
|
||||
| `csv` | `.csv` | none | single | Comma Separated Values |
|
||||
|
||||
- `compression` only applies to formats with ZIP containers.
|
||||
- Formats that only support a single sheet require a `sheet` option specifying
|
||||
the worksheet. If the string is empty, the first worksheet is used.
|
||||
|
||||
### Output Type
|
||||
|
||||
The `type` argument for `write` mirrors the `type` argument for `read`:
|
||||
|
||||
| `type` | output |
|
||||
|------------|-----------------------------------------------------------------|
|
||||
| `"base64"` | string: base64 encoding of the file |
|
||||
| `"binary"` | string: binary string (`n`-th byte is `data.charCodeAt(n)`) |
|
||||
| `"buffer"` | nodejs Buffer |
|
||||
| `"file"` | string: name of file to be written (nodejs only) |
|
||||
|
||||
|
||||
## File Formats
|
||||
|
||||
Despite the fact that the name of the library is `xlsx`, it supports numerous
|
||||
non-XLSX file formats:
|
||||
|
||||
### Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)
|
||||
|
||||
BIFF 2/3 XLS are single-sheet streams of binary records. Excel 4 introduced
|
||||
the concept of a workbook (`XLW` files) but also had single-sheet `XLS` format.
|
||||
The structure is largely similar to the Lotus 1-2-3 file formats. BIFF5/8/12
|
||||
extended the format in various ways but largely stuck to the same record format.
|
||||
|
||||
There is no official specification for any of these formats. Excel 95 can write
|
||||
files in these formats, so record lengths and fields were backsolved by writing
|
||||
in all of the supported formats and comparing files. Excel 2016 can generate
|
||||
BIFF5 files, enabling a full suite of file tests starting from XLSX or BIFF2.
|
||||
|
||||
### Excel 97-2004 Binary (BIFF8)
|
||||
|
||||
BIFF8 exclusively uses the Compound File Binary container format, splitting some
|
||||
content into streams within the file. At its core, it still uses an extended
|
||||
version of the binary record format from older versions of BIFF.
|
||||
|
||||
The `MS-XLS` specification covers the basics of the file format, and other
|
||||
specifications expand on serialization of features like properties.
|
||||
|
||||
### Excel 2003-2004 (SpreadsheetML)
|
||||
|
||||
Predating XLSX, SpreadsheetML files are simple XML files. There is no official
|
||||
and comprehensive specification, although MS has released whitepapers on the
|
||||
format. Since Excel 2016 can generate SpreadsheetML files, backsolving is
|
||||
pretty straightforward.
|
||||
|
||||
### Excel 2007+ Binary (XLSB, BIFF12)
|
||||
|
||||
Introduced in parallel with XLSX, the XLSB filetype combines BIFF architecture
|
||||
with the content separation and ZIP container of XLSX. For the most part nodes
|
||||
in an XLSX sub-file can be mapped to XLSB records in a corresponding sub-file.
|
||||
|
||||
The `MS-XLSB` specification covers the basics of the file format, and other
|
||||
specifications expand on serialization of features like properties.
|
||||
|
||||
### OpenDocument Spreadsheet (ODS/FODS) and Uniform Office Spreadsheet (UOS1/2)
|
||||
|
||||
ODS is an XML-in-ZIP format akin to XLSX while FODS is an XML format akin to
|
||||
SpreadsheetML. Both are detailed in the OASIS standard, but tools like LO/OO
|
||||
add undocumented extensions.
|
||||
|
||||
UOS is a very similar format, and it comes in 2 varieties corresponding to ODS
|
||||
and FODS respectively. For the most part, the difference between the formats
|
||||
lies in the names of tags and attributes.
|
||||
|
||||
### Comma-Separated Values
|
||||
|
||||
Excel CSV deviates from RFC4180 in a number of important ways. The generated
|
||||
CSV files should generally work in Excel although they may not work in RFC4180
|
||||
compatible readers.
|
||||
|
||||
|
||||
## Tested Environments
|
||||
|
||||
- NodeJS 0.8, 0.9, 0.10, 0.11, 0.12, 4.x, 5.x, 6.x, 7.x
|
||||
|
@ -13,11 +13,14 @@ program
|
||||
.option('-p, --password <pw>', 'if file is encrypted, try with specified pw')
|
||||
.option('-l, --list-sheets', 'list sheet names and exit')
|
||||
.option('-o, --output <file>', 'output to specified file')
|
||||
|
||||
.option('-B, --xlsb', 'emit XLSB to <sheetname> or <file>.xlsb')
|
||||
.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('-2, --biff2','emit XLS to <sheetname> or <file>.xls (BIFF2)')
|
||||
.option('-T, --fods', 'emit FODS to <sheetname> or <file>.xls (Flat ODS)')
|
||||
|
||||
.option('-S, --formulae', 'print formulae')
|
||||
.option('-j, --json', 'emit formatted JSON (all fields text)')
|
||||
.option('-J, --raw-js', 'emit raw JS object (raw numbers)')
|
||||
@ -39,6 +42,8 @@ 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'];
|
||||
program.parse(process.argv);
|
||||
|
||||
/* see https://github.com/SheetJS/j/issues/4 */
|
||||
@ -112,7 +117,7 @@ var wopts = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/);
|
||||
if(program.compress) wopts.compression = true;
|
||||
|
||||
/* full workbook formats */
|
||||
['xlsx', 'xlsm', 'xlsb', 'ods'].forEach(function(m) { if(program[m]) {
|
||||
workbook_formats.forEach(function(m) { if(program[m]) {
|
||||
X.writeFile(wb, sheetname || ((filename || "") + "." + m), wopts);
|
||||
process.exit(0);
|
||||
} });
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.8.4';
|
||||
XLSX.version = '0.8.5';
|
||||
|
@ -564,7 +564,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
case '[':
|
||||
o = c;
|
||||
while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i];
|
||||
if(o.substr(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.slice(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.match(abstime)) {
|
||||
if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
|
||||
out[out.length] = {t:'Z', v:o.toLowerCase()};
|
||||
|
@ -42,6 +42,12 @@ function cc2str(arr/*:Array<number>*/)/*:string*/ {
|
||||
return o;
|
||||
}
|
||||
|
||||
function str2cc(str) {
|
||||
var o = [];
|
||||
for(var i = 0; i != str.length; ++i) o.push(str.charCodeAt(i));
|
||||
return o;
|
||||
}
|
||||
|
||||
function dup(o/*:any*/)/*:any*/ {
|
||||
if(typeof JSON != 'undefined') return JSON.parse(JSON.stringify(o));
|
||||
if(typeof o != 'object' || !o) return o;
|
||||
|
@ -11,11 +11,15 @@ function getdatabin(data) {
|
||||
if(!data) return null;
|
||||
if(data.data) return char_codes(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
|
||||
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
|
||||
if(data._data && data._data.getContent) {
|
||||
var o = data._data.getContent();
|
||||
if(typeof o == "string") return str2cc(o);
|
||||
return Array.prototype.slice.call(o);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getdata(data) { return (data && data.name.substr(data.name.length-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
|
||||
function safegetzipfile(zip, file/*:string*/) {
|
||||
var f = file; if(zip.files[f]) return zip.files[f];
|
||||
|
@ -42,7 +42,7 @@ var unescapexml/*:StringConv*/ = (function() {
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
|
||||
function escapexml(text/*:string*/)/*:string*/{
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";});
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
|
||||
}
|
||||
|
||||
/* TODO: handle codepages */
|
||||
|
@ -82,7 +82,10 @@ function ReadShift(size, t) {
|
||||
case 'utf8': o = __utf8(this, this.l, this.l + size); break;
|
||||
case 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break;
|
||||
|
||||
case 'wstr': o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size)); size = 2 * size; break;
|
||||
case 'wstr':
|
||||
if(typeof cptable !== 'undefined') o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size));
|
||||
else return ReadShift.call(this, size, 'dbcs');
|
||||
o = size = 2 * size; break;
|
||||
|
||||
/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
|
||||
case 'lpstr': o = __lpstr(this, this.l); size = 5 + o.length; break;
|
||||
|
@ -192,7 +192,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
|
||||
/* 18.3.1.4 c CT_Cell */
|
||||
cells = x.substr(ri).split(cellregex);
|
||||
for(ri = typeof tag.r === 'undefined' ? 0 : 1; ri != cells.length; ++ri) {
|
||||
for(ri = 0; ri != cells.length; ++ri) {
|
||||
x = cells[ri].trim();
|
||||
if(x.length === 0) continue;
|
||||
cref = x.match(rregex); idx = ri; i=0; cc=0;
|
||||
|
@ -504,7 +504,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
|
||||
}
|
||||
var o/*:CellAddress*/ = ({r:R, c:C}/*:any*/);
|
||||
/* TODO: cell style */
|
||||
o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
//o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
switch(cell.t) {
|
||||
case 's': case 'str':
|
||||
if(opts.bookSST) {
|
||||
|
@ -1,15 +1,15 @@
|
||||
function parse_wb(data, name/*:string*/, opts)/*:Workbook*/ {
|
||||
if(name.substr(name.length-4)===".bin") return parse_wb_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_wb_bin((data/*:any*/), opts);
|
||||
return parse_wb_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function parse_ws(data, name/*:string*/, opts, rels, wb)/*:Worksheet*/ {
|
||||
if(name.substr(name.length-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels, wb);
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels, wb);
|
||||
return parse_ws_xml((data/*:any*/), opts, rels, wb);
|
||||
}
|
||||
|
||||
function parse_sty(data, name/*:string*/, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_sty_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_sty_bin((data/*:any*/), opts);
|
||||
return parse_sty_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
@ -18,41 +18,41 @@ function parse_theme(data, name/*:string*/, opts) {
|
||||
}
|
||||
|
||||
function parse_sst(data, name/*:string*/, opts)/*:SST*/ {
|
||||
if(name.substr(name.length-4)===".bin") return parse_sst_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_sst_bin((data/*:any*/), opts);
|
||||
return parse_sst_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function parse_cmnt(data, name/*:string*/, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_comments_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_comments_bin((data/*:any*/), opts);
|
||||
return parse_comments_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function parse_cc(data, name/*:string*/, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_cc_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_cc_bin((data/*:any*/), opts);
|
||||
return parse_cc_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function write_wb(wb, name/*:string*/, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||
}
|
||||
|
||||
function write_ws(data/*:Worksheet*/, name/*:string*/, opts, wb/*:Workbook*/) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
|
||||
return (name.slice(-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
|
||||
}
|
||||
|
||||
function write_sty(data, name/*:string*/, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
|
||||
}
|
||||
|
||||
function write_sst(data/*:SST*/, name/*:string*/, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
|
||||
}
|
||||
/*
|
||||
function write_cmnt(data, name:string, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
|
||||
}
|
||||
|
||||
function write_cc(data, name:string, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||
}
|
||||
*/
|
||||
|
@ -200,15 +200,15 @@ function parse_xlml_xml(d, opts) {
|
||||
if(cell.Index) c = +cell.Index - 1;
|
||||
if(c < refguess.s.c) refguess.s.c = c;
|
||||
if(c > refguess.e.c) refguess.e.c = c;
|
||||
if(Rn[0].substr(-2) === "/>") ++c;
|
||||
if(Rn[0].slice(-2) === "/>") ++c;
|
||||
comments = [];
|
||||
}
|
||||
break;
|
||||
case 'Row':
|
||||
if(Rn[1]==='/' || Rn[0].substr(-2) === "/>") {
|
||||
if(Rn[1]==='/' || Rn[0].slice(-2) === "/>") {
|
||||
if(r < refguess.s.r) refguess.s.r = r;
|
||||
if(r > refguess.e.r) refguess.e.r = r;
|
||||
if(Rn[0].substr(-2) === "/>") {
|
||||
if(Rn[0].slice(-2) === "/>") {
|
||||
row = xlml_parsexmltag(Rn[0]);
|
||||
if(row.Index) r = +row.Index - 1;
|
||||
}
|
||||
@ -274,7 +274,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'Alignment': break;
|
||||
case 'Borders': break;
|
||||
case 'Font':
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") ss += str.slice(fidx, Rn.index);
|
||||
else fidx = Rn.index + Rn[0].length;
|
||||
break;
|
||||
@ -300,7 +300,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'TotalTime':
|
||||
case 'HyperlinkBase':
|
||||
case 'Manager':
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") xlml_set_prop(Props, Rn[3], str.slice(pidx, Rn.index));
|
||||
else pidx = Rn.index + Rn[0].length;
|
||||
break;
|
||||
@ -352,6 +352,11 @@ function parse_xlml_xml(d, opts) {
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FODS file root is <office:document> */
|
||||
if(state.length == 0 && Rn[3] == "document") return parse_fods(str, opts);
|
||||
/* UOS file root is <uof:UOF> */
|
||||
if(state.length == 0 && Rn[3] == "UOF") return parse_fods(str, opts);
|
||||
|
||||
var seen = true;
|
||||
switch(state[state.length-1][0]) {
|
||||
/* OfficeDocumentSettings */
|
||||
@ -689,7 +694,7 @@ function parse_xlml_xml(d, opts) {
|
||||
/* CustomDocumentProperties */
|
||||
if(!state[state.length-1][1]) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
|
||||
if(state[state.length-1][0]==='CustomDocumentProperties') {
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") xlml_set_custprop(Custprops, Rn, cp, str.slice(pidx, Rn.index));
|
||||
else { cp = Rn; pidx = Rn.index + Rn[0].length; }
|
||||
break;
|
||||
@ -714,6 +719,7 @@ function parse_xlml(data, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
function write_xlml(wb, opts)/*:string*/ {
|
||||
var o = [XML_HEADER];
|
||||
return o.join("");
|
||||
|
@ -101,18 +101,3 @@ function write_biff_buf(wb/*:Workbook*/, o/*:WriteOpts*/) {
|
||||
// TODO
|
||||
return ba.end();
|
||||
}
|
||||
|
||||
function write_biff(wb/*:Workbook*/, o/*:WriteOpts*/) {
|
||||
var out = write_biff_buf(wb, o);
|
||||
switch(o.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": {
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
}
|
||||
case "file": return _fs.writeFileSync(o.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
}
|
||||
|
7
bits/82_sheeter.js
Normal file
7
bits/82_sheeter.js
Normal file
@ -0,0 +1,7 @@
|
||||
/* actual implementation in utils, wrappers are for read/write */
|
||||
function write_csv_str(wb/*:Workbook*/, o/*:WriteOpts*/) {
|
||||
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);
|
||||
return sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o);
|
||||
}
|
@ -9,3 +9,8 @@ function write_ods(wb, opts) {
|
||||
if(typeof ODS === 'undefined' || !ODS.write_ods) throw new Error("Unsupported ODS");
|
||||
return ODS.write_ods(wb, opts);
|
||||
}
|
||||
function parse_fods(data, opts) {
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined' && typeof ODS === 'undefined') ODS = require('./od' + 's');
|
||||
if(typeof ODS === 'undefined' || !ODS.parse_fods) throw new Error("Unsupported ODS");
|
||||
return ODS.parse_fods(data, opts);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ function safe_parse_ws(zip, path/*:string*/, relsPath/*:string*/, sheet, sheetRe
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
|
||||
var nodirs = function nodirs(x/*:string*/)/*:boolean*/{return x.substr(-1) != '/';};
|
||||
var nodirs = function nodirs(x/*:string*/)/*:boolean*/{return x.slice(-1) != '/';};
|
||||
function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
make_ssf(SSF);
|
||||
opts = opts || {};
|
||||
@ -22,6 +22,8 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
|
||||
/* OpenDocument Part 3 Section 2.2.1 OpenDocument Package */
|
||||
if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
|
||||
/* UOC */
|
||||
if(safegetzipfile(zip, 'objectdata.xml')) return parse_ods(zip, opts);
|
||||
|
||||
var entries = keys(zip.files).filter(nodirs).sort();
|
||||
var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')/*:?any*/), opts);
|
||||
@ -37,7 +39,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
dir.workbooks.push(binname);
|
||||
xlsb = true;
|
||||
}
|
||||
if(dir.workbooks[0].substr(-3) == "bin") xlsb = true;
|
||||
if(dir.workbooks[0].slice(-3) == "bin") xlsb = true;
|
||||
if(xlsb) set_cp(1200);
|
||||
|
||||
if(!opts.bookSheets && !opts.bookProps) {
|
||||
|
@ -14,11 +14,36 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
function write_string_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": break; // TODO
|
||||
case "file": return _fs.writeFileSync(opts.file, out, {encoding:'utf8'});
|
||||
case "buffer": break; // TODO
|
||||
default: return out;
|
||||
}
|
||||
}
|
||||
|
||||
function write_binary_type(out, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
}
|
||||
|
||||
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
var o = opts||{};
|
||||
switch(o.bookType) {
|
||||
case 'xml': return write_xlml(wb, o);
|
||||
case 'biff2': return write_biff(wb, o);
|
||||
case 'xml': return write_string_type(write_xlml(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_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);
|
||||
default: return write_zip_type(wb, o);
|
||||
}
|
||||
}
|
||||
@ -26,14 +51,16 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
function writeFileSync(wb/*:Workbook*/, filename/*:string*/, opts/*:?WriteFileOpts*/) {
|
||||
var o = opts||{}; o.type = 'file';
|
||||
o.file = filename;
|
||||
if(!o.bookType) switch(o.file.substr(-5).toLowerCase()) {
|
||||
if(!o.bookType) switch(o.file.slice(-5).toLowerCase()) {
|
||||
case '.xlsx': o.bookType = 'xlsx'; break;
|
||||
case '.xlsm': o.bookType = 'xlsm'; break;
|
||||
case '.xlsb': o.bookType = 'xlsb'; break;
|
||||
default: switch(o.file.substr(-4).toLowerCase()) {
|
||||
case '.fods': o.bookType = 'fods'; break;
|
||||
default: switch(o.file.slice(-4).toLowerCase()) {
|
||||
case '.xls': o.bookType = 'biff2'; break;
|
||||
case '.xml': o.bookType = 'xml'; break;
|
||||
case '.ods': o.bookType = 'ods'; break;
|
||||
case '.csv': o.bookType = 'csv'; break;
|
||||
}}
|
||||
return writeSync(wb, o);
|
||||
}
|
||||
|
112
dist/ods.js
vendored
112
dist/ods.js
vendored
@ -65,7 +65,7 @@ if (typeof exports !== 'undefined') {
|
||||
_fs = require('f'+'s');
|
||||
}
|
||||
}
|
||||
var attregexg=/\b[\w:-]+=["'][^"]*['"]/g;
|
||||
var attregexg=/[^\s?>\/]+=["'][^"]*['"]/g;
|
||||
var tagregex=/<[^>]*>/g;
|
||||
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
|
||||
function parsexmltag(tag, skip_root) {
|
||||
@ -80,8 +80,15 @@ function parsexmltag(tag, skip_root) {
|
||||
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
|
||||
q = cc.substr(0,c); v = cc.substring(c+2, cc.length-1);
|
||||
for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break;
|
||||
if(j===q.length) z[q] = v;
|
||||
else z[(j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1)] = v;
|
||||
if(j===q.length) {
|
||||
if(q.indexOf("_") > 0) q = q.substr(0, q.indexOf("_"));
|
||||
z[q] = v;
|
||||
}
|
||||
else {
|
||||
var k = (j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1);
|
||||
if(z[k] && q.substr(j-3,3) == "ext") continue;
|
||||
z[k] = v;
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
@ -163,7 +170,8 @@ function xlml_normalize(d) {
|
||||
throw "badf";
|
||||
}
|
||||
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/mg;
|
||||
/* UOS uses CJK in tags, original regex /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/ */
|
||||
var xlmlregex = /<(\/?)([^\s?>\/:]*:|)([^\s?>]*[^\s?>\/])[^>]*>/mg;
|
||||
/* Part 3 Section 4 Manifest File */
|
||||
var CT_ODS = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
function parse_manifest(d, opts) {
|
||||
@ -220,7 +228,7 @@ function write_rdf(rdf, opts) {
|
||||
return o.join("");
|
||||
}
|
||||
var parse_text_p = function(text, tag) {
|
||||
return unescapexml(utf8read(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,"")));
|
||||
return unescapexml(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,""));
|
||||
};
|
||||
|
||||
var utf8read = function utf8reada(orig) {
|
||||
@ -270,6 +278,7 @@ var parse_content_xml = (function() {
|
||||
var tag;
|
||||
var NFtag = {name:""}, NF = "", pidx = 0;
|
||||
var sheetag;
|
||||
var rowtag;
|
||||
var Sheets = {}, SheetNames = [], ws = {};
|
||||
var Rn, q;
|
||||
var ctag = {value:""};
|
||||
@ -281,13 +290,13 @@ var parse_content_xml = (function() {
|
||||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]=Rn[3].replace(/_.*$/,"")) {
|
||||
|
||||
case 'table': // 9.1.2 <table:table>
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
if(range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = get_utils().encode_range(range);
|
||||
if(merges.length) ws['!merges'] = merges;
|
||||
sheetag.name = utf8read(sheetag.name);
|
||||
sheetag.name = utf8read(sheetag['名称'] || sheetag.name);
|
||||
SheetNames.push(sheetag.name);
|
||||
Sheets[sheetag.name] = ws;
|
||||
}
|
||||
@ -299,12 +308,14 @@ var parse_content_xml = (function() {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'table-row': // 9.1.3 <table:table-row>
|
||||
case 'table-row': case '行': // 9.1.3 <table:table-row>
|
||||
if(Rn[1] === '/') break;
|
||||
++R; C = -1; break;
|
||||
rowtag = parsexmltag(Rn[0], false);
|
||||
if(rowtag['行号']) R = rowtag['行号'] - 1; else ++R;
|
||||
C = -1; break;
|
||||
case 'covered-table-cell': // 9.1.5 table:covered-table-cell
|
||||
++C; break; /* stub */
|
||||
case 'table-cell':
|
||||
case 'table-cell': case '数据':
|
||||
if(Rn[0].charAt(Rn[0].length-2) === '/') {
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
if(ctag['number-columns-repeated']) C+= parseInt(ctag['number-columns-repeated'], 10);
|
||||
@ -318,7 +329,7 @@ var parse_content_xml = (function() {
|
||||
if(C < range.s.c) range.s.c = C;
|
||||
if(R < range.s.r) range.s.r = R;
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
q = ({t:ctag['value-type'], v:null});
|
||||
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null});
|
||||
if(opts.cellFormula) {
|
||||
if(ctag['number-matrix-columns-spanned'] && ctag['number-matrix-rows-spanned']) {
|
||||
mR = parseInt(ctag['number-matrix-rows-spanned'],10) || 0;
|
||||
@ -351,8 +362,9 @@ var parse_content_xml = (function() {
|
||||
case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
||||
case 'date': q.t = 'n'; q.v = datenum(ctag['date-value']); q.z = 'm/d/yy'; break;
|
||||
case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400; break;
|
||||
case 'number': q.t = 'n'; q.v = parseFloat(ctag['数据数值']); break;
|
||||
default:
|
||||
if(q.t === 'string' || !q.t) {
|
||||
if(q.t === 'string' || q.t === 'text' || !q.t) {
|
||||
q.t = 's';
|
||||
if(ctag['string-value'] != null) textp = ctag['string-value'];
|
||||
} else throw new Error('Unsupported value type ' + q.t);
|
||||
@ -377,15 +389,23 @@ var parse_content_xml = (function() {
|
||||
break; // 9.1.4 <table:table-cell>
|
||||
|
||||
/* pure state */
|
||||
case 'document-content': // 3.1.3.2 <office:document-content>
|
||||
case 'spreadsheet': // 3.7 <office:spreadsheet>
|
||||
case 'document': // TODO: <office:document> is the root for FODS
|
||||
case 'document-content': case '电子表格文档': // 3.1.3.2 <office:document-content>
|
||||
case 'spreadsheet': case '主体': // 3.7 <office:spreadsheet>
|
||||
case 'scripts': // 3.12 <office:scripts>
|
||||
case 'styles': // TODO <office:styles>
|
||||
case 'font-face-decls': // 3.14 <office:font-face-decls>
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
|
||||
break;
|
||||
|
||||
/* ignore state */
|
||||
case 'meta': case '元数据': // TODO: <office:meta> <uof:元数据> FODS/UOF
|
||||
case 'settings': // TODO: <office:settings>
|
||||
case 'config-item-set': // TODO: <office:config-item-set>
|
||||
case 'config-item-map-indexed': // TODO: <office:config-item-map-indexed>
|
||||
case 'config-item-map-entry': // TODO: <office:config-item-map-entry>
|
||||
case 'config-item-map-named': // TODO: <office:config-item-map-entry>
|
||||
case 'shapes': // 9.2.8 <table:shapes>
|
||||
case 'frame': // 10.4.2 <draw:frame>
|
||||
case 'text-box': // 10.4.3 <draw:text-box>
|
||||
@ -395,11 +415,18 @@ var parse_content_xml = (function() {
|
||||
case 'form': // 13.13 <form:form>
|
||||
case 'dde-links': // 9.8 <table:dde-links>
|
||||
case 'annotation': // 14.1 <office:annotation>
|
||||
case 'event-listeners': // TODO
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], false]);
|
||||
textp = ""; textpidx = 0;
|
||||
break;
|
||||
|
||||
case 'scientific-number': // TODO: <number:scientific-number>
|
||||
break;
|
||||
case 'currency-symbol': // TODO: <number:currency-symbol>
|
||||
break;
|
||||
case 'currency-style': // TODO: <number:currency-style>
|
||||
break;
|
||||
case 'number-style': // 16.27.2 <number:number-style>
|
||||
case 'percentage-style': // 16.27.9 <number:percentage-style>
|
||||
case 'date-style': // 16.27.10 <number:date-style>
|
||||
@ -414,8 +441,12 @@ var parse_content_xml = (function() {
|
||||
} break;
|
||||
|
||||
case 'script': break; // 3.13 <office:script>
|
||||
case 'libraries': break; // TODO: <ooo:libraries>
|
||||
case 'automatic-styles': break; // 3.15.3 <office:automatic-styles>
|
||||
case 'master-styles': break; // TODO: <office:automatic-styles>
|
||||
|
||||
case 'default-style': // TODO: <style:default-style>
|
||||
case 'page-layout': break; // TODO: <style:page-layout>
|
||||
case 'style': break; // 16.2 <style:style>
|
||||
case 'map': break; // 16.3 <style:map>
|
||||
case 'font-face': break; // 16.21 <style:font-face>
|
||||
@ -458,7 +489,7 @@ var parse_content_xml = (function() {
|
||||
case 'boolean': break; // 16.27.24 <number:boolean>
|
||||
case 'text-style': break; // 16.27.25 <number:text-style>
|
||||
case 'text': // 16.27.26 <number:text>
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") switch(state[state.length-1][0]) {
|
||||
case 'number-style':
|
||||
case 'date-style':
|
||||
@ -471,7 +502,7 @@ var parse_content_xml = (function() {
|
||||
case 'text-content': break; // 16.27.27 <number:text-content>
|
||||
case 'text-properties': break; // 16.27.27 <style:text-properties>
|
||||
|
||||
case 'body': break; // 3.3 16.9.6 19.726.3
|
||||
case 'body': case '电子表格': break; // 3.3 16.9.6 19.726.3
|
||||
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
@ -489,7 +520,7 @@ var parse_content_xml = (function() {
|
||||
|
||||
case 'span': break; // <text:span>
|
||||
case 'line-break': break; // 6.1.5 <text:line-break>
|
||||
case 'p':
|
||||
case 'p': case '文本串':
|
||||
if(Rn[1]==='/') textp = parse_text_p(str.slice(textpidx,Rn.index), textptag);
|
||||
else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
|
||||
break; // <text:p>
|
||||
@ -497,7 +528,7 @@ var parse_content_xml = (function() {
|
||||
case 'date': break; // <*:date>
|
||||
|
||||
case 'object': break; // 10.4.6.2 <draw:object>
|
||||
case 'title': break; // <*:title>
|
||||
case 'title': case '标题': break; // <*:title> OR <uof:标题>
|
||||
case 'desc': break; // <*:desc>
|
||||
|
||||
case 'table-source': break; // 9.2.6
|
||||
@ -541,6 +572,25 @@ var parse_content_xml = (function() {
|
||||
case 'sheet-name': // 7.3.9
|
||||
break;
|
||||
|
||||
case 'event-listener': // TODO
|
||||
/* TODO: FODS Properties */
|
||||
case 'initial-creator':
|
||||
case 'creator':
|
||||
case 'creation-date':
|
||||
case 'generator':
|
||||
case 'document-statistic':
|
||||
case 'user-defined':
|
||||
break;
|
||||
|
||||
/* TODO: FODS Config */
|
||||
case 'config-item':
|
||||
break;
|
||||
|
||||
/* TODO: style tokens */
|
||||
case 'page-number': break; // TODO <text:page-number>
|
||||
case 'page-count': break; // TODO <text:page-count>
|
||||
case 'time': break; // TODO <text:time>
|
||||
|
||||
/* 9.6 Data Pilot Tables <table: */
|
||||
case 'data-pilot-table': // 9.6.3
|
||||
case 'source-cell-range': // 9.6.5
|
||||
@ -582,7 +632,12 @@ var parse_content_xml = (function() {
|
||||
default:
|
||||
if(Rn[2] === 'dc:') break; // TODO: properties
|
||||
if(Rn[2] === 'draw:') break; // TODO: drawing
|
||||
if(Rn[2] === 'style:') break; // TODO: styles
|
||||
if(Rn[2] === 'calcext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'loext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'uof:') break; // TODO: uof
|
||||
if(Rn[2] === '表:') break; // TODO: uof
|
||||
if(Rn[2] === '字:') break; // TODO: uof
|
||||
if(opts.WTF) throw Rn;
|
||||
}
|
||||
var out = {
|
||||
@ -623,23 +678,33 @@ var write_content_xml = (function() {
|
||||
return function wcx(wb, opts) {
|
||||
var o = [XML_HEADER];
|
||||
/* 3.1.3.2 */
|
||||
o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
if(opts.bookType == "fods") o.push('<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.spreadsheet">');
|
||||
else o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
o.push(' <office:body>\n');
|
||||
o.push(' <office:spreadsheet>\n');
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts));
|
||||
o.push(' </office:spreadsheet>\n');
|
||||
o.push(' </office:body>\n');
|
||||
o.push('</office:document-content>');
|
||||
if(opts.bookType == "fods") o.push('</office:document>');
|
||||
else o.push('</office:document-content>');
|
||||
return o.join("");
|
||||
};
|
||||
})();
|
||||
/* Part 3: Packages */
|
||||
function parse_ods(zip, opts) {
|
||||
opts = opts || ({});
|
||||
var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
return parse_content_xml(getzipdata(zip, 'content.xml'), opts);
|
||||
var ods = !!safegetzipfile(zip, 'objectdata');
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
var content = getzipdata(zip, 'content.xml');
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
}
|
||||
|
||||
function parse_fods(data, opts) {
|
||||
return parse_content_xml(data, opts);
|
||||
}
|
||||
function write_ods(wb, opts) {
|
||||
if(opts.bookType == "fods") return write_content_xml(wb, opts);
|
||||
|
||||
var zip = new jszip();
|
||||
var f = "";
|
||||
|
||||
@ -669,4 +734,5 @@ var zip = new jszip();
|
||||
}
|
||||
ODS.parse_ods = parse_ods;
|
||||
ODS.write_ods = write_ods;
|
||||
ODS.parse_fods = parse_fods;
|
||||
})(typeof exports !== 'undefined' ? exports : ODS);
|
||||
|
2
dist/ods.min.js
vendored
2
dist/ods.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/ods.min.map
vendored
2
dist/ods.min.map
vendored
File diff suppressed because one or more lines are too long
22
dist/xlsx.core.min.js
vendored
22
dist/xlsx.core.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
vendored
2
dist/xlsx.core.min.map
vendored
File diff suppressed because one or more lines are too long
22
dist/xlsx.full.min.js
vendored
22
dist/xlsx.full.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
vendored
2
dist/xlsx.full.min.map
vendored
File diff suppressed because one or more lines are too long
137
dist/xlsx.js
vendored
137
dist/xlsx.js
vendored
@ -4,7 +4,7 @@
|
||||
/*jshint funcscope:true, eqnull:true */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.8.4';
|
||||
XLSX.version = '0.8.5';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
|
||||
@ -651,7 +651,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
case '[':
|
||||
o = c;
|
||||
while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i];
|
||||
if(o.substr(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.slice(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.match(abstime)) {
|
||||
if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
|
||||
out[out.length] = {t:'Z', v:o.toLowerCase()};
|
||||
@ -1297,6 +1297,12 @@ function cc2str(arr) {
|
||||
return o;
|
||||
}
|
||||
|
||||
function str2cc(str) {
|
||||
var o = [];
|
||||
for(var i = 0; i != str.length; ++i) o.push(str.charCodeAt(i));
|
||||
return o;
|
||||
}
|
||||
|
||||
function dup(o) {
|
||||
if(typeof JSON != 'undefined') return JSON.parse(JSON.stringify(o));
|
||||
if(typeof o != 'object' || !o) return o;
|
||||
@ -1319,11 +1325,15 @@ function getdatabin(data) {
|
||||
if(!data) return null;
|
||||
if(data.data) return char_codes(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
|
||||
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
|
||||
if(data._data && data._data.getContent) {
|
||||
var o = data._data.getContent();
|
||||
if(typeof o == "string") return str2cc(o);
|
||||
return Array.prototype.slice.call(o);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getdata(data) { return (data && data.name.substr(data.name.length-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
|
||||
function safegetzipfile(zip, file) {
|
||||
var f = file; if(zip.files[f]) return zip.files[f];
|
||||
@ -1402,7 +1412,7 @@ var unescapexml = (function() {
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
|
||||
function escapexml(text){
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";});
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
|
||||
}
|
||||
|
||||
/* TODO: handle codepages */
|
||||
@ -1613,7 +1623,10 @@ function ReadShift(size, t) {
|
||||
case 'utf8': o = __utf8(this, this.l, this.l + size); break;
|
||||
case 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break;
|
||||
|
||||
case 'wstr': o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size)); size = 2 * size; break;
|
||||
case 'wstr':
|
||||
if(typeof cptable !== 'undefined') o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size));
|
||||
else return ReadShift.call(this, size, 'dbcs');
|
||||
o = size = 2 * size; break;
|
||||
|
||||
/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
|
||||
case 'lpstr': o = __lpstr(this, this.l); size = 5 + o.length; break;
|
||||
@ -8050,7 +8063,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
|
||||
/* 18.3.1.4 c CT_Cell */
|
||||
cells = x.substr(ri).split(cellregex);
|
||||
for(ri = typeof tag.r === 'undefined' ? 0 : 1; ri != cells.length; ++ri) {
|
||||
for(ri = 0; ri != cells.length; ++ri) {
|
||||
x = cells[ri].trim();
|
||||
if(x.length === 0) continue;
|
||||
cref = x.match(rregex); idx = ri; i=0; cc=0;
|
||||
@ -8691,7 +8704,7 @@ function write_ws_bin_cell(ba, cell, R, C, opts) {
|
||||
}
|
||||
var o = ({r:R, c:C});
|
||||
/* TODO: cell style */
|
||||
o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
//o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
switch(cell.t) {
|
||||
case 's': case 'str':
|
||||
if(opts.bookSST) {
|
||||
@ -9236,17 +9249,17 @@ function write_wb_bin(wb, opts) {
|
||||
return ba.end();
|
||||
}
|
||||
function parse_wb(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_wb_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_wb_bin((data), opts);
|
||||
return parse_wb_xml((data), opts);
|
||||
}
|
||||
|
||||
function parse_ws(data, name, opts, rels, wb) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_ws_bin((data), opts, rels, wb);
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data), opts, rels, wb);
|
||||
return parse_ws_xml((data), opts, rels, wb);
|
||||
}
|
||||
|
||||
function parse_sty(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_sty_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_sty_bin((data), opts);
|
||||
return parse_sty_xml((data), opts);
|
||||
}
|
||||
|
||||
@ -9255,42 +9268,42 @@ function parse_theme(data, name, opts) {
|
||||
}
|
||||
|
||||
function parse_sst(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_sst_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_sst_bin((data), opts);
|
||||
return parse_sst_xml((data), opts);
|
||||
}
|
||||
|
||||
function parse_cmnt(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_comments_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_comments_bin((data), opts);
|
||||
return parse_comments_xml((data), opts);
|
||||
}
|
||||
|
||||
function parse_cc(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_cc_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_cc_bin((data), opts);
|
||||
return parse_cc_xml((data), opts);
|
||||
}
|
||||
|
||||
function write_wb(wb, name, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||
}
|
||||
|
||||
function write_ws(data, name, opts, wb) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
|
||||
return (name.slice(-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
|
||||
}
|
||||
|
||||
function write_sty(data, name, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
|
||||
}
|
||||
|
||||
function write_sst(data, name, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
|
||||
}
|
||||
/*
|
||||
function write_cmnt(data, name:string, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
|
||||
}
|
||||
|
||||
function write_cc(data, name:string, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||
}
|
||||
*/
|
||||
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||
@ -9493,15 +9506,15 @@ function parse_xlml_xml(d, opts) {
|
||||
if(cell.Index) c = +cell.Index - 1;
|
||||
if(c < refguess.s.c) refguess.s.c = c;
|
||||
if(c > refguess.e.c) refguess.e.c = c;
|
||||
if(Rn[0].substr(-2) === "/>") ++c;
|
||||
if(Rn[0].slice(-2) === "/>") ++c;
|
||||
comments = [];
|
||||
}
|
||||
break;
|
||||
case 'Row':
|
||||
if(Rn[1]==='/' || Rn[0].substr(-2) === "/>") {
|
||||
if(Rn[1]==='/' || Rn[0].slice(-2) === "/>") {
|
||||
if(r < refguess.s.r) refguess.s.r = r;
|
||||
if(r > refguess.e.r) refguess.e.r = r;
|
||||
if(Rn[0].substr(-2) === "/>") {
|
||||
if(Rn[0].slice(-2) === "/>") {
|
||||
row = xlml_parsexmltag(Rn[0]);
|
||||
if(row.Index) r = +row.Index - 1;
|
||||
}
|
||||
@ -9567,7 +9580,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'Alignment': break;
|
||||
case 'Borders': break;
|
||||
case 'Font':
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") ss += str.slice(fidx, Rn.index);
|
||||
else fidx = Rn.index + Rn[0].length;
|
||||
break;
|
||||
@ -9593,7 +9606,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'TotalTime':
|
||||
case 'HyperlinkBase':
|
||||
case 'Manager':
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") xlml_set_prop(Props, Rn[3], str.slice(pidx, Rn.index));
|
||||
else pidx = Rn.index + Rn[0].length;
|
||||
break;
|
||||
@ -9645,6 +9658,11 @@ function parse_xlml_xml(d, opts) {
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FODS file root is <office:document> */
|
||||
if(state.length == 0 && Rn[3] == "document") return parse_fods(str, opts);
|
||||
/* UOS file root is <uof:UOF> */
|
||||
if(state.length == 0 && Rn[3] == "UOF") return parse_fods(str, opts);
|
||||
|
||||
var seen = true;
|
||||
switch(state[state.length-1][0]) {
|
||||
/* OfficeDocumentSettings */
|
||||
@ -9982,7 +10000,7 @@ function parse_xlml_xml(d, opts) {
|
||||
/* CustomDocumentProperties */
|
||||
if(!state[state.length-1][1]) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
|
||||
if(state[state.length-1][0]==='CustomDocumentProperties') {
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") xlml_set_custprop(Custprops, Rn, cp, str.slice(pidx, Rn.index));
|
||||
else { cp = Rn; pidx = Rn.index + Rn[0].length; }
|
||||
break;
|
||||
@ -10007,6 +10025,7 @@ function parse_xlml(data, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
function write_xlml(wb, opts) {
|
||||
var o = [XML_HEADER];
|
||||
return o.join("");
|
||||
@ -12067,20 +12086,12 @@ function write_biff_buf(wb, o) {
|
||||
// TODO
|
||||
return ba.end();
|
||||
}
|
||||
|
||||
function write_biff(wb, o) {
|
||||
var out = write_biff_buf(wb, o);
|
||||
switch(o.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": {
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
}
|
||||
case "file": return _fs.writeFileSync(o.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
/* actual implementation in utils, wrappers are for read/write */
|
||||
function write_csv_str(wb, o) {
|
||||
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);
|
||||
return sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o);
|
||||
}
|
||||
/* Helper functions to call out to ODS */
|
||||
function parse_ods(zip, opts) {
|
||||
@ -12093,6 +12104,11 @@ function write_ods(wb, opts) {
|
||||
if(typeof ODS === 'undefined' || !ODS.write_ods) throw new Error("Unsupported ODS");
|
||||
return ODS.write_ods(wb, opts);
|
||||
}
|
||||
function parse_fods(data, opts) {
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined' && typeof ODS === 'undefined') ODS = require('./od' + 's');
|
||||
if(typeof ODS === 'undefined' || !ODS.parse_fods) throw new Error("Unsupported ODS");
|
||||
return ODS.parse_fods(data, opts);
|
||||
}
|
||||
function fix_opts_func(defaults) {
|
||||
return function fix_opts(opts) {
|
||||
for(var i = 0; i != defaults.length; ++i) {
|
||||
@ -12150,7 +12166,7 @@ function safe_parse_ws(zip, path, relsPath, sheet, sheetRels, sheets, opts, wb)
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
|
||||
var nodirs = function nodirs(x){return x.substr(-1) != '/';};
|
||||
var nodirs = function nodirs(x){return x.slice(-1) != '/';};
|
||||
function parse_zip(zip, opts) {
|
||||
make_ssf(SSF);
|
||||
opts = opts || {};
|
||||
@ -12159,6 +12175,8 @@ function parse_zip(zip, opts) {
|
||||
|
||||
/* OpenDocument Part 3 Section 2.2.1 OpenDocument Package */
|
||||
if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
|
||||
/* UOC */
|
||||
if(safegetzipfile(zip, 'objectdata.xml')) return parse_ods(zip, opts);
|
||||
|
||||
var entries = keys(zip.files).filter(nodirs).sort();
|
||||
var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')), opts);
|
||||
@ -12174,7 +12192,7 @@ function parse_zip(zip, opts) {
|
||||
dir.workbooks.push(binname);
|
||||
xlsb = true;
|
||||
}
|
||||
if(dir.workbooks[0].substr(-3) == "bin") xlsb = true;
|
||||
if(dir.workbooks[0].slice(-3) == "bin") xlsb = true;
|
||||
if(xlsb) set_cp(1200);
|
||||
|
||||
if(!opts.bookSheets && !opts.bookProps) {
|
||||
@ -12424,11 +12442,36 @@ function write_zip_type(wb, opts) {
|
||||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
function write_string_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": break; // TODO
|
||||
case "file": return _fs.writeFileSync(opts.file, out, {encoding:'utf8'});
|
||||
case "buffer": break; // TODO
|
||||
default: return out;
|
||||
}
|
||||
}
|
||||
|
||||
function write_binary_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
}
|
||||
|
||||
function writeSync(wb, opts) {
|
||||
var o = opts||{};
|
||||
switch(o.bookType) {
|
||||
case 'xml': return write_xlml(wb, o);
|
||||
case 'biff2': return write_biff(wb, o);
|
||||
case 'xml': return write_string_type(write_xlml(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_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);
|
||||
default: return write_zip_type(wb, o);
|
||||
}
|
||||
}
|
||||
@ -12436,14 +12479,16 @@ function writeSync(wb, opts) {
|
||||
function writeFileSync(wb, filename, opts) {
|
||||
var o = opts||{}; o.type = 'file';
|
||||
o.file = filename;
|
||||
if(!o.bookType) switch(o.file.substr(-5).toLowerCase()) {
|
||||
if(!o.bookType) switch(o.file.slice(-5).toLowerCase()) {
|
||||
case '.xlsx': o.bookType = 'xlsx'; break;
|
||||
case '.xlsm': o.bookType = 'xlsm'; break;
|
||||
case '.xlsb': o.bookType = 'xlsb'; break;
|
||||
default: switch(o.file.substr(-4).toLowerCase()) {
|
||||
case '.fods': o.bookType = 'fods'; break;
|
||||
default: switch(o.file.slice(-4).toLowerCase()) {
|
||||
case '.xls': o.bookType = 'biff2'; break;
|
||||
case '.xml': o.bookType = 'xml'; break;
|
||||
case '.ods': o.bookType = 'ods'; break;
|
||||
case '.csv': o.bookType = 'csv'; break;
|
||||
}}
|
||||
return writeSync(wb, o);
|
||||
}
|
||||
|
20
dist/xlsx.min.js
vendored
20
dist/xlsx.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
vendored
2
dist/xlsx.min.map
vendored
File diff suppressed because one or more lines are too long
112
ods.flow.js
112
ods.flow.js
@ -67,7 +67,7 @@ if (typeof exports !== 'undefined') {
|
||||
_fs = require('f'+'s');
|
||||
}
|
||||
}
|
||||
var attregexg=/\b[\w:-]+=["'][^"]*['"]/g;
|
||||
var attregexg=/[^\s?>\/]+=["'][^"]*['"]/g;
|
||||
var tagregex=/<[^>]*>/g;
|
||||
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
|
||||
function parsexmltag(tag, skip_root) {
|
||||
@ -82,8 +82,15 @@ function parsexmltag(tag, skip_root) {
|
||||
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
|
||||
q = cc.substr(0,c); v = cc.substring(c+2, cc.length-1);
|
||||
for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break;
|
||||
if(j===q.length) z[q] = v;
|
||||
else z[(j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1)] = v;
|
||||
if(j===q.length) {
|
||||
if(q.indexOf("_") > 0) q = q.substr(0, q.indexOf("_"));
|
||||
z[q] = v;
|
||||
}
|
||||
else {
|
||||
var k = (j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1);
|
||||
if(z[k] && q.substr(j-3,3) == "ext") continue;
|
||||
z[k] = v;
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
@ -165,7 +172,8 @@ function xlml_normalize(d) {
|
||||
throw "badf";
|
||||
}
|
||||
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/mg;
|
||||
/* UOS uses CJK in tags, original regex /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/ */
|
||||
var xlmlregex = /<(\/?)([^\s?>\/:]*:|)([^\s?>]*[^\s?>\/])[^>]*>/mg;
|
||||
/* Part 3 Section 4 Manifest File */
|
||||
var CT_ODS = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
function parse_manifest(d, opts) {
|
||||
@ -222,7 +230,7 @@ function write_rdf(rdf, opts) {
|
||||
return o.join("");
|
||||
}
|
||||
var parse_text_p = function(text, tag) {
|
||||
return unescapexml(utf8read(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,"")));
|
||||
return unescapexml(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,""));
|
||||
};
|
||||
|
||||
var utf8read = function utf8reada(orig) {
|
||||
@ -272,6 +280,7 @@ var parse_content_xml = (function() {
|
||||
var tag/*:: = {}*/;
|
||||
var NFtag = {name:""}, NF = "", pidx = 0;
|
||||
var sheetag/*:: = {name:""}*/;
|
||||
var rowtag/*:: = {'行号':""}*/;
|
||||
var Sheets = {}, SheetNames/*:Array<string>*/ = [], ws = {};
|
||||
var Rn, q/*:: = ({t:"", v:null, z:null, w:""}:any)*/;
|
||||
var ctag = {value:""};
|
||||
@ -283,13 +292,13 @@ var parse_content_xml = (function() {
|
||||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]=Rn[3].replace(/_.*$/,"")) {
|
||||
|
||||
case 'table': // 9.1.2 <table:table>
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
if(range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = get_utils().encode_range(range);
|
||||
if(merges.length) ws['!merges'] = merges;
|
||||
sheetag.name = utf8read(sheetag.name);
|
||||
sheetag.name = utf8read(sheetag['名称'] || sheetag.name);
|
||||
SheetNames.push(sheetag.name);
|
||||
Sheets[sheetag.name] = ws;
|
||||
}
|
||||
@ -301,12 +310,14 @@ var parse_content_xml = (function() {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'table-row': // 9.1.3 <table:table-row>
|
||||
case 'table-row': case '行': // 9.1.3 <table:table-row>
|
||||
if(Rn[1] === '/') break;
|
||||
++R; C = -1; break;
|
||||
rowtag = parsexmltag(Rn[0], false);
|
||||
if(rowtag['行号']) R = rowtag['行号'] - 1; else ++R;
|
||||
C = -1; break;
|
||||
case 'covered-table-cell': // 9.1.5 table:covered-table-cell
|
||||
++C; break; /* stub */
|
||||
case 'table-cell':
|
||||
case 'table-cell': case '数据':
|
||||
if(Rn[0].charAt(Rn[0].length-2) === '/') {
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
if(ctag['number-columns-repeated']) C+= parseInt(ctag['number-columns-repeated'], 10);
|
||||
@ -320,7 +331,7 @@ var parse_content_xml = (function() {
|
||||
if(C < range.s.c) range.s.c = C;
|
||||
if(R < range.s.r) range.s.r = R;
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
q = ({t:ctag['value-type'], v:null/*:: , z:null, w:""*/}/*:any*/);
|
||||
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null/*:: , z:null, w:""*/}/*:any*/);
|
||||
if(opts.cellFormula) {
|
||||
if(ctag['number-matrix-columns-spanned'] && ctag['number-matrix-rows-spanned']) {
|
||||
mR = parseInt(ctag['number-matrix-rows-spanned'],10) || 0;
|
||||
@ -353,8 +364,9 @@ var parse_content_xml = (function() {
|
||||
case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
||||
case 'date': q.t = 'n'; q.v = datenum(ctag['date-value']); q.z = 'm/d/yy'; break;
|
||||
case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400; break;
|
||||
case 'number': q.t = 'n'; q.v = parseFloat(ctag['数据数值']); break;
|
||||
default:
|
||||
if(q.t === 'string' || !q.t) {
|
||||
if(q.t === 'string' || q.t === 'text' || !q.t) {
|
||||
q.t = 's';
|
||||
if(ctag['string-value'] != null) textp = ctag['string-value'];
|
||||
} else throw new Error('Unsupported value type ' + q.t);
|
||||
@ -379,15 +391,23 @@ var parse_content_xml = (function() {
|
||||
break; // 9.1.4 <table:table-cell>
|
||||
|
||||
/* pure state */
|
||||
case 'document-content': // 3.1.3.2 <office:document-content>
|
||||
case 'spreadsheet': // 3.7 <office:spreadsheet>
|
||||
case 'document': // TODO: <office:document> is the root for FODS
|
||||
case 'document-content': case '电子表格文档': // 3.1.3.2 <office:document-content>
|
||||
case 'spreadsheet': case '主体': // 3.7 <office:spreadsheet>
|
||||
case 'scripts': // 3.12 <office:scripts>
|
||||
case 'styles': // TODO <office:styles>
|
||||
case 'font-face-decls': // 3.14 <office:font-face-decls>
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
|
||||
break;
|
||||
|
||||
/* ignore state */
|
||||
case 'meta': case '元数据': // TODO: <office:meta> <uof:元数据> FODS/UOF
|
||||
case 'settings': // TODO: <office:settings>
|
||||
case 'config-item-set': // TODO: <office:config-item-set>
|
||||
case 'config-item-map-indexed': // TODO: <office:config-item-map-indexed>
|
||||
case 'config-item-map-entry': // TODO: <office:config-item-map-entry>
|
||||
case 'config-item-map-named': // TODO: <office:config-item-map-entry>
|
||||
case 'shapes': // 9.2.8 <table:shapes>
|
||||
case 'frame': // 10.4.2 <draw:frame>
|
||||
case 'text-box': // 10.4.3 <draw:text-box>
|
||||
@ -397,11 +417,18 @@ var parse_content_xml = (function() {
|
||||
case 'form': // 13.13 <form:form>
|
||||
case 'dde-links': // 9.8 <table:dde-links>
|
||||
case 'annotation': // 14.1 <office:annotation>
|
||||
case 'event-listeners': // TODO
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], false]);
|
||||
textp = ""; textpidx = 0;
|
||||
break;
|
||||
|
||||
case 'scientific-number': // TODO: <number:scientific-number>
|
||||
break;
|
||||
case 'currency-symbol': // TODO: <number:currency-symbol>
|
||||
break;
|
||||
case 'currency-style': // TODO: <number:currency-style>
|
||||
break;
|
||||
case 'number-style': // 16.27.2 <number:number-style>
|
||||
case 'percentage-style': // 16.27.9 <number:percentage-style>
|
||||
case 'date-style': // 16.27.10 <number:date-style>
|
||||
@ -416,8 +443,12 @@ var parse_content_xml = (function() {
|
||||
} break;
|
||||
|
||||
case 'script': break; // 3.13 <office:script>
|
||||
case 'libraries': break; // TODO: <ooo:libraries>
|
||||
case 'automatic-styles': break; // 3.15.3 <office:automatic-styles>
|
||||
case 'master-styles': break; // TODO: <office:automatic-styles>
|
||||
|
||||
case 'default-style': // TODO: <style:default-style>
|
||||
case 'page-layout': break; // TODO: <style:page-layout>
|
||||
case 'style': break; // 16.2 <style:style>
|
||||
case 'map': break; // 16.3 <style:map>
|
||||
case 'font-face': break; // 16.21 <style:font-face>
|
||||
@ -460,7 +491,7 @@ var parse_content_xml = (function() {
|
||||
case 'boolean': break; // 16.27.24 <number:boolean>
|
||||
case 'text-style': break; // 16.27.25 <number:text-style>
|
||||
case 'text': // 16.27.26 <number:text>
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") switch(state[state.length-1][0]) {
|
||||
case 'number-style':
|
||||
case 'date-style':
|
||||
@ -473,7 +504,7 @@ var parse_content_xml = (function() {
|
||||
case 'text-content': break; // 16.27.27 <number:text-content>
|
||||
case 'text-properties': break; // 16.27.27 <style:text-properties>
|
||||
|
||||
case 'body': break; // 3.3 16.9.6 19.726.3
|
||||
case 'body': case '电子表格': break; // 3.3 16.9.6 19.726.3
|
||||
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
@ -491,7 +522,7 @@ var parse_content_xml = (function() {
|
||||
|
||||
case 'span': break; // <text:span>
|
||||
case 'line-break': break; // 6.1.5 <text:line-break>
|
||||
case 'p':
|
||||
case 'p': case '文本串':
|
||||
if(Rn[1]==='/') textp = parse_text_p(str.slice(textpidx,Rn.index), textptag);
|
||||
else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
|
||||
break; // <text:p>
|
||||
@ -499,7 +530,7 @@ var parse_content_xml = (function() {
|
||||
case 'date': break; // <*:date>
|
||||
|
||||
case 'object': break; // 10.4.6.2 <draw:object>
|
||||
case 'title': break; // <*:title>
|
||||
case 'title': case '标题': break; // <*:title> OR <uof:标题>
|
||||
case 'desc': break; // <*:desc>
|
||||
|
||||
case 'table-source': break; // 9.2.6
|
||||
@ -543,6 +574,25 @@ var parse_content_xml = (function() {
|
||||
case 'sheet-name': // 7.3.9
|
||||
break;
|
||||
|
||||
case 'event-listener': // TODO
|
||||
/* TODO: FODS Properties */
|
||||
case 'initial-creator':
|
||||
case 'creator':
|
||||
case 'creation-date':
|
||||
case 'generator':
|
||||
case 'document-statistic':
|
||||
case 'user-defined':
|
||||
break;
|
||||
|
||||
/* TODO: FODS Config */
|
||||
case 'config-item':
|
||||
break;
|
||||
|
||||
/* TODO: style tokens */
|
||||
case 'page-number': break; // TODO <text:page-number>
|
||||
case 'page-count': break; // TODO <text:page-count>
|
||||
case 'time': break; // TODO <text:time>
|
||||
|
||||
/* 9.6 Data Pilot Tables <table: */
|
||||
case 'data-pilot-table': // 9.6.3
|
||||
case 'source-cell-range': // 9.6.5
|
||||
@ -584,7 +634,12 @@ var parse_content_xml = (function() {
|
||||
default:
|
||||
if(Rn[2] === 'dc:') break; // TODO: properties
|
||||
if(Rn[2] === 'draw:') break; // TODO: drawing
|
||||
if(Rn[2] === 'style:') break; // TODO: styles
|
||||
if(Rn[2] === 'calcext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'loext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'uof:') break; // TODO: uof
|
||||
if(Rn[2] === '表:') break; // TODO: uof
|
||||
if(Rn[2] === '字:') break; // TODO: uof
|
||||
if(opts.WTF) throw Rn;
|
||||
}
|
||||
var out = {
|
||||
@ -625,23 +680,33 @@ var write_content_xml/*:{(wb:any, opts:any):string}*/ = (function() {
|
||||
return function wcx(wb, opts) {
|
||||
var o = [XML_HEADER];
|
||||
/* 3.1.3.2 */
|
||||
o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
if(opts.bookType == "fods") o.push('<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.spreadsheet">');
|
||||
else o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
o.push(' <office:body>\n');
|
||||
o.push(' <office:spreadsheet>\n');
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts));
|
||||
o.push(' </office:spreadsheet>\n');
|
||||
o.push(' </office:body>\n');
|
||||
o.push('</office:document-content>');
|
||||
if(opts.bookType == "fods") o.push('</office:document>');
|
||||
else o.push('</office:document-content>');
|
||||
return o.join("");
|
||||
};
|
||||
})();
|
||||
/* Part 3: Packages */
|
||||
function parse_ods(zip/*:ZIPFile*/, opts/*:?ParseOpts*/) {
|
||||
opts = opts || ({}/*:any*/);
|
||||
var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
return parse_content_xml(getzipdata(zip, 'content.xml'), opts);
|
||||
var ods = !!safegetzipfile(zip, 'objectdata');
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
var content = getzipdata(zip, 'content.xml');
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
}
|
||||
|
||||
function parse_fods(data/*:string*/, opts/*:?ParseOpts*/) {
|
||||
return parse_content_xml(data, opts);
|
||||
}
|
||||
function write_ods(wb/*:any*/, opts/*:any*/) {
|
||||
if(opts.bookType == "fods") return write_content_xml(wb, opts);
|
||||
|
||||
/*:: if(!jszip) throw new Error("JSZip is not available"); */
|
||||
var zip = new jszip();
|
||||
var f = "";
|
||||
@ -672,4 +737,5 @@ function write_ods(wb/*:any*/, opts/*:any*/) {
|
||||
}
|
||||
ODS.parse_ods = parse_ods;
|
||||
ODS.write_ods = write_ods;
|
||||
ODS.parse_fods = parse_fods;
|
||||
})(typeof exports !== 'undefined' ? exports : ODS);
|
||||
|
112
ods.js
112
ods.js
@ -65,7 +65,7 @@ if (typeof exports !== 'undefined') {
|
||||
_fs = require('f'+'s');
|
||||
}
|
||||
}
|
||||
var attregexg=/\b[\w:-]+=["'][^"]*['"]/g;
|
||||
var attregexg=/[^\s?>\/]+=["'][^"]*['"]/g;
|
||||
var tagregex=/<[^>]*>/g;
|
||||
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
|
||||
function parsexmltag(tag, skip_root) {
|
||||
@ -80,8 +80,15 @@ function parsexmltag(tag, skip_root) {
|
||||
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
|
||||
q = cc.substr(0,c); v = cc.substring(c+2, cc.length-1);
|
||||
for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break;
|
||||
if(j===q.length) z[q] = v;
|
||||
else z[(j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1)] = v;
|
||||
if(j===q.length) {
|
||||
if(q.indexOf("_") > 0) q = q.substr(0, q.indexOf("_"));
|
||||
z[q] = v;
|
||||
}
|
||||
else {
|
||||
var k = (j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1);
|
||||
if(z[k] && q.substr(j-3,3) == "ext") continue;
|
||||
z[k] = v;
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
@ -163,7 +170,8 @@ function xlml_normalize(d) {
|
||||
throw "badf";
|
||||
}
|
||||
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/mg;
|
||||
/* UOS uses CJK in tags, original regex /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/ */
|
||||
var xlmlregex = /<(\/?)([^\s?>\/:]*:|)([^\s?>]*[^\s?>\/])[^>]*>/mg;
|
||||
/* Part 3 Section 4 Manifest File */
|
||||
var CT_ODS = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
function parse_manifest(d, opts) {
|
||||
@ -220,7 +228,7 @@ function write_rdf(rdf, opts) {
|
||||
return o.join("");
|
||||
}
|
||||
var parse_text_p = function(text, tag) {
|
||||
return unescapexml(utf8read(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,"")));
|
||||
return unescapexml(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,""));
|
||||
};
|
||||
|
||||
var utf8read = function utf8reada(orig) {
|
||||
@ -270,6 +278,7 @@ var parse_content_xml = (function() {
|
||||
var tag;
|
||||
var NFtag = {name:""}, NF = "", pidx = 0;
|
||||
var sheetag;
|
||||
var rowtag;
|
||||
var Sheets = {}, SheetNames = [], ws = {};
|
||||
var Rn, q;
|
||||
var ctag = {value:""};
|
||||
@ -281,13 +290,13 @@ var parse_content_xml = (function() {
|
||||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]=Rn[3].replace(/_.*$/,"")) {
|
||||
|
||||
case 'table': // 9.1.2 <table:table>
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
if(range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = get_utils().encode_range(range);
|
||||
if(merges.length) ws['!merges'] = merges;
|
||||
sheetag.name = utf8read(sheetag.name);
|
||||
sheetag.name = utf8read(sheetag['名称'] || sheetag.name);
|
||||
SheetNames.push(sheetag.name);
|
||||
Sheets[sheetag.name] = ws;
|
||||
}
|
||||
@ -299,12 +308,14 @@ var parse_content_xml = (function() {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'table-row': // 9.1.3 <table:table-row>
|
||||
case 'table-row': case '行': // 9.1.3 <table:table-row>
|
||||
if(Rn[1] === '/') break;
|
||||
++R; C = -1; break;
|
||||
rowtag = parsexmltag(Rn[0], false);
|
||||
if(rowtag['行号']) R = rowtag['行号'] - 1; else ++R;
|
||||
C = -1; break;
|
||||
case 'covered-table-cell': // 9.1.5 table:covered-table-cell
|
||||
++C; break; /* stub */
|
||||
case 'table-cell':
|
||||
case 'table-cell': case '数据':
|
||||
if(Rn[0].charAt(Rn[0].length-2) === '/') {
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
if(ctag['number-columns-repeated']) C+= parseInt(ctag['number-columns-repeated'], 10);
|
||||
@ -318,7 +329,7 @@ var parse_content_xml = (function() {
|
||||
if(C < range.s.c) range.s.c = C;
|
||||
if(R < range.s.r) range.s.r = R;
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
q = ({t:ctag['value-type'], v:null});
|
||||
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null});
|
||||
if(opts.cellFormula) {
|
||||
if(ctag['number-matrix-columns-spanned'] && ctag['number-matrix-rows-spanned']) {
|
||||
mR = parseInt(ctag['number-matrix-rows-spanned'],10) || 0;
|
||||
@ -351,8 +362,9 @@ var parse_content_xml = (function() {
|
||||
case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
||||
case 'date': q.t = 'n'; q.v = datenum(ctag['date-value']); q.z = 'm/d/yy'; break;
|
||||
case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400; break;
|
||||
case 'number': q.t = 'n'; q.v = parseFloat(ctag['数据数值']); break;
|
||||
default:
|
||||
if(q.t === 'string' || !q.t) {
|
||||
if(q.t === 'string' || q.t === 'text' || !q.t) {
|
||||
q.t = 's';
|
||||
if(ctag['string-value'] != null) textp = ctag['string-value'];
|
||||
} else throw new Error('Unsupported value type ' + q.t);
|
||||
@ -377,15 +389,23 @@ var parse_content_xml = (function() {
|
||||
break; // 9.1.4 <table:table-cell>
|
||||
|
||||
/* pure state */
|
||||
case 'document-content': // 3.1.3.2 <office:document-content>
|
||||
case 'spreadsheet': // 3.7 <office:spreadsheet>
|
||||
case 'document': // TODO: <office:document> is the root for FODS
|
||||
case 'document-content': case '电子表格文档': // 3.1.3.2 <office:document-content>
|
||||
case 'spreadsheet': case '主体': // 3.7 <office:spreadsheet>
|
||||
case 'scripts': // 3.12 <office:scripts>
|
||||
case 'styles': // TODO <office:styles>
|
||||
case 'font-face-decls': // 3.14 <office:font-face-decls>
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
|
||||
break;
|
||||
|
||||
/* ignore state */
|
||||
case 'meta': case '元数据': // TODO: <office:meta> <uof:元数据> FODS/UOF
|
||||
case 'settings': // TODO: <office:settings>
|
||||
case 'config-item-set': // TODO: <office:config-item-set>
|
||||
case 'config-item-map-indexed': // TODO: <office:config-item-map-indexed>
|
||||
case 'config-item-map-entry': // TODO: <office:config-item-map-entry>
|
||||
case 'config-item-map-named': // TODO: <office:config-item-map-entry>
|
||||
case 'shapes': // 9.2.8 <table:shapes>
|
||||
case 'frame': // 10.4.2 <draw:frame>
|
||||
case 'text-box': // 10.4.3 <draw:text-box>
|
||||
@ -395,11 +415,18 @@ var parse_content_xml = (function() {
|
||||
case 'form': // 13.13 <form:form>
|
||||
case 'dde-links': // 9.8 <table:dde-links>
|
||||
case 'annotation': // 14.1 <office:annotation>
|
||||
case 'event-listeners': // TODO
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], false]);
|
||||
textp = ""; textpidx = 0;
|
||||
break;
|
||||
|
||||
case 'scientific-number': // TODO: <number:scientific-number>
|
||||
break;
|
||||
case 'currency-symbol': // TODO: <number:currency-symbol>
|
||||
break;
|
||||
case 'currency-style': // TODO: <number:currency-style>
|
||||
break;
|
||||
case 'number-style': // 16.27.2 <number:number-style>
|
||||
case 'percentage-style': // 16.27.9 <number:percentage-style>
|
||||
case 'date-style': // 16.27.10 <number:date-style>
|
||||
@ -414,8 +441,12 @@ var parse_content_xml = (function() {
|
||||
} break;
|
||||
|
||||
case 'script': break; // 3.13 <office:script>
|
||||
case 'libraries': break; // TODO: <ooo:libraries>
|
||||
case 'automatic-styles': break; // 3.15.3 <office:automatic-styles>
|
||||
case 'master-styles': break; // TODO: <office:automatic-styles>
|
||||
|
||||
case 'default-style': // TODO: <style:default-style>
|
||||
case 'page-layout': break; // TODO: <style:page-layout>
|
||||
case 'style': break; // 16.2 <style:style>
|
||||
case 'map': break; // 16.3 <style:map>
|
||||
case 'font-face': break; // 16.21 <style:font-face>
|
||||
@ -458,7 +489,7 @@ var parse_content_xml = (function() {
|
||||
case 'boolean': break; // 16.27.24 <number:boolean>
|
||||
case 'text-style': break; // 16.27.25 <number:text-style>
|
||||
case 'text': // 16.27.26 <number:text>
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") switch(state[state.length-1][0]) {
|
||||
case 'number-style':
|
||||
case 'date-style':
|
||||
@ -471,7 +502,7 @@ var parse_content_xml = (function() {
|
||||
case 'text-content': break; // 16.27.27 <number:text-content>
|
||||
case 'text-properties': break; // 16.27.27 <style:text-properties>
|
||||
|
||||
case 'body': break; // 3.3 16.9.6 19.726.3
|
||||
case 'body': case '电子表格': break; // 3.3 16.9.6 19.726.3
|
||||
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
@ -489,7 +520,7 @@ var parse_content_xml = (function() {
|
||||
|
||||
case 'span': break; // <text:span>
|
||||
case 'line-break': break; // 6.1.5 <text:line-break>
|
||||
case 'p':
|
||||
case 'p': case '文本串':
|
||||
if(Rn[1]==='/') textp = parse_text_p(str.slice(textpidx,Rn.index), textptag);
|
||||
else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
|
||||
break; // <text:p>
|
||||
@ -497,7 +528,7 @@ var parse_content_xml = (function() {
|
||||
case 'date': break; // <*:date>
|
||||
|
||||
case 'object': break; // 10.4.6.2 <draw:object>
|
||||
case 'title': break; // <*:title>
|
||||
case 'title': case '标题': break; // <*:title> OR <uof:标题>
|
||||
case 'desc': break; // <*:desc>
|
||||
|
||||
case 'table-source': break; // 9.2.6
|
||||
@ -541,6 +572,25 @@ var parse_content_xml = (function() {
|
||||
case 'sheet-name': // 7.3.9
|
||||
break;
|
||||
|
||||
case 'event-listener': // TODO
|
||||
/* TODO: FODS Properties */
|
||||
case 'initial-creator':
|
||||
case 'creator':
|
||||
case 'creation-date':
|
||||
case 'generator':
|
||||
case 'document-statistic':
|
||||
case 'user-defined':
|
||||
break;
|
||||
|
||||
/* TODO: FODS Config */
|
||||
case 'config-item':
|
||||
break;
|
||||
|
||||
/* TODO: style tokens */
|
||||
case 'page-number': break; // TODO <text:page-number>
|
||||
case 'page-count': break; // TODO <text:page-count>
|
||||
case 'time': break; // TODO <text:time>
|
||||
|
||||
/* 9.6 Data Pilot Tables <table: */
|
||||
case 'data-pilot-table': // 9.6.3
|
||||
case 'source-cell-range': // 9.6.5
|
||||
@ -582,7 +632,12 @@ var parse_content_xml = (function() {
|
||||
default:
|
||||
if(Rn[2] === 'dc:') break; // TODO: properties
|
||||
if(Rn[2] === 'draw:') break; // TODO: drawing
|
||||
if(Rn[2] === 'style:') break; // TODO: styles
|
||||
if(Rn[2] === 'calcext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'loext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'uof:') break; // TODO: uof
|
||||
if(Rn[2] === '表:') break; // TODO: uof
|
||||
if(Rn[2] === '字:') break; // TODO: uof
|
||||
if(opts.WTF) throw Rn;
|
||||
}
|
||||
var out = {
|
||||
@ -623,23 +678,33 @@ var write_content_xml = (function() {
|
||||
return function wcx(wb, opts) {
|
||||
var o = [XML_HEADER];
|
||||
/* 3.1.3.2 */
|
||||
o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
if(opts.bookType == "fods") o.push('<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.spreadsheet">');
|
||||
else o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
o.push(' <office:body>\n');
|
||||
o.push(' <office:spreadsheet>\n');
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts));
|
||||
o.push(' </office:spreadsheet>\n');
|
||||
o.push(' </office:body>\n');
|
||||
o.push('</office:document-content>');
|
||||
if(opts.bookType == "fods") o.push('</office:document>');
|
||||
else o.push('</office:document-content>');
|
||||
return o.join("");
|
||||
};
|
||||
})();
|
||||
/* Part 3: Packages */
|
||||
function parse_ods(zip, opts) {
|
||||
opts = opts || ({});
|
||||
var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
return parse_content_xml(getzipdata(zip, 'content.xml'), opts);
|
||||
var ods = !!safegetzipfile(zip, 'objectdata');
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
var content = getzipdata(zip, 'content.xml');
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
}
|
||||
|
||||
function parse_fods(data, opts) {
|
||||
return parse_content_xml(data, opts);
|
||||
}
|
||||
function write_ods(wb, opts) {
|
||||
if(opts.bookType == "fods") return write_content_xml(wb, opts);
|
||||
|
||||
var zip = new jszip();
|
||||
var f = "";
|
||||
|
||||
@ -669,4 +734,5 @@ var zip = new jszip();
|
||||
}
|
||||
ODS.parse_ods = parse_ods;
|
||||
ODS.write_ods = write_ods;
|
||||
ODS.parse_fods = parse_fods;
|
||||
})(typeof exports !== 'undefined' ? exports : ODS);
|
||||
|
@ -1,4 +1,4 @@
|
||||
var attregexg=/\b[\w:-]+=["'][^"]*['"]/g;
|
||||
var attregexg=/[^\s?>\/]+=["'][^"]*['"]/g;
|
||||
var tagregex=/<[^>]*>/g;
|
||||
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
|
||||
function parsexmltag(tag, skip_root) {
|
||||
@ -13,8 +13,15 @@ function parsexmltag(tag, skip_root) {
|
||||
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
|
||||
q = cc.substr(0,c); v = cc.substring(c+2, cc.length-1);
|
||||
for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break;
|
||||
if(j===q.length) z[q] = v;
|
||||
else z[(j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1)] = v;
|
||||
if(j===q.length) {
|
||||
if(q.indexOf("_") > 0) q = q.substr(0, q.indexOf("_"));
|
||||
z[q] = v;
|
||||
}
|
||||
else {
|
||||
var k = (j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1);
|
||||
if(z[k] && q.substr(j-3,3) == "ext") continue;
|
||||
z[k] = v;
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
@ -5,4 +5,5 @@ function xlml_normalize(d) {
|
||||
throw "badf";
|
||||
}
|
||||
|
||||
var xlmlregex = /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/mg;
|
||||
/* UOS uses CJK in tags, original regex /<(\/?)([a-z0-9]*:|)([\w-]+)[^>]*>/ */
|
||||
var xlmlregex = /<(\/?)([^\s?>\/:]*:|)([^\s?>]*[^\s?>\/])[^>]*>/mg;
|
||||
|
@ -1,5 +1,5 @@
|
||||
var parse_text_p = function(text, tag) {
|
||||
return unescapexml(utf8read(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,"")));
|
||||
return unescapexml(text.replace(/<text:s\/>/g," ").replace(/<[^>]*>/g,""));
|
||||
};
|
||||
|
||||
var utf8read = function utf8reada(orig) {
|
||||
|
@ -18,6 +18,7 @@ var parse_content_xml = (function() {
|
||||
var tag/*:: = {}*/;
|
||||
var NFtag = {name:""}, NF = "", pidx = 0;
|
||||
var sheetag/*:: = {name:""}*/;
|
||||
var rowtag/*:: = {'行号':""}*/;
|
||||
var Sheets = {}, SheetNames/*:Array<string>*/ = [], ws = {};
|
||||
var Rn, q/*:: = ({t:"", v:null, z:null, w:""}:any)*/;
|
||||
var ctag = {value:""};
|
||||
@ -29,13 +30,13 @@ var parse_content_xml = (function() {
|
||||
var rept = 1, isstub = false;
|
||||
var i = 0;
|
||||
xlmlregex.lastIndex = 0;
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
|
||||
while((Rn = xlmlregex.exec(str))) switch(Rn[3]=Rn[3].replace(/_.*$/,"")) {
|
||||
|
||||
case 'table': // 9.1.2 <table:table>
|
||||
case 'table': case '工作表': // 9.1.2 <table:table>
|
||||
if(Rn[1]==='/') {
|
||||
if(range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = get_utils().encode_range(range);
|
||||
if(merges.length) ws['!merges'] = merges;
|
||||
sheetag.name = utf8read(sheetag.name);
|
||||
sheetag.name = utf8read(sheetag['名称'] || sheetag.name);
|
||||
SheetNames.push(sheetag.name);
|
||||
Sheets[sheetag.name] = ws;
|
||||
}
|
||||
@ -47,12 +48,14 @@ var parse_content_xml = (function() {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'table-row': // 9.1.3 <table:table-row>
|
||||
case 'table-row': case '行': // 9.1.3 <table:table-row>
|
||||
if(Rn[1] === '/') break;
|
||||
++R; C = -1; break;
|
||||
rowtag = parsexmltag(Rn[0], false);
|
||||
if(rowtag['行号']) R = rowtag['行号'] - 1; else ++R;
|
||||
C = -1; break;
|
||||
case 'covered-table-cell': // 9.1.5 table:covered-table-cell
|
||||
++C; break; /* stub */
|
||||
case 'table-cell':
|
||||
case 'table-cell': case '数据':
|
||||
if(Rn[0].charAt(Rn[0].length-2) === '/') {
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
if(ctag['number-columns-repeated']) C+= parseInt(ctag['number-columns-repeated'], 10);
|
||||
@ -66,7 +69,7 @@ var parse_content_xml = (function() {
|
||||
if(C < range.s.c) range.s.c = C;
|
||||
if(R < range.s.r) range.s.r = R;
|
||||
ctag = parsexmltag(Rn[0], false);
|
||||
q = ({t:ctag['value-type'], v:null/*:: , z:null, w:""*/}/*:any*/);
|
||||
q = ({t:ctag['数据类型'] || ctag['value-type'], v:null/*:: , z:null, w:""*/}/*:any*/);
|
||||
if(opts.cellFormula) {
|
||||
if(ctag['number-matrix-columns-spanned'] && ctag['number-matrix-rows-spanned']) {
|
||||
mR = parseInt(ctag['number-matrix-rows-spanned'],10) || 0;
|
||||
@ -99,8 +102,9 @@ var parse_content_xml = (function() {
|
||||
case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
|
||||
case 'date': q.t = 'n'; q.v = datenum(ctag['date-value']); q.z = 'm/d/yy'; break;
|
||||
case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400; break;
|
||||
case 'number': q.t = 'n'; q.v = parseFloat(ctag['数据数值']); break;
|
||||
default:
|
||||
if(q.t === 'string' || !q.t) {
|
||||
if(q.t === 'string' || q.t === 'text' || !q.t) {
|
||||
q.t = 's';
|
||||
if(ctag['string-value'] != null) textp = ctag['string-value'];
|
||||
} else throw new Error('Unsupported value type ' + q.t);
|
||||
@ -125,15 +129,23 @@ var parse_content_xml = (function() {
|
||||
break; // 9.1.4 <table:table-cell>
|
||||
|
||||
/* pure state */
|
||||
case 'document-content': // 3.1.3.2 <office:document-content>
|
||||
case 'spreadsheet': // 3.7 <office:spreadsheet>
|
||||
case 'document': // TODO: <office:document> is the root for FODS
|
||||
case 'document-content': case '电子表格文档': // 3.1.3.2 <office:document-content>
|
||||
case 'spreadsheet': case '主体': // 3.7 <office:spreadsheet>
|
||||
case 'scripts': // 3.12 <office:scripts>
|
||||
case 'styles': // TODO <office:styles>
|
||||
case 'font-face-decls': // 3.14 <office:font-face-decls>
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
|
||||
break;
|
||||
|
||||
/* ignore state */
|
||||
case 'meta': case '元数据': // TODO: <office:meta> <uof:元数据> FODS/UOF
|
||||
case 'settings': // TODO: <office:settings>
|
||||
case 'config-item-set': // TODO: <office:config-item-set>
|
||||
case 'config-item-map-indexed': // TODO: <office:config-item-map-indexed>
|
||||
case 'config-item-map-entry': // TODO: <office:config-item-map-entry>
|
||||
case 'config-item-map-named': // TODO: <office:config-item-map-entry>
|
||||
case 'shapes': // 9.2.8 <table:shapes>
|
||||
case 'frame': // 10.4.2 <draw:frame>
|
||||
case 'text-box': // 10.4.3 <draw:text-box>
|
||||
@ -143,11 +155,18 @@ var parse_content_xml = (function() {
|
||||
case 'form': // 13.13 <form:form>
|
||||
case 'dde-links': // 9.8 <table:dde-links>
|
||||
case 'annotation': // 14.1 <office:annotation>
|
||||
case 'event-listeners': // TODO
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], false]);
|
||||
textp = ""; textpidx = 0;
|
||||
break;
|
||||
|
||||
case 'scientific-number': // TODO: <number:scientific-number>
|
||||
break;
|
||||
case 'currency-symbol': // TODO: <number:currency-symbol>
|
||||
break;
|
||||
case 'currency-style': // TODO: <number:currency-style>
|
||||
break;
|
||||
case 'number-style': // 16.27.2 <number:number-style>
|
||||
case 'percentage-style': // 16.27.9 <number:percentage-style>
|
||||
case 'date-style': // 16.27.10 <number:date-style>
|
||||
@ -162,8 +181,12 @@ var parse_content_xml = (function() {
|
||||
} break;
|
||||
|
||||
case 'script': break; // 3.13 <office:script>
|
||||
case 'libraries': break; // TODO: <ooo:libraries>
|
||||
case 'automatic-styles': break; // 3.15.3 <office:automatic-styles>
|
||||
case 'master-styles': break; // TODO: <office:automatic-styles>
|
||||
|
||||
case 'default-style': // TODO: <style:default-style>
|
||||
case 'page-layout': break; // TODO: <style:page-layout>
|
||||
case 'style': break; // 16.2 <style:style>
|
||||
case 'map': break; // 16.3 <style:map>
|
||||
case 'font-face': break; // 16.21 <style:font-face>
|
||||
@ -206,7 +229,7 @@ var parse_content_xml = (function() {
|
||||
case 'boolean': break; // 16.27.24 <number:boolean>
|
||||
case 'text-style': break; // 16.27.25 <number:text-style>
|
||||
case 'text': // 16.27.26 <number:text>
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") switch(state[state.length-1][0]) {
|
||||
case 'number-style':
|
||||
case 'date-style':
|
||||
@ -219,7 +242,7 @@ var parse_content_xml = (function() {
|
||||
case 'text-content': break; // 16.27.27 <number:text-content>
|
||||
case 'text-properties': break; // 16.27.27 <style:text-properties>
|
||||
|
||||
case 'body': break; // 3.3 16.9.6 19.726.3
|
||||
case 'body': case '电子表格': break; // 3.3 16.9.6 19.726.3
|
||||
|
||||
case 'forms': break; // 12.25.2 13.2
|
||||
case 'table-column': break; // 9.1.6 <table:table-column>
|
||||
@ -237,7 +260,7 @@ var parse_content_xml = (function() {
|
||||
|
||||
case 'span': break; // <text:span>
|
||||
case 'line-break': break; // 6.1.5 <text:line-break>
|
||||
case 'p':
|
||||
case 'p': case '文本串':
|
||||
if(Rn[1]==='/') textp = parse_text_p(str.slice(textpidx,Rn.index), textptag);
|
||||
else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
|
||||
break; // <text:p>
|
||||
@ -245,7 +268,7 @@ var parse_content_xml = (function() {
|
||||
case 'date': break; // <*:date>
|
||||
|
||||
case 'object': break; // 10.4.6.2 <draw:object>
|
||||
case 'title': break; // <*:title>
|
||||
case 'title': case '标题': break; // <*:title> OR <uof:标题>
|
||||
case 'desc': break; // <*:desc>
|
||||
|
||||
case 'table-source': break; // 9.2.6
|
||||
@ -289,6 +312,25 @@ var parse_content_xml = (function() {
|
||||
case 'sheet-name': // 7.3.9
|
||||
break;
|
||||
|
||||
case 'event-listener': // TODO
|
||||
/* TODO: FODS Properties */
|
||||
case 'initial-creator':
|
||||
case 'creator':
|
||||
case 'creation-date':
|
||||
case 'generator':
|
||||
case 'document-statistic':
|
||||
case 'user-defined':
|
||||
break;
|
||||
|
||||
/* TODO: FODS Config */
|
||||
case 'config-item':
|
||||
break;
|
||||
|
||||
/* TODO: style tokens */
|
||||
case 'page-number': break; // TODO <text:page-number>
|
||||
case 'page-count': break; // TODO <text:page-count>
|
||||
case 'time': break; // TODO <text:time>
|
||||
|
||||
/* 9.6 Data Pilot Tables <table: */
|
||||
case 'data-pilot-table': // 9.6.3
|
||||
case 'source-cell-range': // 9.6.5
|
||||
@ -330,7 +372,12 @@ var parse_content_xml = (function() {
|
||||
default:
|
||||
if(Rn[2] === 'dc:') break; // TODO: properties
|
||||
if(Rn[2] === 'draw:') break; // TODO: drawing
|
||||
if(Rn[2] === 'style:') break; // TODO: styles
|
||||
if(Rn[2] === 'calcext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'loext:') break; // ignore undocumented extensions
|
||||
if(Rn[2] === 'uof:') break; // TODO: uof
|
||||
if(Rn[2] === '表:') break; // TODO: uof
|
||||
if(Rn[2] === '字:') break; // TODO: uof
|
||||
if(opts.WTF) throw Rn;
|
||||
}
|
||||
var out = {
|
||||
|
@ -29,13 +29,15 @@ var write_content_xml/*:{(wb:any, opts:any):string}*/ = (function() {
|
||||
return function wcx(wb, opts) {
|
||||
var o = [XML_HEADER];
|
||||
/* 3.1.3.2 */
|
||||
o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
if(opts.bookType == "fods") o.push('<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.spreadsheet">');
|
||||
else o.push('<office:document-content office:version="1.2" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">\n'); // TODO
|
||||
o.push(' <office:body>\n');
|
||||
o.push(' <office:spreadsheet>\n');
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts));
|
||||
o.push(' </office:spreadsheet>\n');
|
||||
o.push(' </office:body>\n');
|
||||
o.push('</office:document-content>');
|
||||
if(opts.bookType == "fods") o.push('</office:document>');
|
||||
else o.push('</office:document-content>');
|
||||
return o.join("");
|
||||
};
|
||||
})();
|
||||
|
@ -1,6 +1,12 @@
|
||||
/* Part 3: Packages */
|
||||
function parse_ods(zip/*:ZIPFile*/, opts/*:?ParseOpts*/) {
|
||||
opts = opts || ({}/*:any*/);
|
||||
var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
return parse_content_xml(getzipdata(zip, 'content.xml'), opts);
|
||||
var ods = !!safegetzipfile(zip, 'objectdata');
|
||||
if(ods) var manifest = parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
|
||||
var content = getzipdata(zip, 'content.xml');
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
}
|
||||
|
||||
function parse_fods(data/*:string*/, opts/*:?ParseOpts*/) {
|
||||
return parse_content_xml(data, opts);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
function write_ods(wb/*:any*/, opts/*:any*/) {
|
||||
if(opts.bookType == "fods") return write_content_xml(wb, opts);
|
||||
|
||||
/*:: if(!jszip) throw new Error("JSZip is not available"); */
|
||||
var zip = new jszip();
|
||||
var f = "";
|
||||
|
@ -1,2 +1,3 @@
|
||||
ODS.parse_ods = parse_ods;
|
||||
ODS.write_ods = write_ods;
|
||||
ODS.parse_fods = parse_fods;
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.8.4",
|
||||
"version": "0.8.5",
|
||||
"author": "sheetjs",
|
||||
"description": "Excel (XLSB/XLSX/XLSM/XLS/XML) and ODS spreadsheet parser and writer",
|
||||
"description": "Excel (XLSB/XLSX/XLSM/XLS/XML) and ODS (ODS/FODS/UOS) spreadsheet parser and writer",
|
||||
"keywords": [ "excel", "xls", "xlsx", "xlsb", "xlsm", "ods", "office", "spreadsheet" ],
|
||||
"bin": {
|
||||
"xlsx": "./bin/xlsx.njs"
|
||||
|
@ -89,3 +89,5 @@ XLSX.writeFile(wb, 'sheetjs.xlsm');
|
||||
XLSX.writeFile(wb, 'sheetjs.xlsb');
|
||||
XLSX.writeFile(wb, 'sheetjs.xls', {bookType:'biff2'});
|
||||
XLSX.writeFile(wb, 'sheetjs.ods');
|
||||
XLSX.writeFile(wb, 'sheetjs.fods');
|
||||
XLSX.writeFile(wb, 'sheetjs.csv');
|
||||
|
137
xlsx.flow.js
137
xlsx.flow.js
@ -4,7 +4,7 @@
|
||||
/*jshint funcscope:true, eqnull:true */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.8.4';
|
||||
XLSX.version = '0.8.5';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
|
||||
@ -668,7 +668,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
case '[':
|
||||
o = c;
|
||||
while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i];
|
||||
if(o.substr(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.slice(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.match(abstime)) {
|
||||
if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
|
||||
out[out.length] = {t:'Z', v:o.toLowerCase()};
|
||||
@ -1314,6 +1314,12 @@ function cc2str(arr/*:Array<number>*/)/*:string*/ {
|
||||
return o;
|
||||
}
|
||||
|
||||
function str2cc(str) {
|
||||
var o = [];
|
||||
for(var i = 0; i != str.length; ++i) o.push(str.charCodeAt(i));
|
||||
return o;
|
||||
}
|
||||
|
||||
function dup(o/*:any*/)/*:any*/ {
|
||||
if(typeof JSON != 'undefined') return JSON.parse(JSON.stringify(o));
|
||||
if(typeof o != 'object' || !o) return o;
|
||||
@ -1336,11 +1342,15 @@ function getdatabin(data) {
|
||||
if(!data) return null;
|
||||
if(data.data) return char_codes(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
|
||||
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
|
||||
if(data._data && data._data.getContent) {
|
||||
var o = data._data.getContent();
|
||||
if(typeof o == "string") return str2cc(o);
|
||||
return Array.prototype.slice.call(o);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getdata(data) { return (data && data.name.substr(data.name.length-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
|
||||
function safegetzipfile(zip, file/*:string*/) {
|
||||
var f = file; if(zip.files[f]) return zip.files[f];
|
||||
@ -1420,7 +1430,7 @@ var unescapexml/*:StringConv*/ = (function() {
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
|
||||
function escapexml(text/*:string*/)/*:string*/{
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";});
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
|
||||
}
|
||||
|
||||
/* TODO: handle codepages */
|
||||
@ -1631,7 +1641,10 @@ function ReadShift(size, t) {
|
||||
case 'utf8': o = __utf8(this, this.l, this.l + size); break;
|
||||
case 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break;
|
||||
|
||||
case 'wstr': o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size)); size = 2 * size; break;
|
||||
case 'wstr':
|
||||
if(typeof cptable !== 'undefined') o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size));
|
||||
else return ReadShift.call(this, size, 'dbcs');
|
||||
o = size = 2 * size; break;
|
||||
|
||||
/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
|
||||
case 'lpstr': o = __lpstr(this, this.l); size = 5 + o.length; break;
|
||||
@ -8068,7 +8081,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
|
||||
/* 18.3.1.4 c CT_Cell */
|
||||
cells = x.substr(ri).split(cellregex);
|
||||
for(ri = typeof tag.r === 'undefined' ? 0 : 1; ri != cells.length; ++ri) {
|
||||
for(ri = 0; ri != cells.length; ++ri) {
|
||||
x = cells[ri].trim();
|
||||
if(x.length === 0) continue;
|
||||
cref = x.match(rregex); idx = ri; i=0; cc=0;
|
||||
@ -8709,7 +8722,7 @@ function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:num
|
||||
}
|
||||
var o/*:CellAddress*/ = ({r:R, c:C}/*:any*/);
|
||||
/* TODO: cell style */
|
||||
o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
//o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
switch(cell.t) {
|
||||
case 's': case 'str':
|
||||
if(opts.bookSST) {
|
||||
@ -9254,17 +9267,17 @@ function write_wb_bin(wb, opts) {
|
||||
return ba.end();
|
||||
}
|
||||
function parse_wb(data, name/*:string*/, opts)/*:Workbook*/ {
|
||||
if(name.substr(name.length-4)===".bin") return parse_wb_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_wb_bin((data/*:any*/), opts);
|
||||
return parse_wb_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function parse_ws(data, name/*:string*/, opts, rels, wb)/*:Worksheet*/ {
|
||||
if(name.substr(name.length-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels, wb);
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data/*:any*/), opts, rels, wb);
|
||||
return parse_ws_xml((data/*:any*/), opts, rels, wb);
|
||||
}
|
||||
|
||||
function parse_sty(data, name/*:string*/, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_sty_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_sty_bin((data/*:any*/), opts);
|
||||
return parse_sty_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
@ -9273,42 +9286,42 @@ function parse_theme(data, name/*:string*/, opts) {
|
||||
}
|
||||
|
||||
function parse_sst(data, name/*:string*/, opts)/*:SST*/ {
|
||||
if(name.substr(name.length-4)===".bin") return parse_sst_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_sst_bin((data/*:any*/), opts);
|
||||
return parse_sst_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function parse_cmnt(data, name/*:string*/, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_comments_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_comments_bin((data/*:any*/), opts);
|
||||
return parse_comments_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function parse_cc(data, name/*:string*/, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_cc_bin((data/*:any*/), opts);
|
||||
if(name.slice(-4)===".bin") return parse_cc_bin((data/*:any*/), opts);
|
||||
return parse_cc_xml((data/*:any*/), opts);
|
||||
}
|
||||
|
||||
function write_wb(wb, name/*:string*/, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||
}
|
||||
|
||||
function write_ws(data/*:Worksheet*/, name/*:string*/, opts, wb/*:Workbook*/) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
|
||||
return (name.slice(-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
|
||||
}
|
||||
|
||||
function write_sty(data, name/*:string*/, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
|
||||
}
|
||||
|
||||
function write_sst(data/*:SST*/, name/*:string*/, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
|
||||
}
|
||||
/*
|
||||
function write_cmnt(data, name:string, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
|
||||
}
|
||||
|
||||
function write_cc(data, name:string, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||
}
|
||||
*/
|
||||
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||
@ -9513,15 +9526,15 @@ function parse_xlml_xml(d, opts) {
|
||||
if(cell.Index) c = +cell.Index - 1;
|
||||
if(c < refguess.s.c) refguess.s.c = c;
|
||||
if(c > refguess.e.c) refguess.e.c = c;
|
||||
if(Rn[0].substr(-2) === "/>") ++c;
|
||||
if(Rn[0].slice(-2) === "/>") ++c;
|
||||
comments = [];
|
||||
}
|
||||
break;
|
||||
case 'Row':
|
||||
if(Rn[1]==='/' || Rn[0].substr(-2) === "/>") {
|
||||
if(Rn[1]==='/' || Rn[0].slice(-2) === "/>") {
|
||||
if(r < refguess.s.r) refguess.s.r = r;
|
||||
if(r > refguess.e.r) refguess.e.r = r;
|
||||
if(Rn[0].substr(-2) === "/>") {
|
||||
if(Rn[0].slice(-2) === "/>") {
|
||||
row = xlml_parsexmltag(Rn[0]);
|
||||
if(row.Index) r = +row.Index - 1;
|
||||
}
|
||||
@ -9587,7 +9600,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'Alignment': break;
|
||||
case 'Borders': break;
|
||||
case 'Font':
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") ss += str.slice(fidx, Rn.index);
|
||||
else fidx = Rn.index + Rn[0].length;
|
||||
break;
|
||||
@ -9613,7 +9626,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'TotalTime':
|
||||
case 'HyperlinkBase':
|
||||
case 'Manager':
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") xlml_set_prop(Props, Rn[3], str.slice(pidx, Rn.index));
|
||||
else pidx = Rn.index + Rn[0].length;
|
||||
break;
|
||||
@ -9665,6 +9678,11 @@ function parse_xlml_xml(d, opts) {
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FODS file root is <office:document> */
|
||||
if(state.length == 0 && Rn[3] == "document") return parse_fods(str, opts);
|
||||
/* UOS file root is <uof:UOF> */
|
||||
if(state.length == 0 && Rn[3] == "UOF") return parse_fods(str, opts);
|
||||
|
||||
var seen = true;
|
||||
switch(state[state.length-1][0]) {
|
||||
/* OfficeDocumentSettings */
|
||||
@ -10002,7 +10020,7 @@ function parse_xlml_xml(d, opts) {
|
||||
/* CustomDocumentProperties */
|
||||
if(!state[state.length-1][1]) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
|
||||
if(state[state.length-1][0]==='CustomDocumentProperties') {
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") xlml_set_custprop(Custprops, Rn, cp, str.slice(pidx, Rn.index));
|
||||
else { cp = Rn; pidx = Rn.index + Rn[0].length; }
|
||||
break;
|
||||
@ -10027,6 +10045,7 @@ function parse_xlml(data, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
function write_xlml(wb, opts)/*:string*/ {
|
||||
var o = [XML_HEADER];
|
||||
return o.join("");
|
||||
@ -12087,20 +12106,12 @@ function write_biff_buf(wb/*:Workbook*/, o/*:WriteOpts*/) {
|
||||
// TODO
|
||||
return ba.end();
|
||||
}
|
||||
|
||||
function write_biff(wb/*:Workbook*/, o/*:WriteOpts*/) {
|
||||
var out = write_biff_buf(wb, o);
|
||||
switch(o.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": {
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
}
|
||||
case "file": return _fs.writeFileSync(o.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
/* actual implementation in utils, wrappers are for read/write */
|
||||
function write_csv_str(wb/*:Workbook*/, o/*:WriteOpts*/) {
|
||||
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);
|
||||
return sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o);
|
||||
}
|
||||
/* Helper functions to call out to ODS */
|
||||
function parse_ods(zip, opts) {
|
||||
@ -12113,6 +12124,11 @@ function write_ods(wb, opts) {
|
||||
if(typeof ODS === 'undefined' || !ODS.write_ods) throw new Error("Unsupported ODS");
|
||||
return ODS.write_ods(wb, opts);
|
||||
}
|
||||
function parse_fods(data, opts) {
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined' && typeof ODS === 'undefined') ODS = require('./od' + 's');
|
||||
if(typeof ODS === 'undefined' || !ODS.parse_fods) throw new Error("Unsupported ODS");
|
||||
return ODS.parse_fods(data, opts);
|
||||
}
|
||||
function fix_opts_func(defaults/*:Array<Array<any> >*/)/*:{(o:any):void}*/ {
|
||||
return function fix_opts(opts) {
|
||||
for(var i = 0; i != defaults.length; ++i) {
|
||||
@ -12170,7 +12186,7 @@ function safe_parse_ws(zip, path/*:string*/, relsPath/*:string*/, sheet, sheetRe
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
|
||||
var nodirs = function nodirs(x/*:string*/)/*:boolean*/{return x.substr(-1) != '/';};
|
||||
var nodirs = function nodirs(x/*:string*/)/*:boolean*/{return x.slice(-1) != '/';};
|
||||
function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
make_ssf(SSF);
|
||||
opts = opts || {};
|
||||
@ -12179,6 +12195,8 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
|
||||
/* OpenDocument Part 3 Section 2.2.1 OpenDocument Package */
|
||||
if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
|
||||
/* UOC */
|
||||
if(safegetzipfile(zip, 'objectdata.xml')) return parse_ods(zip, opts);
|
||||
|
||||
var entries = keys(zip.files).filter(nodirs).sort();
|
||||
var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')/*:?any*/), opts);
|
||||
@ -12194,7 +12212,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
||||
dir.workbooks.push(binname);
|
||||
xlsb = true;
|
||||
}
|
||||
if(dir.workbooks[0].substr(-3) == "bin") xlsb = true;
|
||||
if(dir.workbooks[0].slice(-3) == "bin") xlsb = true;
|
||||
if(xlsb) set_cp(1200);
|
||||
|
||||
if(!opts.bookSheets && !opts.bookProps) {
|
||||
@ -12446,11 +12464,36 @@ function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
function write_string_type(out/*:string*/, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": break; // TODO
|
||||
case "file": return _fs.writeFileSync(opts.file, out, {encoding:'utf8'});
|
||||
case "buffer": break; // TODO
|
||||
default: return out;
|
||||
}
|
||||
}
|
||||
|
||||
function write_binary_type(out, opts/*:WriteOpts*/) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
}
|
||||
|
||||
function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
var o = opts||{};
|
||||
switch(o.bookType) {
|
||||
case 'xml': return write_xlml(wb, o);
|
||||
case 'biff2': return write_biff(wb, o);
|
||||
case 'xml': return write_string_type(write_xlml(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_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);
|
||||
default: return write_zip_type(wb, o);
|
||||
}
|
||||
}
|
||||
@ -12458,14 +12501,16 @@ function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
|
||||
function writeFileSync(wb/*:Workbook*/, filename/*:string*/, opts/*:?WriteFileOpts*/) {
|
||||
var o = opts||{}; o.type = 'file';
|
||||
o.file = filename;
|
||||
if(!o.bookType) switch(o.file.substr(-5).toLowerCase()) {
|
||||
if(!o.bookType) switch(o.file.slice(-5).toLowerCase()) {
|
||||
case '.xlsx': o.bookType = 'xlsx'; break;
|
||||
case '.xlsm': o.bookType = 'xlsm'; break;
|
||||
case '.xlsb': o.bookType = 'xlsb'; break;
|
||||
default: switch(o.file.substr(-4).toLowerCase()) {
|
||||
case '.fods': o.bookType = 'fods'; break;
|
||||
default: switch(o.file.slice(-4).toLowerCase()) {
|
||||
case '.xls': o.bookType = 'biff2'; break;
|
||||
case '.xml': o.bookType = 'xml'; break;
|
||||
case '.ods': o.bookType = 'ods'; break;
|
||||
case '.csv': o.bookType = 'csv'; break;
|
||||
}}
|
||||
return writeSync(wb, o);
|
||||
}
|
||||
|
137
xlsx.js
137
xlsx.js
@ -4,7 +4,7 @@
|
||||
/*jshint funcscope:true, eqnull:true */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.8.4';
|
||||
XLSX.version = '0.8.5';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel');
|
||||
@ -651,7 +651,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
case '[':
|
||||
o = c;
|
||||
while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i];
|
||||
if(o.substr(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.slice(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.match(abstime)) {
|
||||
if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; }
|
||||
out[out.length] = {t:'Z', v:o.toLowerCase()};
|
||||
@ -1297,6 +1297,12 @@ function cc2str(arr) {
|
||||
return o;
|
||||
}
|
||||
|
||||
function str2cc(str) {
|
||||
var o = [];
|
||||
for(var i = 0; i != str.length; ++i) o.push(str.charCodeAt(i));
|
||||
return o;
|
||||
}
|
||||
|
||||
function dup(o) {
|
||||
if(typeof JSON != 'undefined') return JSON.parse(JSON.stringify(o));
|
||||
if(typeof o != 'object' || !o) return o;
|
||||
@ -1319,11 +1325,15 @@ function getdatabin(data) {
|
||||
if(!data) return null;
|
||||
if(data.data) return char_codes(data.data);
|
||||
if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
|
||||
if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent());
|
||||
if(data._data && data._data.getContent) {
|
||||
var o = data._data.getContent();
|
||||
if(typeof o == "string") return str2cc(o);
|
||||
return Array.prototype.slice.call(o);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getdata(data) { return (data && data.name.substr(data.name.length-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
|
||||
|
||||
function safegetzipfile(zip, file) {
|
||||
var f = file; if(zip.files[f]) return zip.files[f];
|
||||
@ -1402,7 +1412,7 @@ var unescapexml = (function() {
|
||||
var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
|
||||
function escapexml(text){
|
||||
var s = text + '';
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";});
|
||||
return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
|
||||
}
|
||||
|
||||
/* TODO: handle codepages */
|
||||
@ -1613,7 +1623,10 @@ function ReadShift(size, t) {
|
||||
case 'utf8': o = __utf8(this, this.l, this.l + size); break;
|
||||
case 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break;
|
||||
|
||||
case 'wstr': o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size)); size = 2 * size; break;
|
||||
case 'wstr':
|
||||
if(typeof cptable !== 'undefined') o = cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size));
|
||||
else return ReadShift.call(this, size, 'dbcs');
|
||||
o = size = 2 * size; break;
|
||||
|
||||
/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
|
||||
case 'lpstr': o = __lpstr(this, this.l); size = 5 + o.length; break;
|
||||
@ -8050,7 +8063,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
|
||||
/* 18.3.1.4 c CT_Cell */
|
||||
cells = x.substr(ri).split(cellregex);
|
||||
for(ri = typeof tag.r === 'undefined' ? 0 : 1; ri != cells.length; ++ri) {
|
||||
for(ri = 0; ri != cells.length; ++ri) {
|
||||
x = cells[ri].trim();
|
||||
if(x.length === 0) continue;
|
||||
cref = x.match(rregex); idx = ri; i=0; cc=0;
|
||||
@ -8691,7 +8704,7 @@ function write_ws_bin_cell(ba, cell, R, C, opts) {
|
||||
}
|
||||
var o = ({r:R, c:C});
|
||||
/* TODO: cell style */
|
||||
o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
//o.s = get_cell_style(opts.cellXfs, cell, opts);
|
||||
switch(cell.t) {
|
||||
case 's': case 'str':
|
||||
if(opts.bookSST) {
|
||||
@ -9236,17 +9249,17 @@ function write_wb_bin(wb, opts) {
|
||||
return ba.end();
|
||||
}
|
||||
function parse_wb(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_wb_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_wb_bin((data), opts);
|
||||
return parse_wb_xml((data), opts);
|
||||
}
|
||||
|
||||
function parse_ws(data, name, opts, rels, wb) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_ws_bin((data), opts, rels, wb);
|
||||
if(name.slice(-4)===".bin") return parse_ws_bin((data), opts, rels, wb);
|
||||
return parse_ws_xml((data), opts, rels, wb);
|
||||
}
|
||||
|
||||
function parse_sty(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_sty_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_sty_bin((data), opts);
|
||||
return parse_sty_xml((data), opts);
|
||||
}
|
||||
|
||||
@ -9255,42 +9268,42 @@ function parse_theme(data, name, opts) {
|
||||
}
|
||||
|
||||
function parse_sst(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_sst_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_sst_bin((data), opts);
|
||||
return parse_sst_xml((data), opts);
|
||||
}
|
||||
|
||||
function parse_cmnt(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_comments_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_comments_bin((data), opts);
|
||||
return parse_comments_xml((data), opts);
|
||||
}
|
||||
|
||||
function parse_cc(data, name, opts) {
|
||||
if(name.substr(name.length-4)===".bin") return parse_cc_bin((data), opts);
|
||||
if(name.slice(-4)===".bin") return parse_cc_bin((data), opts);
|
||||
return parse_cc_xml((data), opts);
|
||||
}
|
||||
|
||||
function write_wb(wb, name, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||
}
|
||||
|
||||
function write_ws(data, name, opts, wb) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
|
||||
return (name.slice(-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb);
|
||||
}
|
||||
|
||||
function write_sty(data, name, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
|
||||
}
|
||||
|
||||
function write_sst(data, name, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
|
||||
}
|
||||
/*
|
||||
function write_cmnt(data, name:string, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
|
||||
}
|
||||
|
||||
function write_cc(data, name:string, opts) {
|
||||
return (name.substr(name.length-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||
}
|
||||
*/
|
||||
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||
@ -9493,15 +9506,15 @@ function parse_xlml_xml(d, opts) {
|
||||
if(cell.Index) c = +cell.Index - 1;
|
||||
if(c < refguess.s.c) refguess.s.c = c;
|
||||
if(c > refguess.e.c) refguess.e.c = c;
|
||||
if(Rn[0].substr(-2) === "/>") ++c;
|
||||
if(Rn[0].slice(-2) === "/>") ++c;
|
||||
comments = [];
|
||||
}
|
||||
break;
|
||||
case 'Row':
|
||||
if(Rn[1]==='/' || Rn[0].substr(-2) === "/>") {
|
||||
if(Rn[1]==='/' || Rn[0].slice(-2) === "/>") {
|
||||
if(r < refguess.s.r) refguess.s.r = r;
|
||||
if(r > refguess.e.r) refguess.e.r = r;
|
||||
if(Rn[0].substr(-2) === "/>") {
|
||||
if(Rn[0].slice(-2) === "/>") {
|
||||
row = xlml_parsexmltag(Rn[0]);
|
||||
if(row.Index) r = +row.Index - 1;
|
||||
}
|
||||
@ -9567,7 +9580,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'Alignment': break;
|
||||
case 'Borders': break;
|
||||
case 'Font':
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") ss += str.slice(fidx, Rn.index);
|
||||
else fidx = Rn.index + Rn[0].length;
|
||||
break;
|
||||
@ -9593,7 +9606,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'TotalTime':
|
||||
case 'HyperlinkBase':
|
||||
case 'Manager':
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") xlml_set_prop(Props, Rn[3], str.slice(pidx, Rn.index));
|
||||
else pidx = Rn.index + Rn[0].length;
|
||||
break;
|
||||
@ -9645,6 +9658,11 @@ function parse_xlml_xml(d, opts) {
|
||||
break;
|
||||
|
||||
default:
|
||||
/* FODS file root is <office:document> */
|
||||
if(state.length == 0 && Rn[3] == "document") return parse_fods(str, opts);
|
||||
/* UOS file root is <uof:UOF> */
|
||||
if(state.length == 0 && Rn[3] == "UOF") return parse_fods(str, opts);
|
||||
|
||||
var seen = true;
|
||||
switch(state[state.length-1][0]) {
|
||||
/* OfficeDocumentSettings */
|
||||
@ -9982,7 +10000,7 @@ function parse_xlml_xml(d, opts) {
|
||||
/* CustomDocumentProperties */
|
||||
if(!state[state.length-1][1]) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
|
||||
if(state[state.length-1][0]==='CustomDocumentProperties') {
|
||||
if(Rn[0].substr(-2) === "/>") break;
|
||||
if(Rn[0].slice(-2) === "/>") break;
|
||||
else if(Rn[1]==="/") xlml_set_custprop(Custprops, Rn, cp, str.slice(pidx, Rn.index));
|
||||
else { cp = Rn; pidx = Rn.index + Rn[0].length; }
|
||||
break;
|
||||
@ -10007,6 +10025,7 @@ function parse_xlml(data, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
function write_xlml(wb, opts) {
|
||||
var o = [XML_HEADER];
|
||||
return o.join("");
|
||||
@ -12067,20 +12086,12 @@ function write_biff_buf(wb, o) {
|
||||
// TODO
|
||||
return ba.end();
|
||||
}
|
||||
|
||||
function write_biff(wb, o) {
|
||||
var out = write_biff_buf(wb, o);
|
||||
switch(o.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": {
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
}
|
||||
case "file": return _fs.writeFileSync(o.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + o.type);
|
||||
}
|
||||
/* actual implementation in utils, wrappers are for read/write */
|
||||
function write_csv_str(wb, o) {
|
||||
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);
|
||||
return sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o);
|
||||
}
|
||||
/* Helper functions to call out to ODS */
|
||||
function parse_ods(zip, opts) {
|
||||
@ -12093,6 +12104,11 @@ function write_ods(wb, opts) {
|
||||
if(typeof ODS === 'undefined' || !ODS.write_ods) throw new Error("Unsupported ODS");
|
||||
return ODS.write_ods(wb, opts);
|
||||
}
|
||||
function parse_fods(data, opts) {
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined' && typeof ODS === 'undefined') ODS = require('./od' + 's');
|
||||
if(typeof ODS === 'undefined' || !ODS.parse_fods) throw new Error("Unsupported ODS");
|
||||
return ODS.parse_fods(data, opts);
|
||||
}
|
||||
function fix_opts_func(defaults) {
|
||||
return function fix_opts(opts) {
|
||||
for(var i = 0; i != defaults.length; ++i) {
|
||||
@ -12150,7 +12166,7 @@ function safe_parse_ws(zip, path, relsPath, sheet, sheetRels, sheets, opts, wb)
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
|
||||
var nodirs = function nodirs(x){return x.substr(-1) != '/';};
|
||||
var nodirs = function nodirs(x){return x.slice(-1) != '/';};
|
||||
function parse_zip(zip, opts) {
|
||||
make_ssf(SSF);
|
||||
opts = opts || {};
|
||||
@ -12159,6 +12175,8 @@ function parse_zip(zip, opts) {
|
||||
|
||||
/* OpenDocument Part 3 Section 2.2.1 OpenDocument Package */
|
||||
if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
|
||||
/* UOC */
|
||||
if(safegetzipfile(zip, 'objectdata.xml')) return parse_ods(zip, opts);
|
||||
|
||||
var entries = keys(zip.files).filter(nodirs).sort();
|
||||
var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')), opts);
|
||||
@ -12174,7 +12192,7 @@ function parse_zip(zip, opts) {
|
||||
dir.workbooks.push(binname);
|
||||
xlsb = true;
|
||||
}
|
||||
if(dir.workbooks[0].substr(-3) == "bin") xlsb = true;
|
||||
if(dir.workbooks[0].slice(-3) == "bin") xlsb = true;
|
||||
if(xlsb) set_cp(1200);
|
||||
|
||||
if(!opts.bookSheets && !opts.bookProps) {
|
||||
@ -12424,11 +12442,36 @@ function write_zip_type(wb, opts) {
|
||||
return z.generate(oopts);
|
||||
}
|
||||
|
||||
function write_string_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary": break; // TODO
|
||||
case "file": return _fs.writeFileSync(opts.file, out, {encoding:'utf8'});
|
||||
case "buffer": break; // TODO
|
||||
default: return out;
|
||||
}
|
||||
}
|
||||
|
||||
function write_binary_type(out, opts) {
|
||||
switch(opts.type) {
|
||||
case "base64": break; // TODO
|
||||
case "binary":
|
||||
var bstr = "";
|
||||
for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
|
||||
return bstr;
|
||||
case "file": return _fs.writeFileSync(opts.file, out);
|
||||
case "buffer": return out;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
}
|
||||
|
||||
function writeSync(wb, opts) {
|
||||
var o = opts||{};
|
||||
switch(o.bookType) {
|
||||
case 'xml': return write_xlml(wb, o);
|
||||
case 'biff2': return write_biff(wb, o);
|
||||
case 'xml': return write_string_type(write_xlml(wb, o), o);
|
||||
case 'csv': return write_string_type(write_csv_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);
|
||||
default: return write_zip_type(wb, o);
|
||||
}
|
||||
}
|
||||
@ -12436,14 +12479,16 @@ function writeSync(wb, opts) {
|
||||
function writeFileSync(wb, filename, opts) {
|
||||
var o = opts||{}; o.type = 'file';
|
||||
o.file = filename;
|
||||
if(!o.bookType) switch(o.file.substr(-5).toLowerCase()) {
|
||||
if(!o.bookType) switch(o.file.slice(-5).toLowerCase()) {
|
||||
case '.xlsx': o.bookType = 'xlsx'; break;
|
||||
case '.xlsm': o.bookType = 'xlsm'; break;
|
||||
case '.xlsb': o.bookType = 'xlsb'; break;
|
||||
default: switch(o.file.substr(-4).toLowerCase()) {
|
||||
case '.fods': o.bookType = 'fods'; break;
|
||||
default: switch(o.file.slice(-4).toLowerCase()) {
|
||||
case '.xls': o.bookType = 'biff2'; break;
|
||||
case '.xml': o.bookType = 'xml'; break;
|
||||
case '.ods': o.bookType = 'ods'; break;
|
||||
case '.csv': o.bookType = 'csv'; break;
|
||||
}}
|
||||
return writeSync(wb, o);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user