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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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);
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
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