forked from sheetjs/sheetjs
version bump 0.9.2: more bugfixes
- decode sheet name for XLSX and XLML (fixes #203 h/t @rocketmonkeys) - XFExt (fixes #298 h/t @aetna-softwares @aimcom @baharudinafif) - handle truly empty `<is>` elements (fixes #506 h/t @asksahil) - pin version numbers for dependencies (fixes #469 h/t @nhtera) - sed usage fix (see #572 h/t @liryna) - fix hex2RGB substr indices (fixes #294 h/t @kamorahul) - removed stale typescript files (see #442) - reworked shift formula regex (fixed #551 h/t @SheetJSDev) - README note on webpack codepage suppression (fixes #438 h/t @rusty1s) - README note on WTF (fixes #487 h/t @livesoftware)
This commit is contained in:
parent
8cd9e81569
commit
456ab63dc4
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
node_modules
|
||||
*.tgz
|
||||
misc/coverage.html
|
||||
misc/prof.js
|
||||
v8.log
|
||||
|
@ -4,6 +4,7 @@ demos/
|
||||
index.html
|
||||
misc/
|
||||
node_modules
|
||||
*.tgz
|
||||
tmp
|
||||
*.txt
|
||||
*.[cC][sS][vV]
|
||||
@ -20,6 +21,7 @@ tmp
|
||||
*.htm
|
||||
*.html
|
||||
*.sheetjs
|
||||
*.exe
|
||||
.gitignore
|
||||
.jshintrc
|
||||
CONTRIBUTING.md
|
||||
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -5,6 +5,18 @@ but not limited to API changes and file location changes. Minor behavioral
|
||||
changes may not be included if they are not expected to break existing code.
|
||||
|
||||
|
||||
## 0.9.2 (2017-03-13)
|
||||
|
||||
* Removed stale TypeScript definition files. Flowtype comments are used in the
|
||||
`xlsx.flow.js` source and stripped to produce `xlsx.js`.
|
||||
* sed usage reworked to support GNU sed in-place form. BSD sed seems to work,
|
||||
but the build script has not been tested on other sed variants:
|
||||
|
||||
```bash
|
||||
$ sed -i.ext [...] # GNU
|
||||
$ sed -i .ext [...] # bsd
|
||||
```
|
||||
|
||||
## 0.9.0 (2017-03-09)
|
||||
|
||||
* Removed ods.js source. The xlsx.js source absorbed the ODS logic and exposes
|
||||
|
180
README.md
180
README.md
@ -5,36 +5,68 @@ 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.
|
||||
|
||||
File format support for known spreadsheet data formats:
|
||||
[**In-Browser Demo**](http://oss.sheetjs.com/js-xlsx)
|
||||
|
||||
| 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: | |
|
||||
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
|
||||
| HTML Tables | :o: | |
|
||||
[**Source Code**](http://git.io/xlsx)
|
||||
|
||||
[**Commercial Support**](http://sheetjs.com/reinforcements)
|
||||
|
||||
[**File format support for known spreadsheet data formats:**](#file-formats)
|
||||
|
||||
![circo graph of format support](formats.png)
|
||||
|
||||
Demo: <http://oss.sheetjs.com/js-xlsx>
|
||||
|
||||
Source: <http://git.io/xlsx>
|
||||
|
||||
Paid support available through the [reinforcements program](http://sheetjs.com/reinforcements)
|
||||
## Table of Contents
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Installation](#installation)
|
||||
* [JS Ecosystem Demos](#js-ecosystem-demos)
|
||||
* [Optional Modules](#optional-modules)
|
||||
* [ECMAScript 5 Compatibility](#ecmascript-5-compatibility)
|
||||
- [Parsing Workbooks](#parsing-workbooks)
|
||||
- [Working with the Workbook](#working-with-the-workbook)
|
||||
- [Writing Workbooks](#writing-workbooks)
|
||||
- [Interface](#interface)
|
||||
* [Parsing functions](#parsing-functions)
|
||||
* [Writing functions](#writing-functions)
|
||||
* [Utilities](#utilities)
|
||||
- [Workbook / Worksheet / Cell Object Description](#workbook--worksheet--cell-object-description)
|
||||
* [General Structures](#general-structures)
|
||||
* [Cell Object](#cell-object)
|
||||
* [Data Types](#data-types)
|
||||
* [Formulae](#formulae)
|
||||
* [Worksheet Object](#worksheet-object)
|
||||
* [Workbook Object](#workbook-object)
|
||||
- [Parsing Options](#parsing-options)
|
||||
* [Input Type](#input-type)
|
||||
* [Guessing File Type](#guessing-file-type)
|
||||
- [Writing Options](#writing-options)
|
||||
* [Supported Output Formats](#supported-output-formats)
|
||||
* [Output Type](#output-type)
|
||||
- [Utility Functions](#utility-functions)
|
||||
* [Formulae Output](#formulae-output)
|
||||
* [CSV and general DSV Output](#csv-and-general-dsv-output)
|
||||
* [JSON](#json)
|
||||
- [File Formats](#file-formats)
|
||||
* [Excel 2007+ XML (XLSX/XLSM)](#excel-2007-xml-xlsxxlsm)
|
||||
* [Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)](#excel-20-95-biff2biff3biff4biff5)
|
||||
* [Excel 97-2004 Binary (BIFF8)](#excel-97-2004-binary-biff8)
|
||||
* [Excel 2003-2004 (SpreadsheetML)](#excel-2003-2004-spreadsheetml)
|
||||
* [Excel 2007+ Binary (XLSB, BIFF12)](#excel-2007-binary-xlsb-biff12)
|
||||
* [OpenDocument Spreadsheet (ODS/FODS) and Uniform Office Spreadsheet (UOS1/2)](#opendocument-spreadsheet-odsfods-and-uniform-office-spreadsheet-uos12)
|
||||
* [Comma-Separated Values](#comma-separated-values)
|
||||
* [HTML](#html)
|
||||
- [Testing](#testing)
|
||||
* [Tested Environments](#tested-environments)
|
||||
* [Test Files](#test-files)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
- [References](#references)
|
||||
- [Badges](#badges)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Installation
|
||||
|
||||
@ -83,6 +115,17 @@ 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`
|
||||
|
||||
Webpack and browserify builds include optional modules by default. Webpack can
|
||||
be configured to remove support with `resolve.alias`:
|
||||
|
||||
```js
|
||||
/* uncomment the lines below to remove support */
|
||||
resolve: {
|
||||
alias: { "./dist/cpexcel.js": "" } // <-- omit international support
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### ECMAScript 5 Compatibility
|
||||
|
||||
Since xlsx.js uses ES5 functions like `Array#forEach`, older browsers require
|
||||
@ -143,10 +186,10 @@ oReq.send();
|
||||
```js
|
||||
/* processing array buffers, only required for readAsArrayBuffer */
|
||||
function fixdata(data) {
|
||||
var o = "", l = 0, w = 10240;
|
||||
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
|
||||
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
|
||||
return o;
|
||||
var o = "", l = 0, w = 10240;
|
||||
for(; l<data.byteLength/w; ++l) o+=String.fromCharCode.apply(null,new Uint8Array(data.slice(l*w,l*w+w)));
|
||||
o+=String.fromCharCode.apply(null, new Uint8Array(data.slice(l*w)));
|
||||
return o;
|
||||
}
|
||||
|
||||
var rABS = true; // true: readAsBinaryString ; false: readAsArrayBuffer
|
||||
@ -528,6 +571,7 @@ The exported `read` and `readFile` functions accept an options argument:
|
||||
| bookSheets | false | If true, only parse enough to get the sheet names |
|
||||
| bookVBA | false | If true, expose vbaProject.bin to `vbaraw` field ** |
|
||||
| password | "" | If defined and file is encrypted, use password ** |
|
||||
| WTF | false | If true, throw errors on unexpected file features ** |
|
||||
|
||||
- `cellFormula` option only applies to formats that require extra processing to
|
||||
parse formulae (XLS/XLSB).
|
||||
@ -545,6 +589,9 @@ The exported `read` and `readFile` functions accept an options argument:
|
||||
- `cellDates` currently does not convert numerical dates to JS dates.
|
||||
- Currently only XOR encryption is supported. Unsupported error will be thrown
|
||||
for files employing other encryption methods.
|
||||
- WTF is mainly for development. By default, the parser will suppress read
|
||||
errors on single worksheets, allowing you to read from the worksheets that do
|
||||
parse properly. Setting `WTF:1` forces those errors to be thrown.
|
||||
|
||||
The defaults are enumerated in bits/84\_defaults.js
|
||||
|
||||
@ -754,8 +801,37 @@ Example showing the effect of `raw`:
|
||||
|
||||
## File Formats
|
||||
|
||||
Despite the fact that the name of the library is `xlsx`, it supports numerous
|
||||
non-XLSX file formats:
|
||||
Despite the library name `xlsx`, it supports numerous spreadsheet file formats:
|
||||
|
||||
| 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: | |
|
||||
| **Other Common Spreadsheet Output Formats** |:-----:|:-----:|
|
||||
| HTML Tables | :o: | |
|
||||
|
||||
### Excel 2007+ XML (XLSX/XLSM)
|
||||
|
||||
XLSX and XLSM files are ZIP containers containing a series of XML files in
|
||||
accordance with the Open Packaging Conventions (OPC). The XLSM filetype, almost
|
||||
identical to XLSX, is used for files containing macros.
|
||||
|
||||
The format is standardized in ECMA-376 and later in ISO/IEC 29500. Excel does
|
||||
not follow the specification, and there are additional documents discussing how
|
||||
Excel deviates from the specification.
|
||||
|
||||
### Excel 2.0-95 (BIFF2/BIFF3/BIFF4/BIFF5)
|
||||
|
||||
@ -816,26 +892,6 @@ Excel HTML worksheets include special metadata encoded in styles. For example,
|
||||
`mso-number-format` is a localized string containing the number format. Despite
|
||||
the metadata the output is valid HTML, although it does accept bare `&` symbols.
|
||||
|
||||
## Tested Environments
|
||||
|
||||
- NodeJS 0.8, 0.9, 0.10, 0.11, 0.12, 4.x, 5.x, 6.x, 7.x
|
||||
- IE 6/7/8/9/10/11 (IE6-9 browsers require shims for interacting with client)
|
||||
- Chrome 24+
|
||||
- Safari 6+
|
||||
- FF 18+
|
||||
|
||||
Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:
|
||||
|
||||
- <https://travis-ci.org/SheetJS/js-xlsx> for XLSX module in nodejs
|
||||
- <https://travis-ci.org/SheetJS/SheetJS.github.io> for XLS\* modules
|
||||
- <https://saucelabs.com/u/sheetjs> for XLS\* modules using Sauce Labs
|
||||
|
||||
## Test Files
|
||||
|
||||
Test files are housed in [another repo](https://github.com/SheetJS/test_files).
|
||||
|
||||
Running `make init` will refresh the `test_files` submodule and get the files.
|
||||
|
||||
## Testing
|
||||
|
||||
`make test` will run the node-based tests. By default it runs tests on files in
|
||||
@ -865,9 +921,9 @@ $ make lint # JSHint and JSCS checks
|
||||
$ make flow # make lint + Flow checking
|
||||
```
|
||||
|
||||
To run the in-browser tests, clone
|
||||
[The oss.sheetjs.com repo](https://github.com/SheetJS/SheetJS.github.io) and
|
||||
replace the xlsx.js file (then fire up the browser and go to `stress.html`):
|
||||
To run the in-browser tests, clone the repo for
|
||||
[oss.sheetjs.com](https://github.com/SheetJS/SheetJS.github.io) and replace
|
||||
the xlsx.js file (then fire up the browser and go to `stress.html`):
|
||||
|
||||
```bash
|
||||
$ cp xlsx.js ../SheetJS.github.io
|
||||
@ -875,6 +931,26 @@ $ cd ../SheetJS.github.io
|
||||
$ simplehttpserver # or "python -mSimpleHTTPServer" or "serve"
|
||||
$ open -a Chromium.app http://localhost:8000/stress.html
|
||||
```
|
||||
### Tested Environments
|
||||
|
||||
- NodeJS 0.8, 0.9, 0.10, 0.11, 0.12, 4.x, 5.x, 6.x, 7.x
|
||||
- IE 6/7/8/9/10/11 (IE6-9 browsers require shims for interacting with client)
|
||||
- Chrome 24+
|
||||
- Safari 6+
|
||||
- FF 18+
|
||||
|
||||
Tests utilize the mocha testing framework. Travis-CI and Sauce Labs links:
|
||||
|
||||
- <https://travis-ci.org/SheetJS/js-xlsx> for XLSX module in nodejs
|
||||
- <https://travis-ci.org/SheetJS/SheetJS.github.io> for XLS\* modules
|
||||
- <https://saucelabs.com/u/sheetjs> for XLS\* modules using Sauce Labs
|
||||
|
||||
### Test Files
|
||||
|
||||
Test files are housed in [another repo](https://github.com/SheetJS/test_files).
|
||||
|
||||
Running `make init` will refresh the `test_files` submodule and get the files.
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
|
@ -1 +1 @@
|
||||
XLSX.version = '0.9.1';
|
||||
XLSX.version = '0.9.2';
|
||||
|
@ -193,7 +193,6 @@ function parse_ct(data/*:?string*/, opts) {
|
||||
case '<Default': ctext[y.Extension] = y.ContentType; break;
|
||||
case '<Override':
|
||||
if(ct[ct2type[y.ContentType]] !== undefined) ct[ct2type[y.ContentType]].push(y.PartName);
|
||||
else if(opts.WTF) console.error(y);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
@ -70,7 +70,7 @@ function write_ext_props(cp, opts)/*:string*/ {
|
||||
|
||||
/* TODO: HeadingPairs, TitlesOfParts */
|
||||
o[o.length] = (W('HeadingPairs', W('vt:vector', W('vt:variant', '<vt:lpstr>Worksheets</vt:lpstr>')+W('vt:variant', W('vt:i4', String(cp.Worksheets))), {size:2, baseType:"variant"})));
|
||||
o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + s + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
|
||||
o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + escapexml(s) + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
|
||||
if(o.length>2){ o[o.length] = ('</Properties>'); o[1]=o[1].replace("/>",">"); }
|
||||
return o.join("");
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ function parse_XTI(blob, length) {
|
||||
function parse_RkRec(blob, length) {
|
||||
var ixfe = blob.read_shift(2);
|
||||
var RK = parse_RkNumber(blob);
|
||||
//console.log("::", ixfe, RK,";;");
|
||||
return [ixfe, RK];
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
function hex2RGB(h) {
|
||||
var o = h.substr(h[0]==="#"?1:0,6);
|
||||
return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)];
|
||||
return [parseInt(o.substr(0,2),16),parseInt(o.substr(2,2),16),parseInt(o.substr(4,2),16)];
|
||||
}
|
||||
function rgb2Hex(rgb) {
|
||||
for(var i=0,o=1; i!=3; ++i) o = o*256 + (rgb[i]>255?255:rgb[i]<0?0:rgb[i]);
|
||||
|
@ -68,10 +68,15 @@ function update_xfext(xf, xfext) {
|
||||
switch(xfe[0]) { /* 2.5.108 extPropData */
|
||||
case 0x04: break; /* foreground color */
|
||||
case 0x05: break; /* background color */
|
||||
case 0x07: case 0x08: case 0x09: case 0x0a: break;
|
||||
case 0x06: break; /* gradient fill */
|
||||
case 0x07: break; /* top cell border color */
|
||||
case 0x08: break; /* bottom cell border color */
|
||||
case 0x09: break; /* left cell border color */
|
||||
case 0x0a: break; /* right cell border color */
|
||||
case 0x0b: break; /* diagonal cell border color */
|
||||
case 0x0d: break; /* text color */
|
||||
case 0x0e: break; /* font scheme */
|
||||
default: throw "bafuq" + xfe[0].toString(16);
|
||||
case 0x0f: break; /* indentation level */
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -16,9 +16,10 @@ var rc_to_a1 = (function(){
|
||||
};
|
||||
})();
|
||||
|
||||
/* TODO actually parse the formula */
|
||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
|
||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
|
||||
function shift_formula_str(f/*:string*/, delta/*:Cell*/)/*:string*/ {
|
||||
return f.replace(/(^|[^A-Z0-9])([$]?)([A-Z]+)([$]?)(\d+)/g, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
return f.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
return $1+($2=="$" ? $2+$3 : encode_col(decode_col($3)+delta.c))+($4=="$" ? $4+$5 : encode_row(decode_row($5) + delta.r));
|
||||
});
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
case 'inlineStr':
|
||||
cref = d.match(isregex);
|
||||
p.t = 's';
|
||||
if(cref != null) { if((sstr = parse_si(cref[1]))) p.v = sstr.t; } else p.v = "";
|
||||
if(cref != null && (sstr = parse_si(cref[1]))) p.v = sstr.t; else p.v = "";
|
||||
break; // inline string
|
||||
case 'b': p.v = parsexmlbool(p.v); break;
|
||||
case 'd':
|
||||
|
@ -41,7 +41,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
||||
/* 18.2.19 sheet CT_Sheet + */
|
||||
case '<sheet': delete y[0]; y.name = utf8read(y.name); wb.Sheets.push(y); break;
|
||||
case '<sheet': delete y[0]; y.name = unescapexml(utf8read(y.name)); wb.Sheets.push(y); break;
|
||||
case '</sheet>': break;
|
||||
|
||||
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
||||
@ -140,7 +140,7 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
|
||||
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb)}));
|
||||
o[o.length] = "<sheets>";
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i)
|
||||
o[o.length] = (writextag('sheet',null,{name:wb.SheetNames[i].substr(0,31), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
||||
o[o.length] = (writextag('sheet',null,{name:escapexml(wb.SheetNames[i].substr(0,31)), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
||||
o[o.length] = "</sheets>";
|
||||
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
||||
return o.join("");
|
||||
|
@ -237,7 +237,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
||||
r = c = 0;
|
||||
state.push([Rn[3], false]);
|
||||
tmp = xlml_parsexmltag(Rn[0]);
|
||||
sheetname = tmp.Name;
|
||||
sheetname = unescapexml(tmp.Name);
|
||||
cursheet = {};
|
||||
mergecells = [];
|
||||
}
|
||||
|
22
dist/xlsx.core.min.js
vendored
22
dist/xlsx.core.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
vendored
2
dist/xlsx.core.min.map
vendored
File diff suppressed because one or more lines are too long
24
dist/xlsx.full.min.js
vendored
24
dist/xlsx.full.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
vendored
2
dist/xlsx.full.min.map
vendored
File diff suppressed because one or more lines are too long
332
dist/xlsx.js
vendored
332
dist/xlsx.js
vendored
@ -5,7 +5,7 @@
|
||||
/*exported XLSX */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.9.1';
|
||||
XLSX.version = '0.9.2';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js');
|
||||
@ -92,7 +92,7 @@ function s2a(s) {
|
||||
var bconcat = function(bufs) { return [].concat.apply([], bufs); };
|
||||
|
||||
var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/;
|
||||
/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */
|
||||
/* ssf.js (C) 2013-present SheetJS -- http://sheetjs.com */
|
||||
/*jshint -W041 */
|
||||
var SSF = {};
|
||||
var make_ssf = function make_ssf(SSF){
|
||||
@ -106,7 +106,7 @@ function pad0r1(v,d){var t=""+Math.round(v); return t.length>=d?t:fill('0',d-t.l
|
||||
function pad0r2(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
|
||||
var p2_32 = Math.pow(2,32);
|
||||
function pad0r(v,d){if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); }
|
||||
function isgeneral(s, i) { return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; }
|
||||
function isgeneral(s, i) { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; }
|
||||
/* Options */
|
||||
var opts_fmt = [
|
||||
["date1904", 0],
|
||||
@ -118,36 +118,36 @@ function fixopts(o){
|
||||
}
|
||||
SSF.opts = opts_fmt;
|
||||
var table_fmt = {
|
||||
0: 'General',
|
||||
1: '0',
|
||||
2: '0.00',
|
||||
3: '#,##0',
|
||||
4: '#,##0.00',
|
||||
9: '0%',
|
||||
10: '0.00%',
|
||||
11: '0.00E+00',
|
||||
12: '# ?/?',
|
||||
13: '# ??/??',
|
||||
14: 'm/d/yy',
|
||||
15: 'd-mmm-yy',
|
||||
16: 'd-mmm',
|
||||
17: 'mmm-yy',
|
||||
18: 'h:mm AM/PM',
|
||||
19: 'h:mm:ss AM/PM',
|
||||
20: 'h:mm',
|
||||
21: 'h:mm:ss',
|
||||
22: 'm/d/yy h:mm',
|
||||
37: '#,##0 ;(#,##0)',
|
||||
38: '#,##0 ;[Red](#,##0)',
|
||||
39: '#,##0.00;(#,##0.00)',
|
||||
40: '#,##0.00;[Red](#,##0.00)',
|
||||
45: 'mm:ss',
|
||||
46: '[h]:mm:ss',
|
||||
47: 'mmss.0',
|
||||
48: '##0.0E+0',
|
||||
49: '@',
|
||||
56: '"上午/下午 "hh"時"mm"分"ss"秒 "',
|
||||
65535: 'General'
|
||||
0: 'General',
|
||||
1: '0',
|
||||
2: '0.00',
|
||||
3: '#,##0',
|
||||
4: '#,##0.00',
|
||||
9: '0%',
|
||||
10: '0.00%',
|
||||
11: '0.00E+00',
|
||||
12: '# ?/?',
|
||||
13: '# ??/??',
|
||||
14: 'm/d/yy',
|
||||
15: 'd-mmm-yy',
|
||||
16: 'd-mmm',
|
||||
17: 'mmm-yy',
|
||||
18: 'h:mm AM/PM',
|
||||
19: 'h:mm:ss AM/PM',
|
||||
20: 'h:mm',
|
||||
21: 'h:mm:ss',
|
||||
22: 'm/d/yy h:mm',
|
||||
37: '#,##0 ;(#,##0)',
|
||||
38: '#,##0 ;[Red](#,##0)',
|
||||
39: '#,##0.00;(#,##0.00)',
|
||||
40: '#,##0.00;[Red](#,##0.00)',
|
||||
45: 'mm:ss',
|
||||
46: '[h]:mm:ss',
|
||||
47: 'mmss.0',
|
||||
48: '##0.0E+0',
|
||||
49: '@',
|
||||
56: '"上午/下午 "hh"時"mm"分"ss"秒 "',
|
||||
65535: 'General'
|
||||
};
|
||||
var days = [
|
||||
['Sun', 'Sunday'],
|
||||
@ -253,8 +253,8 @@ function parse_date_code(v,opts,b2) {
|
||||
else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;}
|
||||
else {
|
||||
if(date > 60) --date;
|
||||
/* 1 = Jan 1 1900 */
|
||||
var d = new Date(1900,0,1);
|
||||
/* 1 = Jan 1 1900 in Gregorian */
|
||||
var d = new Date(1900, 0, 1);
|
||||
d.setDate(d.getDate() + date - 1);
|
||||
dout = [d.getFullYear(), d.getMonth()+1,d.getDate()];
|
||||
dow = d.getDay();
|
||||
@ -316,7 +316,7 @@ function write_date(type, fmt, val, ss0) {
|
||||
}
|
||||
switch(fmt) {
|
||||
case 's': case 'ss': case '.0': case '.00': case '.000':
|
||||
if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100;
|
||||
if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100;
|
||||
else tt = ss0 === 1 ? 10 : 1;
|
||||
ss = Math.round((tt)*(val.S + val.u));
|
||||
if(ss >= 60*tt) ss = 0;
|
||||
@ -366,23 +366,23 @@ function write_num_exp(fmt, val){
|
||||
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
|
||||
if(o.indexOf("e") === -1) {
|
||||
var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E);
|
||||
if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
|
||||
if(o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
|
||||
else o += "E+" + (fakee - ee);
|
||||
while(o.substr(0,2) === "0.") {
|
||||
o = o[0] + o.substr(2,period) + "." + o.substr(2+period);
|
||||
o = o.charAt(0) + o.substr(2,period) + "." + o.substr(2+period);
|
||||
o = o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.");
|
||||
}
|
||||
o = o.replace(/\+-/,"-");
|
||||
}
|
||||
o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
|
||||
} else o = val.toExponential(idx);
|
||||
if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o[o.length-1];
|
||||
if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o.charAt(o.length-1);
|
||||
if(fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/,"e");
|
||||
return o.replace("e","E");
|
||||
}
|
||||
var frac1 = /# (\?+)( ?)\/( ?)(\d+)/;
|
||||
function write_num_f1(r, aval, sign) {
|
||||
var den = parseInt(r[4]), rr = Math.round(aval * den), base = Math.floor(rr/den);
|
||||
var den = parseInt(r[4],10), rr = Math.round(aval * den), base = Math.floor(rr/den);
|
||||
var myn = (rr - base*den), myd = den;
|
||||
return sign + (base === 0 ? "" : ""+base) + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad_(myn,r[1].length) + r[2] + "/" + r[3] + pad0(myd,r[4].length));
|
||||
}
|
||||
@ -415,39 +415,40 @@ function write_num_flt(type, fmt, val) {
|
||||
if(fmt.indexOf('%') !== -1) return write_num_pct(type, fmt, val);
|
||||
if(fmt.indexOf('E') !== -1) return write_num_exp(fmt, val);
|
||||
if(fmt.charCodeAt(0) === 36) return "$"+write_num_flt(type,fmt.substr(fmt[1]==' '?2:1),val);
|
||||
var o, oo;
|
||||
var o;
|
||||
var r, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
|
||||
if(fmt.match(/^00+$/)) return sign + pad0r(aval,fmt.length);
|
||||
if(fmt.match(/^[#?]+$/)) {
|
||||
o = pad0r(val,0); if(o === "0") o = "";
|
||||
return o.length > fmt.length ? o : hashq(fmt.substr(0,fmt.length-o.length)) + o;
|
||||
}
|
||||
if((r = fmt.match(frac1)) !== null) return write_num_f1(r, aval, sign);
|
||||
if(fmt.match(/^#+0+$/) !== null) return sign + pad0r(aval,fmt.length - fmt.indexOf("0"));
|
||||
if((r = fmt.match(dec1)) !== null) {
|
||||
if((r = fmt.match(frac1))) return write_num_f1(r, aval, sign);
|
||||
if(fmt.match(/^#+0+$/)) return sign + pad0r(aval,fmt.length - fmt.indexOf("0"));
|
||||
if((r = fmt.match(dec1))) {
|
||||
// $FlowIgnore
|
||||
o = rnd(val, r[1].length).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); });
|
||||
return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,".");
|
||||
}
|
||||
fmt = fmt.replace(/^#+([0.])/, "$1");
|
||||
if((r = fmt.match(/^(0*)\.(#*)$/)) !== null) {
|
||||
if((r = fmt.match(/^(0*)\.(#*)$/))) {
|
||||
return sign + rnd(aval, r[2].length).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
|
||||
}
|
||||
if((r = fmt.match(/^#,##0(\.?)$/)) !== null) return sign + commaify(pad0r(aval,0));
|
||||
if((r = fmt.match(/^#,##0\.([#0]*0)$/)) !== null) {
|
||||
if((r = fmt.match(/^#,##0(\.?)$/))) return sign + commaify(pad0r(aval,0));
|
||||
if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
|
||||
return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(""+(Math.floor(val))) + "." + pad0(dec(val, r[1].length),r[1].length);
|
||||
}
|
||||
if((r = fmt.match(/^#,#*,#0/)) !== null) return write_num_flt(type,fmt.replace(/^#,#*,/,""),val);
|
||||
if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/)) !== null) {
|
||||
if((r = fmt.match(/^#,#*,#0/))) return write_num_flt(type,fmt.replace(/^#,#*,/,""),val);
|
||||
if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/))) {
|
||||
o = _strrev(write_num_flt(type, fmt.replace(/[\\-]/g,""), val));
|
||||
ri = 0;
|
||||
return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri<o.length?o[ri++]:x==='0'?'0':"";}));
|
||||
}
|
||||
if(fmt.match(phone) !== null) {
|
||||
if(fmt.match(phone)) {
|
||||
o = write_num_flt(type, "##########", val);
|
||||
return "(" + o.substr(0,3) + ") " + o.substr(3, 3) + "-" + o.substr(6);
|
||||
}
|
||||
var oa = "";
|
||||
if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/)) !== null) {
|
||||
if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/))) {
|
||||
ri = Math.min(r[4].length,7);
|
||||
ff = frac(aval, Math.pow(10,ri)-1, false);
|
||||
o = "" + sign;
|
||||
@ -459,23 +460,23 @@ function write_num_flt(type, fmt, val) {
|
||||
o += oa;
|
||||
return o;
|
||||
}
|
||||
if((r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/)) !== null) {
|
||||
if((r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/))) {
|
||||
ri = Math.min(Math.max(r[1].length, r[4].length),7);
|
||||
ff = frac(aval, Math.pow(10,ri)-1, true);
|
||||
return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad_(ff[1],ri) + r[2] + "/" + r[3] + rpad_(ff[2],ri): fill(" ", 2*ri+1 + r[2].length + r[3].length));
|
||||
}
|
||||
if((r = fmt.match(/^[#0?]+$/)) !== null) {
|
||||
if((r = fmt.match(/^[#0?]+$/))) {
|
||||
o = pad0r(val, 0);
|
||||
if(fmt.length <= o.length) return o;
|
||||
return hashq(fmt.substr(0,fmt.length-o.length)) + o;
|
||||
}
|
||||
if((r = fmt.match(/^([#0?]+)\.([#0]+)$/)) !== null) {
|
||||
if((r = fmt.match(/^([#0?]+)\.([#0]+)$/))) {
|
||||
o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
|
||||
ri = o.indexOf(".");
|
||||
var lres = fmt.indexOf(".") - ri, rres = fmt.length - o.length - lres;
|
||||
return hashq(fmt.substr(0,lres) + o + fmt.substr(fmt.length-rres));
|
||||
}
|
||||
if((r = fmt.match(/^00,000\.([#0]*0)$/)) !== null) {
|
||||
if((r = fmt.match(/^00,000\.([#0]*0)$/))) {
|
||||
ri = dec(val, r[1].length);
|
||||
return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(flr(val)).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(ri,r[1].length);
|
||||
}
|
||||
@ -504,13 +505,13 @@ function write_num_exp2(fmt, val){
|
||||
o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
|
||||
if(!o.match(/[Ee]/)) {
|
||||
var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E);
|
||||
if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
|
||||
if(o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
|
||||
else o += "E+" + (fakee - ee);
|
||||
o = o.replace(/\+-/,"-");
|
||||
}
|
||||
o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
|
||||
} else o = val.toExponential(idx);
|
||||
if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o[o.length-1];
|
||||
if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o.charAt(o.length-1);
|
||||
if(fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/,"e");
|
||||
return o.replace("e","E");
|
||||
}
|
||||
@ -531,32 +532,33 @@ function write_num_int(type, fmt, val) {
|
||||
o = (""+val); if(val === 0) o = "";
|
||||
return o.length > fmt.length ? o : hashq(fmt.substr(0,fmt.length-o.length)) + o;
|
||||
}
|
||||
if((r = fmt.match(frac1)) !== null) return write_num_f2(r, aval, sign);
|
||||
if(fmt.match(/^#+0+$/) !== null) return sign + pad0(aval,fmt.length - fmt.indexOf("0"));
|
||||
if((r = fmt.match(dec1)) !== null) {
|
||||
if((r = fmt.match(frac1))) return write_num_f2(r, aval, sign);
|
||||
if(fmt.match(/^#+0+$/)) return sign + pad0(aval,fmt.length - fmt.indexOf("0"));
|
||||
if((r = fmt.match(dec1))) {
|
||||
// $FlowIgnore
|
||||
o = (""+val).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); });
|
||||
return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,".");
|
||||
}
|
||||
fmt = fmt.replace(/^#+([0.])/, "$1");
|
||||
if((r = fmt.match(/^(0*)\.(#*)$/)) !== null) {
|
||||
if((r = fmt.match(/^(0*)\.(#*)$/))) {
|
||||
return sign + (""+aval).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
|
||||
}
|
||||
if((r = fmt.match(/^#,##0(\.?)$/)) !== null) return sign + commaify((""+aval));
|
||||
if((r = fmt.match(/^#,##0\.([#0]*0)$/)) !== null) {
|
||||
if((r = fmt.match(/^#,##0(\.?)$/))) return sign + commaify((""+aval));
|
||||
if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
|
||||
return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify((""+val)) + "." + fill('0',r[1].length);
|
||||
}
|
||||
if((r = fmt.match(/^#,#*,#0/)) !== null) return write_num_int(type,fmt.replace(/^#,#*,/,""),val);
|
||||
if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/)) !== null) {
|
||||
if((r = fmt.match(/^#,#*,#0/))) return write_num_int(type,fmt.replace(/^#,#*,/,""),val);
|
||||
if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/))) {
|
||||
o = _strrev(write_num_int(type, fmt.replace(/[\\-]/g,""), val));
|
||||
ri = 0;
|
||||
return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri<o.length?o[ri++]:x==='0'?'0':"";}));
|
||||
}
|
||||
if(fmt.match(phone) !== null) {
|
||||
if(fmt.match(phone)) {
|
||||
o = write_num_int(type, "##########", val);
|
||||
return "(" + o.substr(0,3) + ") " + o.substr(3, 3) + "-" + o.substr(6);
|
||||
}
|
||||
var oa = "";
|
||||
if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/)) !== null) {
|
||||
if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/))) {
|
||||
ri = Math.min(r[4].length,7);
|
||||
ff = frac(aval, Math.pow(10,ri)-1, false);
|
||||
o = "" + sign;
|
||||
@ -568,23 +570,23 @@ function write_num_int(type, fmt, val) {
|
||||
o += oa;
|
||||
return o;
|
||||
}
|
||||
if((r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/)) !== null) {
|
||||
if((r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/))) {
|
||||
ri = Math.min(Math.max(r[1].length, r[4].length),7);
|
||||
ff = frac(aval, Math.pow(10,ri)-1, true);
|
||||
return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad_(ff[1],ri) + r[2] + "/" + r[3] + rpad_(ff[2],ri): fill(" ", 2*ri+1 + r[2].length + r[3].length));
|
||||
}
|
||||
if((r = fmt.match(/^[#0?]+$/)) !== null) {
|
||||
if((r = fmt.match(/^[#0?]+$/))) {
|
||||
o = "" + val;
|
||||
if(fmt.length <= o.length) return o;
|
||||
return hashq(fmt.substr(0,fmt.length-o.length)) + o;
|
||||
}
|
||||
if((r = fmt.match(/^([#0]+)\.([#0]+)$/)) !== null) {
|
||||
if((r = fmt.match(/^([#0]+)\.([#0]+)$/))) {
|
||||
o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
|
||||
ri = o.indexOf(".");
|
||||
var lres = fmt.indexOf(".") - ri, rres = fmt.length - o.length - lres;
|
||||
return hashq(fmt.substr(0,lres) + o + fmt.substr(fmt.length-rres));
|
||||
}
|
||||
if((r = fmt.match(/^00,000\.([#0]*0)$/)) !== null) {
|
||||
if((r = fmt.match(/^00,000\.([#0]*0)$/))) {
|
||||
return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify(""+val).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(0,r[1].length);
|
||||
}
|
||||
switch(fmt) {
|
||||
@ -619,7 +621,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
var hr='H';
|
||||
/* Tokenize */
|
||||
while(i < fmt.length) {
|
||||
switch((c = fmt[i])) {
|
||||
switch((c = fmt.charAt(i))) {
|
||||
case 'G': /* General */
|
||||
if(!isgeneral(fmt, i)) throw new Error('unrecognized character ' + c + ' in ' +fmt);
|
||||
out[out.length] = {t:'G', v:'General'}; i+=7; break;
|
||||
@ -633,7 +635,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
out[out.length] = {t:'T', v:v}; ++i; break;
|
||||
case 'B': case 'b':
|
||||
if(fmt[i+1] === "1" || fmt[i+1] === "2") {
|
||||
if(dt==null) { dt=parse_date_code(v, opts, fmt[i+1] === "2"); if(dt==null) return ""; }
|
||||
if(dt==null) { dt=parse_date_code(v, opts, fmt[i+1] === "2"); if(dt==null) return ""; }
|
||||
out[out.length] = {t:'X', v:fmt.substr(i,2)}; lst = c; i+=2; break;
|
||||
}
|
||||
/* falls through */
|
||||
@ -650,15 +652,15 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
case 'A':
|
||||
q={t:c, v:"A"};
|
||||
if(dt==null) dt=parse_date_code(v, opts);
|
||||
if(fmt.substr(i, 3) === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
|
||||
else if(fmt.substr(i,5) === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
|
||||
if(fmt.substr(i, 3) === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
|
||||
else if(fmt.substr(i,5) === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
|
||||
else { q.t = "t"; ++i; }
|
||||
if(dt==null && q.t === 'T') return "";
|
||||
out[out.length] = q; lst = c; break;
|
||||
case '[':
|
||||
o = c;
|
||||
while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i];
|
||||
if(o.slice(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
|
||||
if(o.substr(-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()};
|
||||
@ -709,12 +711,12 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
switch(bt) {
|
||||
case 0: break;
|
||||
case 1:
|
||||
if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
|
||||
if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
|
||||
if(dt.S >= 60) { dt.S = 0; ++dt.M; }
|
||||
if(dt.M >= 60) { dt.M = 0; ++dt.H; }
|
||||
break;
|
||||
case 2:
|
||||
if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
|
||||
if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
|
||||
if(dt.S >= 60) { dt.S = 0; ++dt.M; }
|
||||
break;
|
||||
}
|
||||
@ -723,9 +725,9 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
for(i=0; i < out.length; ++i) {
|
||||
switch(out[i].t) {
|
||||
case 't': case 'T': case ' ': case 'D': break;
|
||||
case 'X': out[i] = undefined; break;
|
||||
case 'X': out[i].v = ""; out[i].t = ";"; break;
|
||||
case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z':
|
||||
out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
|
||||
out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
|
||||
out[i].t = 't'; break;
|
||||
case 'n': case '(': case '?':
|
||||
jj = i+1;
|
||||
@ -736,7 +738,7 @@ function eval_fmt(fmt, v, opts, flen) {
|
||||
c === 't' && (out[jj].v === '/' || '$€'.indexOf(out[jj].v) > -1 || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?')
|
||||
)) {
|
||||
out[i].v += out[jj].v;
|
||||
out[jj] = undefined; ++jj;
|
||||
out[jj] = {v:"", t:";"}; ++jj;
|
||||
}
|
||||
nstr += out[i].v;
|
||||
i = jj-1; break;
|
||||
@ -819,7 +821,7 @@ function choose_fmt(f, v) {
|
||||
var fmt = split_fmt(f);
|
||||
var l = fmt.length, lat = fmt[l-1].indexOf("@");
|
||||
if(l<4 && lat>-1) --l;
|
||||
if(fmt.length > 4) throw "cannot find right format for |" + fmt + "|";
|
||||
if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
|
||||
if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
|
||||
switch(fmt.length) {
|
||||
case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
|
||||
@ -841,7 +843,7 @@ function format(fmt,v,o) {
|
||||
var sfmt = "";
|
||||
switch(typeof fmt) {
|
||||
case "string": sfmt = fmt; break;
|
||||
case "number": sfmt = (o.table != null ? o.table : table_fmt)[fmt]; break;
|
||||
case "number": sfmt = (o.table != null ? (o.table) : table_fmt)[fmt]; break;
|
||||
}
|
||||
if(isgeneral(sfmt,0)) return general_fmt(v, o);
|
||||
var f = choose_fmt(sfmt, v);
|
||||
@ -1425,12 +1427,12 @@ function parsexmltag(tag, skip_root) {
|
||||
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) {
|
||||
//if(q.indexOf("_") > 0) q = q.substr(0, q.indexOf("_")); // from ods
|
||||
if(q.indexOf("_") > 0) q = q.substr(0, q.indexOf("_")); // from ods
|
||||
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; // from ods
|
||||
if(z[k] && q.substr(j-3,3) == "ext") continue; // from ods
|
||||
z[k] = v;
|
||||
}
|
||||
}
|
||||
@ -1517,17 +1519,18 @@ if(has_buf) {
|
||||
};
|
||||
var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
|
||||
if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb;
|
||||
// $FlowIgnore
|
||||
var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); };
|
||||
if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc;
|
||||
}
|
||||
|
||||
// matches <foo>...</foo> extracts content
|
||||
var matchtag = (function() {
|
||||
var mtcache = {};
|
||||
var mtcache = ({});
|
||||
return function matchtag(f,g) {
|
||||
var t = f+"|"+(g||"");
|
||||
if(mtcache[t] !== undefined) return mtcache[t];
|
||||
return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)</(?:\\w+:)?'+f+'>',(g||"")));
|
||||
if(mtcache[t]) return mtcache[t];
|
||||
return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)</(?:\\w+:)?'+f+'>',((g||""))));
|
||||
};
|
||||
})();
|
||||
|
||||
@ -1720,7 +1723,7 @@ function ReadShift(size, t) {
|
||||
case 2: oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); this.l += 2; return oI;
|
||||
case 4:
|
||||
if(t === 'i' || (this[this.l+3] & 0x80)===0) { oI = __readInt32LE(this, this.l); this.l += 4; return oI; }
|
||||
else { oR = __readUInt32LE(this, this.l); this.l += 4; return oR; } break;
|
||||
else { oR = __readUInt32LE(this, this.l); this.l += 4; } return oR;
|
||||
case 8: if(t === 'f') { oR = __double(this, this.l); this.l += 8; return oR; }
|
||||
/* falls through */
|
||||
case 16: o = __hexlify(this, this.l, size); break;
|
||||
@ -1733,14 +1736,14 @@ var __writeUInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] =
|
||||
var __writeInt32LE = function(b, val, idx) { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
|
||||
|
||||
function WriteShift(t, val, f) {
|
||||
var size, i;
|
||||
var size = 0, i = 0;
|
||||
if(f === 'dbcs') {
|
||||
for(i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i);
|
||||
for(i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i);
|
||||
size = 2 * val.length;
|
||||
} else if(f === 'sbcs') {
|
||||
for(i = 0; i != val.length; ++i) this[this.l + i] = val.charCodeAt(i) & 0xFF;
|
||||
for(i = 0; i != val.length; ++i) this[this.l + i] = val.charCodeAt(i) & 0xFF;
|
||||
size = val.length;
|
||||
} else switch(t) {
|
||||
} else switch(t) {
|
||||
case 1: size = 1; this[this.l] = val&0xFF; break;
|
||||
case 2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break;
|
||||
case 3: size = 3; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; val >>>= 8; this[this.l+2] = val&0xFF; break;
|
||||
@ -1797,7 +1800,7 @@ function recordhopper(data, cb, opts) {
|
||||
function buf_array() {
|
||||
var bufs = [], blksz = 2048;
|
||||
var newblk = function ba_newblk(sz) {
|
||||
var o = new_buf(sz);
|
||||
var o = (new_buf(sz));
|
||||
prep_blob(o, 0);
|
||||
return o;
|
||||
};
|
||||
@ -1890,6 +1893,7 @@ function encode_range_xls(r, opts) {
|
||||
return encode_cell_xls(r.s) + ":" + encode_cell_xls(r.e);
|
||||
}
|
||||
var OFFCRYPTO = {};
|
||||
|
||||
var make_offcrypto = function(O, _crypto) {
|
||||
var crypto;
|
||||
if(typeof _crypto !== 'undefined') crypto = _crypto;
|
||||
@ -1906,7 +1910,8 @@ var make_offcrypto = function(O, _crypto) {
|
||||
j = (j + S[i] + (key[i%key.length]).charCodeAt(0))&255;
|
||||
t = S[i]; S[i] = S[j]; S[j] = t;
|
||||
}
|
||||
i = j = 0; out = Buffer(data.length);
|
||||
// $FlowIgnore
|
||||
i = j = 0; var out = Buffer(data.length);
|
||||
for(c = 0; c != data.length; ++c) {
|
||||
i = (i + 1)&255;
|
||||
j = (j + S[i])%256;
|
||||
@ -2561,7 +2566,6 @@ function parse_ct(data, opts) {
|
||||
case '<Default': ctext[y.Extension] = y.ContentType; break;
|
||||
case '<Override':
|
||||
if(ct[ct2type[y.ContentType]] !== undefined) ct[ct2type[y.ContentType]].push(y.PartName);
|
||||
else if(opts.WTF) console.error(y);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -2888,7 +2892,7 @@ function write_ext_props(cp, opts) {
|
||||
|
||||
/* TODO: HeadingPairs, TitlesOfParts */
|
||||
o[o.length] = (W('HeadingPairs', W('vt:vector', W('vt:variant', '<vt:lpstr>Worksheets</vt:lpstr>')+W('vt:variant', W('vt:i4', String(cp.Worksheets))), {size:2, baseType:"variant"})));
|
||||
o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + s + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
|
||||
o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + escapexml(s) + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
|
||||
if(o.length>2){ o[o.length] = ('</Properties>'); o[1]=o[1].replace("/>",">"); }
|
||||
return o.join("");
|
||||
}
|
||||
@ -2950,6 +2954,7 @@ function write_cust_props(cp, opts) {
|
||||
if(!cp) return o.join("");
|
||||
var pid = 1;
|
||||
keys(cp).forEach(function custprop(k) { ++pid;
|
||||
// $FlowIgnore
|
||||
o[o.length] = (writextag('property', write_vt(cp[k]), {
|
||||
'fmtid': '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}',
|
||||
'pid': pid,
|
||||
@ -3449,7 +3454,6 @@ function parse_XTI(blob, length) {
|
||||
function parse_RkRec(blob, length) {
|
||||
var ixfe = blob.read_shift(2);
|
||||
var RK = parse_RkNumber(blob);
|
||||
//console.log("::", ixfe, RK,";;");
|
||||
return [ixfe, RK];
|
||||
}
|
||||
|
||||
@ -3607,7 +3611,7 @@ function parse_BoundSheet8(blob, length, opts) {
|
||||
function parse_SST(blob, length) {
|
||||
var cnt = blob.read_shift(4);
|
||||
var ucnt = blob.read_shift(4);
|
||||
var strs = [];
|
||||
var strs = ([]);
|
||||
for(var i = 0; i != ucnt; ++i) {
|
||||
strs.push(parse_XLUnicodeRichExtendedString(blob));
|
||||
}
|
||||
@ -4524,6 +4528,7 @@ var parse_rs = (function parse_rs_factory() {
|
||||
|
||||
/* 18.4.8 si CT_Rst */
|
||||
var sitregex = /<(?:\w+:)?t[^>]*>([^<]*)<\/(?:\w+:)?t>/g, sirregex = /<(?:\w+:)?r>/;
|
||||
var sirphregex = /<(?:\w+:)?rPh.*?>(.*?)<\/(?:\w+:)?rPh>/g;
|
||||
function parse_si(x, opts) {
|
||||
var html = opts ? opts.cellHTML : true;
|
||||
var z = {};
|
||||
@ -4539,7 +4544,7 @@ function parse_si(x, opts) {
|
||||
/* 18.4.4 r CT_RElt (Rich Text Run) */
|
||||
else if((y = x.match(sirregex))) {
|
||||
z.r = utf8read(x);
|
||||
z.t = utf8read(unescapexml((x.replace(/<rPh.*?>(.*?)<\/rPh>/g, '').match(sitregex)||[]).join("").replace(tagregex,"")));
|
||||
z.t = utf8read(unescapexml((x.replace(sirphregex, '').match(sitregex)||[]).join("").replace(tagregex,"")));
|
||||
if(html) z.h = parse_rs(z.r);
|
||||
}
|
||||
/* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
|
||||
@ -4599,7 +4604,7 @@ function parse_BrtBeginSst(data, length) {
|
||||
|
||||
/* [MS-XLSB] 2.1.7.45 Shared Strings */
|
||||
function parse_sst_bin(data, opts) {
|
||||
var s = [];
|
||||
var s = ([]);
|
||||
var pass = false;
|
||||
recordhopper(data, function hopper_sst(val, R, RT) {
|
||||
switch(R.n) {
|
||||
@ -4818,7 +4823,7 @@ function parse_FilePass(blob, length, opts) {
|
||||
|
||||
function hex2RGB(h) {
|
||||
var o = h.substr(h[0]==="#"?1:0,6);
|
||||
return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)];
|
||||
return [parseInt(o.substr(0,2),16),parseInt(o.substr(2,2),16),parseInt(o.substr(4,2),16)];
|
||||
}
|
||||
function rgb2Hex(rgb) {
|
||||
for(var i=0,o=1; i!=3; ++i) o = o*256 + (rgb[i]>255?255:rgb[i]<0?0:rgb[i]);
|
||||
@ -4974,7 +4979,7 @@ function parse_numFmts(t, opts) {
|
||||
function write_numFmts(NF, opts) {
|
||||
var o = ["<numFmts>"];
|
||||
[[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) {
|
||||
for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
|
||||
for(var i = r[0]; i <= r[1]; ++i) if(NF[i]) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
|
||||
});
|
||||
if(o.length === 1) return "";
|
||||
o[o.length] = ("</numFmts>");
|
||||
@ -5064,7 +5069,7 @@ RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/
|
||||
|
||||
function write_sty_xml(wb, opts) {
|
||||
var o = [XML_HEADER, STYLES_XML_ROOT], w;
|
||||
if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
|
||||
if(wb.SSF && (w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
|
||||
o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
|
||||
o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
|
||||
o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
|
||||
@ -5560,10 +5565,15 @@ function update_xfext(xf, xfext) {
|
||||
switch(xfe[0]) { /* 2.5.108 extPropData */
|
||||
case 0x04: break; /* foreground color */
|
||||
case 0x05: break; /* background color */
|
||||
case 0x07: case 0x08: case 0x09: case 0x0a: break;
|
||||
case 0x06: break; /* gradient fill */
|
||||
case 0x07: break; /* top cell border color */
|
||||
case 0x08: break; /* bottom cell border color */
|
||||
case 0x09: break; /* left cell border color */
|
||||
case 0x0a: break; /* right cell border color */
|
||||
case 0x0b: break; /* diagonal cell border color */
|
||||
case 0x0d: break; /* text color */
|
||||
case 0x0e: break; /* font scheme */
|
||||
default: throw "bafuq" + xfe[0].toString(16);
|
||||
case 0x0f: break; /* indentation level */
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -5756,9 +5766,10 @@ var rc_to_a1 = (function(){
|
||||
};
|
||||
})();
|
||||
|
||||
/* TODO actually parse the formula */
|
||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
|
||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
|
||||
function shift_formula_str(f, delta) {
|
||||
return f.replace(/(^|[^A-Z0-9])([$]?)([A-Z]+)([$]?)(\d+)/g, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
return f.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
return $1+($2=="$" ? $2+$3 : encode_col(decode_col($3)+delta.c))+($4=="$" ? $4+$5 : encode_row(decode_row($5) + delta.r));
|
||||
});
|
||||
}
|
||||
@ -6097,6 +6108,7 @@ function parse_PtgExtraArray(blob, length, opts) {
|
||||
rows = 1 + blob.read_shift(2); //DRw
|
||||
}
|
||||
if(opts.biff >= 2 && opts.biff < 8) { --rows; if(--cols == 0) cols = 0x100; }
|
||||
// $FlowIgnore
|
||||
for(var i = 0, o=[]; i != rows && (o[i] = []); ++i)
|
||||
for(var j = 0; j != cols; ++j) o[i][j] = parse_SerAr(blob, opts.biff);
|
||||
return o;
|
||||
@ -6417,7 +6429,8 @@ function parse_Rgce(blob, length, opts) {
|
||||
id = blob[blob.l + 1];
|
||||
R = (id === 0x18 ? Ptg18 : Ptg19)[id];
|
||||
}
|
||||
if(!R || !R.f) { ptgs.push(parsenoop(blob, length)); }
|
||||
if(!R || !R.f) { /*ptgs.push*/(parsenoop(blob, length)); }
|
||||
// $FlowIgnore
|
||||
else { ptgs.push([R.n, R.f(blob, length, opts)]); }
|
||||
}
|
||||
return ptgs;
|
||||
@ -6431,7 +6444,8 @@ function stringify_array(f) {
|
||||
var y = x[j];
|
||||
if(y) switch(y[0]) {
|
||||
// TODO: handle embedded quotes
|
||||
case 0x02: r.push('"' + y[1].replace(/"/g,'""') + '"'); break;
|
||||
case 0x02:
|
||||
r.push('"' + y[1].replace(/"/g,'""') + '"'); break;
|
||||
default: r.push(y[1]);
|
||||
} else r.push("");
|
||||
}
|
||||
@ -6456,10 +6470,10 @@ var PtgBinOp = {
|
||||
PtgPower: "^",
|
||||
PtgSub: "-"
|
||||
};
|
||||
function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
function stringify_formula(formula/*Array<any>*/, range, cell, supbooks, opts) {
|
||||
//console.log(formula);
|
||||
var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
|
||||
var stack = [], e1, e2, type, c, ixti, nameidx, r, sname="";
|
||||
var stack = [], e1, e2, type, c, ixti=0, nameidx=0, r, sname="";
|
||||
if(!formula[0] || !formula[0][0]) return "";
|
||||
var last_sp = -1, sp = "";
|
||||
//console.log("--",cell,formula[0])
|
||||
@ -6489,10 +6503,13 @@ function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
e1 = stack.pop(); e2 = stack.pop();
|
||||
if(last_sp >= 0) {
|
||||
switch(formula[0][last_sp][1][0]) {
|
||||
// $FlowIgnore
|
||||
case 0: sp = fill(" ", formula[0][last_sp][1][1]); break;
|
||||
// $FlowIgnore
|
||||
case 1: sp = fill("\r", formula[0][last_sp][1][1]); break;
|
||||
default:
|
||||
sp = "";
|
||||
// $FlowIgnore
|
||||
if(opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + formula[0][last_sp][1][0]);
|
||||
}
|
||||
e2 = e2 + sp;
|
||||
@ -6562,6 +6579,7 @@ function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
/* 2.5.198.79 TODO: precision? */
|
||||
case 'PtgNum': stack.push(String(f[1])); break;
|
||||
/* 2.5.198.89 */
|
||||
// $FlowIgnore
|
||||
case 'PtgStr': stack.push('"' + f[1] + '"'); break;
|
||||
/* 2.5.198.57 */
|
||||
case 'PtgErr': stack.push(f[1]); break;
|
||||
@ -6594,7 +6612,7 @@ function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
/* f[1] = type, 0, nameindex */
|
||||
nameidx = f[1][2];
|
||||
var lbl = supbooks[0][nameidx];
|
||||
var name = lbl ? lbl.Name : "**MISSING**" + nameidx;
|
||||
var name = lbl ? lbl.Name : "**MISSING**" + String(nameidx);
|
||||
if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name];
|
||||
stack.push(name);
|
||||
break;
|
||||
@ -6602,7 +6620,7 @@ function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
/* 2.5.97.61 TODO: do something different for revisions */
|
||||
case 'PtgNameX':
|
||||
/* f[1] = type, ixti, nameindex */
|
||||
var bookidx = f[1][1]; nameidx = f[1][2]; var externbook;
|
||||
var bookidx = (f[1][1]); nameidx = f[1][2]; var externbook;
|
||||
/* TODO: Properly handle missing values */
|
||||
//console.log(bookidx, supbooks);
|
||||
if(opts.biff == 5) {
|
||||
@ -6622,11 +6640,16 @@ function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
if(last_sp >= 0) {
|
||||
sp = "";
|
||||
switch(formula[0][last_sp][1][0]) {
|
||||
// $FlowIgnore
|
||||
case 2: lp = fill(" ", formula[0][last_sp][1][1]) + lp; break;
|
||||
// $FlowIgnore
|
||||
case 3: lp = fill("\r", formula[0][last_sp][1][1]) + lp; break;
|
||||
// $FlowIgnore
|
||||
case 4: rp = fill(" ", formula[0][last_sp][1][1]) + rp; break;
|
||||
// $FlowIgnore
|
||||
case 5: rp = fill("\r", formula[0][last_sp][1][1]) + rp; break;
|
||||
default:
|
||||
// $FlowIgnore
|
||||
if(opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + formula[0][last_sp][1][0]);
|
||||
}
|
||||
last_sp = -1;
|
||||
@ -6643,7 +6666,7 @@ function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
/* 2.5.198.58 TODO */
|
||||
case 'PtgExp':
|
||||
c = {c:f[1][1],r:f[1][0]};
|
||||
var q = {c: cell.c, r:cell.r};
|
||||
var q = ({c: cell.c, r:cell.r});
|
||||
if(supbooks.sharedf[encode_cell(c)]) {
|
||||
var parsedf = (supbooks.sharedf[encode_cell(c)]);
|
||||
stack.push(stringify_formula(parsedf, _range, q, supbooks, opts));
|
||||
@ -6697,7 +6720,7 @@ function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
/* 2.5.198.72 TODO */
|
||||
case 'PtgMemFunc': break;
|
||||
|
||||
default: throw new Error('Unrecognized Formula Token: ' + f);
|
||||
default: throw new Error('Unrecognized Formula Token: ' + String(f));
|
||||
}
|
||||
var PtgNonDisp = ['PtgAttrSpace', 'PtgAttrSpaceSemi', 'PtgAttrGoto'];
|
||||
if(last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) {
|
||||
@ -6707,12 +6730,15 @@ function stringify_formula(formula, range, cell, supbooks, opts) {
|
||||
/* note: some bad XLSB files omit the PtgParen */
|
||||
case 4: _left = false;
|
||||
/* falls through */
|
||||
// $FlowIgnore
|
||||
case 0: sp = fill(" ", f[1][1]); break;
|
||||
case 5: _left = false;
|
||||
/* falls through */
|
||||
// $FlowIgnore
|
||||
case 1: sp = fill("\r", f[1][1]); break;
|
||||
default:
|
||||
sp = "";
|
||||
// $FlowIgnore
|
||||
if(opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + f[1][0]);
|
||||
}
|
||||
stack.push((_left ? sp : "") + stack.pop() + (_left ? "" : sp));
|
||||
@ -8333,7 +8359,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
case 'inlineStr':
|
||||
cref = d.match(isregex);
|
||||
p.t = 's';
|
||||
if(cref != null) { if((sstr = parse_si(cref[1]))) p.v = sstr.t; } else p.v = "";
|
||||
if(cref != null && (sstr = parse_si(cref[1]))) p.v = sstr.t; else p.v = "";
|
||||
break; // inline string
|
||||
case 'b': p.v = parsexmlbool(p.v); break;
|
||||
case 'd':
|
||||
@ -8402,7 +8428,7 @@ function write_ws_xml(idx, opts, wb) {
|
||||
|
||||
/* [MS-XLSB] 2.4.718 BrtRowHdr */
|
||||
function parse_BrtRowHdr(data, length) {
|
||||
var z = [];
|
||||
var z = ([]);
|
||||
z.r = data.read_shift(4);
|
||||
data.l += length-4;
|
||||
return z;
|
||||
@ -8628,7 +8654,7 @@ function parse_BrtArrFmla(data, length, opts) {
|
||||
var end = data.l + length;
|
||||
var rfx = parse_RfX(data, 16);
|
||||
var fAlwaysCalc = data.read_shift(1);
|
||||
var o = [rfx, null, fAlwaysCalc];
|
||||
var o = [rfx]; o[2] = fAlwaysCalc;
|
||||
if(opts.cellFormula) {
|
||||
var formula = parse_XLSBArrayParsedFormula(data, end - data.l, opts);
|
||||
o[1] = formula;
|
||||
@ -8640,7 +8666,7 @@ function parse_BrtArrFmla(data, length, opts) {
|
||||
function parse_BrtShrFmla(data, length, opts) {
|
||||
var end = data.l + length;
|
||||
var rfx = parse_UncheckedRfX(data, 16);
|
||||
var o = [rfx, null];
|
||||
var o = [rfx];
|
||||
if(opts.cellFormula) {
|
||||
var formula = parse_XLSBSharedParsedFormula(data, end - data.l, opts);
|
||||
o[1] = formula;
|
||||
@ -9147,7 +9173,7 @@ function parse_wb_xml(data, opts) {
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
||||
/* 18.2.19 sheet CT_Sheet + */
|
||||
case '<sheet': delete y[0]; y.name = utf8read(y.name); wb.Sheets.push(y); break;
|
||||
case '<sheet': delete y[0]; y.name = unescapexml(utf8read(y.name)); wb.Sheets.push(y); break;
|
||||
case '</sheet>': break;
|
||||
|
||||
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
||||
@ -9234,7 +9260,10 @@ var WB_XML_ROOT = writextag('workbook', null, {
|
||||
|
||||
function safe1904(wb) {
|
||||
/* TODO: store date1904 somewhere else */
|
||||
try { return parsexmlbool(wb.Workbook.WBProps.date1904) ? "true" : "false"; } catch(e) { return "false"; }
|
||||
if(!wb.Workbook) return "false";
|
||||
if(!wb.Workbook.WBProps) return "false";
|
||||
// $FlowIgnore
|
||||
return parsexmlbool(wb.Workbook.WBProps.date1904) ? "true" : "false";
|
||||
}
|
||||
|
||||
function write_wb_xml(wb, opts) {
|
||||
@ -9243,7 +9272,7 @@ function write_wb_xml(wb, opts) {
|
||||
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb)}));
|
||||
o[o.length] = "<sheets>";
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i)
|
||||
o[o.length] = (writextag('sheet',null,{name:wb.SheetNames[i].substr(0,31), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
||||
o[o.length] = (writextag('sheet',null,{name:escapexml(wb.SheetNames[i].substr(0,31)), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
||||
o[o.length] = "</sheets>";
|
||||
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
||||
return o.join("");
|
||||
@ -9377,6 +9406,7 @@ function parse_wb_bin(data, opts) {
|
||||
parse_wb_defaults(wb);
|
||||
|
||||
Names['!names'] = NameList;
|
||||
// $FlowIgnore
|
||||
wb.Names = Names;
|
||||
|
||||
return wb;
|
||||
@ -9563,15 +9593,16 @@ function xlml_format(format, value) {
|
||||
}
|
||||
|
||||
function xlml_set_custprop(Custprops, Rn, cp, val) {
|
||||
var oval = val;
|
||||
switch((cp[0].match(/dt:dt="([\w.]+)"/)||["",""])[1]) {
|
||||
case "boolean": val = parsexmlbool(val); break;
|
||||
case "i2": case "int": val = parseInt(val, 10); break;
|
||||
case "r4": case "float": val = parseFloat(val); break;
|
||||
case "date": case "dateTime.tz": val = new Date(val); break;
|
||||
case "boolean": oval = parsexmlbool(val); break;
|
||||
case "i2": case "int": oval = parseInt(val, 10); break;
|
||||
case "r4": case "float": oval = parseFloat(val); break;
|
||||
case "date": case "dateTime.tz": oval = new Date(val); break;
|
||||
case "i8": case "string": case "fixed": case "uuid": case "bin.base64": break;
|
||||
default: throw "bad custprop:" + cp[0];
|
||||
default: throw new Error("bad custprop:" + cp[0]);
|
||||
}
|
||||
Custprops[unescapexml(Rn[3])] = val;
|
||||
Custprops[unescapexml(Rn[3])] = oval;
|
||||
}
|
||||
|
||||
function safe_format_xlml(cell, nf, o) {
|
||||
@ -9744,7 +9775,7 @@ function parse_xlml_xml(d, opts) {
|
||||
break;
|
||||
case 'Worksheet': /* TODO: read range from FullRows/FullColumns */
|
||||
if(Rn[1]==='/'){
|
||||
if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;
|
||||
if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));
|
||||
sheetnames.push(sheetname);
|
||||
if(refguess.s.r <= refguess.e.r && refguess.s.c <= refguess.e.c) cursheet["!ref"] = encode_range(refguess);
|
||||
if(mergecells.length) cursheet["!merges"] = mergecells;
|
||||
@ -9754,13 +9785,13 @@ function parse_xlml_xml(d, opts) {
|
||||
r = c = 0;
|
||||
state.push([Rn[3], false]);
|
||||
tmp = xlml_parsexmltag(Rn[0]);
|
||||
sheetname = tmp.Name;
|
||||
sheetname = unescapexml(tmp.Name);
|
||||
cursheet = {};
|
||||
mergecells = [];
|
||||
}
|
||||
break;
|
||||
case 'Table':
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));}
|
||||
else if(Rn[0].slice(-2) == "/>") break;
|
||||
else {
|
||||
table = xlml_parsexmltag(Rn[0]);
|
||||
@ -9832,13 +9863,13 @@ function parse_xlml_xml(d, opts) {
|
||||
|
||||
case 'Styles':
|
||||
case 'Workbook':
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));}
|
||||
else state.push([Rn[3], false]);
|
||||
break;
|
||||
|
||||
case 'Comment':
|
||||
if(Rn[1]==='/'){
|
||||
if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;
|
||||
if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));
|
||||
xlml_clean_comment(comment);
|
||||
comments.push(comment);
|
||||
} else {
|
||||
@ -9871,7 +9902,7 @@ function parse_xlml_xml(d, opts) {
|
||||
case 'ExcelWorkbook':
|
||||
case 'WorkbookOptions':
|
||||
case 'WorksheetOptions':
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
|
||||
if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));}
|
||||
else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
|
||||
break;
|
||||
|
||||
@ -10315,7 +10346,7 @@ function safe_format_xf(p, opts, date1904) {
|
||||
}
|
||||
else p.w = SSF._general(p.v);
|
||||
}
|
||||
else p.w = SSF.format(fmtid,p.v, {date1904:date1904||false});
|
||||
else p.w = SSF.format(fmtid,p.v, {date1904:!!date1904});
|
||||
if(opts.cellNF) p.z = SSF._table[fmtid];
|
||||
} catch(e) { if(opts.WTF) throw e; }
|
||||
}
|
||||
@ -10336,7 +10367,7 @@ function parse_workbook(blob, options) {
|
||||
var sst = [];
|
||||
var cur_sheet = "";
|
||||
var Preamble = {};
|
||||
var lastcell, last_cell, cc, cmnt, rng, rngC, rngR;
|
||||
var lastcell, last_cell = "", cc, cmnt, rng, rngC, rngR;
|
||||
var shared_formulae = {};
|
||||
var array_formulae = []; /* TODO: something more clever */
|
||||
var temp_val;
|
||||
@ -10352,7 +10383,7 @@ function parse_workbook(blob, options) {
|
||||
var process_cell_style = function pcs(cell, line) {
|
||||
var xfd = line.XF.data;
|
||||
if(!xfd || !xfd.patternType) return;
|
||||
line.s = {};
|
||||
line.s = ({});
|
||||
line.s.patternType = xfd.patternType;
|
||||
var t;
|
||||
if((t = rgb2Hex(get_rgb(xfd.icvFore)))) { line.s.fgColor = {rgb:t}; }
|
||||
@ -10582,6 +10613,8 @@ function parse_workbook(blob, options) {
|
||||
case 'Array': {
|
||||
array_formulae.push(val);
|
||||
if(options.cellFormula && out[last_cell]) {
|
||||
if(!last_formula) break; /* technically unreachable */
|
||||
if(!last_cell || !out[last_cell]) break; /* technically unreachable */
|
||||
out[last_cell].f = stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
|
||||
out[last_cell].F = encode_range(val[0]);
|
||||
}
|
||||
@ -10591,6 +10624,7 @@ function parse_workbook(blob, options) {
|
||||
if(!options.cellFormula) break;
|
||||
if(last_cell) {
|
||||
/* TODO: capture range */
|
||||
if(!last_formula) break; /* technically unreachable */
|
||||
shared_formulae[encode_cell(last_formula.cell)]= val[0];
|
||||
(out[encode_cell(last_formula.cell)]||{}).f = stringify_formula(val[0], range, lastcell, supbooks, opts);
|
||||
}
|
||||
@ -10922,7 +10956,7 @@ if(!Workbook) Workbook = cfb.find('/Book');
|
||||
var CompObjP, SummaryP, WorkbookP;
|
||||
|
||||
if(CompObj) CompObjP = parse_compobj(CompObj);
|
||||
if(options.bookProps && !options.bookSheets) WorkbookP = {};
|
||||
if(options.bookProps && !options.bookSheets) WorkbookP = ({});
|
||||
else {
|
||||
if(Workbook) WorkbookP = parse_workbook(Workbook.content, options, !!Workbook.find);
|
||||
else throw new Error("Cannot find Workbook stream");
|
||||
@ -10935,7 +10969,7 @@ for(var y in cfb.Summary) props[y] = cfb.Summary[y];
|
||||
for(y in cfb.DocSummary) props[y] = cfb.DocSummary[y];
|
||||
WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
|
||||
if(options.bookFiles) WorkbookP.cfb = cfb;
|
||||
WorkbookP.CompObjP = CompObjP;
|
||||
/*WorkbookP.CompObjP = CompObjP; // TODO: storage? */
|
||||
return WorkbookP;
|
||||
}
|
||||
|
||||
@ -12331,7 +12365,7 @@ function parse_html(str, opts) {
|
||||
if(range.e.c < C) range.e.c = C;
|
||||
var coord = encode_cell({r:R, c:C});
|
||||
/* TODO: value parsing */
|
||||
if(m == +m) ws[coord] = {t:'n', v:+m};
|
||||
if(Number(m) == Number(m)) ws[coord] = {t:'n', v:+m};
|
||||
else ws[coord] = {t:'s', v:m};
|
||||
}
|
||||
++R; C = 0;
|
||||
@ -12788,7 +12822,7 @@ function parse_ods(zip, opts) {
|
||||
opts = 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');
|
||||
var content = getzipstr(zip, 'content.xml');
|
||||
if(!content) throw new Error("Missing content.xml in " + (ods ? "ODS" : "UOF")+ " file");
|
||||
return parse_content_xml(ods ? content : utf8read(content), opts);
|
||||
}
|
||||
@ -12920,7 +12954,7 @@ function parse_zip(zip, opts) {
|
||||
if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style, opts);
|
||||
|
||||
themes = {};
|
||||
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipdata(zip, dir.themes[0].replace(/^\//,''), true),dir.themes[0], opts);
|
||||
if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
|
||||
}
|
||||
|
||||
var wb = parse_wb(getzipdata(zip, dir.workbooks[0].replace(/^\//,'')), dir.workbooks[0], opts);
|
||||
@ -12944,12 +12978,12 @@ function parse_zip(zip, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
var out = {};
|
||||
var out = ({});
|
||||
if(opts.bookSheets || opts.bookProps) {
|
||||
if(props.Worksheets && props.SheetNames.length > 0) sheets=props.SheetNames;
|
||||
else if(wb.Sheets) sheets = wb.Sheets.map(function pluck(x){ return x.name; });
|
||||
if(opts.bookProps) { out.Props = props; out.Custprops = custprops; }
|
||||
if(typeof sheets !== 'undefined') out.SheetNames = sheets;
|
||||
if(opts.bookSheets && typeof sheets !== 'undefined') out.SheetNames = sheets;
|
||||
if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out;
|
||||
}
|
||||
sheets = {};
|
||||
@ -13027,7 +13061,9 @@ function write_zip(wb, opts) {
|
||||
wb.SSF = SSF.get_table();
|
||||
}
|
||||
if(wb && wb.SSF) {
|
||||
// $FlowIgnore
|
||||
make_ssf(SSF); SSF.load_table(wb.SSF);
|
||||
// $FlowIgnore
|
||||
opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
|
||||
}
|
||||
opts.rels = {}; opts.wbrels = {};
|
||||
@ -13050,7 +13086,7 @@ var zip = new jszip();
|
||||
ct.coreprops.push(f);
|
||||
add_rels(opts.rels, 2, f, RELS.CORE_PROPS);
|
||||
|
||||
f = "docProps/app.xml";
|
||||
f = "docProps/app.xml";
|
||||
wb.Props.SheetNames = wb.SheetNames;
|
||||
wb.Props.Worksheets = wb.SheetNames.length;
|
||||
zip.file(f, write_ext_props(wb.Props, opts));
|
||||
@ -13169,9 +13205,9 @@ function write_string_type(out, opts) {
|
||||
case "buffer": {
|
||||
if(has_buf) return new Buffer(out, 'utf8');
|
||||
else return out.split("").map(function(c) { return c.charCodeAt(0); });
|
||||
} break;
|
||||
default: throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
}
|
||||
throw new Error("Unrecognized type " + opts.type);
|
||||
}
|
||||
|
||||
/* TODO: test consistency */
|
||||
|
22
dist/xlsx.min.js
vendored
22
dist/xlsx.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.min.map
vendored
2
dist/xlsx.min.map
vendored
File diff suppressed because one or more lines are too long
104
misc/cfb.d.ts
vendored
104
misc/cfb.d.ts
vendored
@ -1,104 +0,0 @@
|
||||
declare enum CFBEntryType { unknown, storage, stream, lockbytes, property, root }
|
||||
declare enum CFBStorageType { fat, minifat }
|
||||
|
||||
/* CFB Entry Object demanded by write functions */
|
||||
interface CFBEntryMin {
|
||||
|
||||
/* Raw Content (Buffer when available, Array of bytes otherwise) */
|
||||
content:any;
|
||||
}
|
||||
|
||||
/* CFB Entry Object returned by parse functions */
|
||||
interface CFBEntry extends CFBEntryMin {
|
||||
|
||||
/* Case-sensitive internal name */
|
||||
name:string;
|
||||
|
||||
/* CFB type (salient types: stream, storage) -- see CFBEntryType */
|
||||
type:string;
|
||||
|
||||
/* Creation Time */
|
||||
ct:Date;
|
||||
/* Modification Time */
|
||||
mt:Date;
|
||||
|
||||
|
||||
/* Raw creation time -- see [MS-DTYP] 2.3.3 FILETIME */
|
||||
mtime:string;
|
||||
/* Raw modification time -- see [MS-DTYP] 2.3.3 FILETIME */
|
||||
ctime:string;
|
||||
|
||||
/* RBT color: 0 = red, 1 = black */
|
||||
color:number;
|
||||
|
||||
/* Class ID represented as hex string */
|
||||
clsid:string;
|
||||
|
||||
/* User-Defined State Bits */
|
||||
state:number;
|
||||
|
||||
/* Starting Sector */
|
||||
start:number;
|
||||
|
||||
/* Data Size */
|
||||
size:number;
|
||||
|
||||
/* Storage location -- see CFBStorageType */
|
||||
storage:string;
|
||||
}
|
||||
|
||||
|
||||
/* cfb.FullPathDir as demanded by write functions */
|
||||
interface CFBDirectoryMin {
|
||||
|
||||
/* keys are unix-style paths */
|
||||
[key:string]: CFBEntryMin;
|
||||
}
|
||||
|
||||
/* cfb.FullPathDir Directory object */
|
||||
interface CFBDirectory extends CFBDirectoryMin {
|
||||
|
||||
/* cfb.FullPathDir keys are paths; cfb.Directory keys are file names */
|
||||
[key:string]: CFBEntry;
|
||||
}
|
||||
|
||||
|
||||
/* cfb object demanded by write functions */
|
||||
interface CFBContainerMin {
|
||||
|
||||
/* Path -> CFB object mapping */
|
||||
FullPathDir:CFBDirectoryMin;
|
||||
}
|
||||
|
||||
/* cfb object returned by read and parse functions */
|
||||
interface CFBContainer extends CFBContainerMin {
|
||||
|
||||
/* search by path or file name */
|
||||
find(string):CFBEntry;
|
||||
|
||||
/* list of streams and storages */
|
||||
FullPaths:string[];
|
||||
|
||||
/* Path -> CFB object mapping */
|
||||
FullPathDir:CFBDirectory;
|
||||
|
||||
/* Array of entries in the same order as FullPaths */
|
||||
FileIndex:CFBEntry[];
|
||||
|
||||
/* Raw Content, in chunks (Buffer when available, Array of bytes otherwise) */
|
||||
raw:any[];
|
||||
}
|
||||
|
||||
|
||||
interface CFB {
|
||||
read(f:any, options:any):CFBContainer;
|
||||
parse(f:any):CFBContainer;
|
||||
utils: {
|
||||
ReadShift(size:any,t?:any):any;
|
||||
WarnField(hexstr:string,fld?:string);
|
||||
CheckField(hexstr:string,fld?:string);
|
||||
prep_blob(blob:any, pos?:number):any;
|
||||
bconcat(bufs:any[]):any;
|
||||
};
|
||||
main;
|
||||
}
|
8
misc/node.d.ts
vendored
8
misc/node.d.ts
vendored
@ -1,8 +0,0 @@
|
||||
declare var require: {
|
||||
(id: string): any;
|
||||
}
|
||||
|
||||
declare var process: {
|
||||
argv: string[];
|
||||
exit(status: number): void;
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
if [ -e "$1" ]; then
|
||||
sed -i .sheetjs '/sourceMappingURL/d' "$1"
|
||||
sed -i.sheetjs '/sourceMappingURL/d' "$1"
|
||||
fi
|
||||
else
|
||||
cat - | sed '/sourceMappingURL/d'
|
||||
|
65
misc/xl.d.ts
vendored
65
misc/xl.d.ts
vendored
@ -1,65 +0,0 @@
|
||||
///<reference path='cfb.d.ts'/>
|
||||
|
||||
interface Cell {
|
||||
v;
|
||||
w?: string;
|
||||
t?: string;
|
||||
f?: string;
|
||||
r?: string;
|
||||
h?: string;
|
||||
c?: any;
|
||||
z?: string;
|
||||
ixfe?: number;
|
||||
}
|
||||
|
||||
interface CellAddress {
|
||||
c: number;
|
||||
r: number;
|
||||
}
|
||||
|
||||
interface CellRange {
|
||||
s: CellAddress;
|
||||
e: CellAddress;
|
||||
}
|
||||
|
||||
interface WorksheetBase {
|
||||
'!range':CellRange;
|
||||
'!ref':string;
|
||||
}
|
||||
|
||||
interface Worksheet extends WorksheetBase {
|
||||
[key: string]: Cell;
|
||||
}
|
||||
|
||||
interface Worksheets {
|
||||
[key: string]: Worksheet;
|
||||
}
|
||||
|
||||
interface Workbook {
|
||||
SheetNames: string[];
|
||||
Sheets: Worksheets;
|
||||
}
|
||||
|
||||
interface XLSX {
|
||||
parse_xlscfb(cfb:CFBContainer): Workbook;
|
||||
read;
|
||||
readFile(filename: string): Workbook;
|
||||
utils: {
|
||||
encode_col(col: number): string;
|
||||
encode_row(row: number): string;
|
||||
encode_cell(cell: CellAddress): string;
|
||||
encode_range;
|
||||
decode_col(col: string): number;
|
||||
decode_row(row: string): number;
|
||||
split_cell(cell: string): string[];
|
||||
decode_cell(cell: string): CellAddress;
|
||||
decode_range(cell: string): CellRange;
|
||||
sheet_to_csv(worksheet: Worksheet): string;
|
||||
get_formulae(worksheet: Worksheet): string[];
|
||||
make_csv(worksheet: Worksheet): string;
|
||||
sheet_to_row_object_array(worksheet: Worksheet): Object[];
|
||||
};
|
||||
verbose: Number;
|
||||
CFB:CFB;
|
||||
main;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
///<reference path='node.d.ts'/>
|
||||
///<reference path='xl.d.ts'/>
|
||||
|
||||
/* vim: set ts=2: */
|
||||
var XLSX = <XLSX>require('xlsx');
|
||||
var fs = require('fs'), program = require('commander');
|
||||
program
|
||||
.version('0.3.1')
|
||||
.usage('[options] <file> [sheetname]')
|
||||
.option('-f, --file <file>', 'use specified workbook')
|
||||
.option('-s, --sheet <sheet>', 'print specified sheet (default first sheet)')
|
||||
.option('-l, --list-sheets', 'list sheet names and exit')
|
||||
.option('-F, --formulae', 'print formulae')
|
||||
.option('--dev', 'development mode')
|
||||
.option('--read', 'read but do not print out contents')
|
||||
.option('-q, --quiet', 'quiet mode')
|
||||
.parse(process.argv);
|
||||
|
||||
var filename:string, sheetname:string = '';
|
||||
if(program.args[0]) {
|
||||
filename = program.args[0];
|
||||
if(program.args[1]) sheetname = program.args[1];
|
||||
}
|
||||
if(program.sheet) sheetname = program.sheet;
|
||||
if(program.file) filename = program.file;
|
||||
|
||||
if(!filename) {
|
||||
console.error("xlsx2csv: must specify a filename");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if(!fs.existsSync(filename)) {
|
||||
console.error("xlsx2csv: " + filename + ": No such file or directory");
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
if(program.dev) XLSX.verbose = 2;
|
||||
|
||||
var wb:Workbook;
|
||||
if(program.dev) wb = XLSX.readFile(filename);
|
||||
else try {
|
||||
wb = XLSX.readFile(filename);
|
||||
} catch(e) {
|
||||
var msg:string = (program.quiet) ? "" : "xlsx2csv: error parsing ";
|
||||
msg += filename + ": " + e;
|
||||
console.error(msg);
|
||||
process.exit(3);
|
||||
}
|
||||
if(program.read) process.exit(0);
|
||||
|
||||
if(program.listSheets) {
|
||||
console.log(wb.SheetNames.join("\n"));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
var target_sheet:string = sheetname || '';
|
||||
if(target_sheet === '') target_sheet = wb.SheetNames[0];
|
||||
|
||||
var ws:Worksheet;
|
||||
try {
|
||||
ws = wb.Sheets[target_sheet];
|
||||
if(!ws) throw "Sheet " + target_sheet + " cannot be found";
|
||||
} catch(e) {
|
||||
console.error("xlsx2csv: error parsing "+filename+" "+target_sheet+": " + e);
|
||||
process.exit(4);
|
||||
}
|
||||
|
||||
if(!program.quiet) console.error(target_sheet);
|
||||
if(program.formulae) console.log(XLSX.utils.get_formulae(ws).join("\n"));
|
||||
else console.log(XLSX.utils.make_csv(ws));
|
||||
console.log(ws["C2"]);
|
10
package.json
10
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xlsx",
|
||||
"version": "0.9.1",
|
||||
"version": "0.9.2",
|
||||
"author": "sheetjs",
|
||||
"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" ],
|
||||
@ -14,13 +14,13 @@
|
||||
"fs": false
|
||||
},
|
||||
"dependencies": {
|
||||
"exit-on-epipe":"",
|
||||
"exit-on-epipe":"~1.0.0",
|
||||
"ssf":"~0.8.1",
|
||||
"codepage":"~1.7.0",
|
||||
"cfb":"~0.11.0",
|
||||
"crc-32":"",
|
||||
"adler-32":"",
|
||||
"commander":""
|
||||
"crc-32":"~1.0.0",
|
||||
"adler-32":"~1.0.0",
|
||||
"commander":"~2.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha":"",
|
||||
|
30
xlsx.flow.js
30
xlsx.flow.js
@ -5,7 +5,7 @@
|
||||
/*exported XLSX */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.9.1';
|
||||
XLSX.version = '0.9.2';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
/*:: declare var cptable:any; */
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
@ -2616,7 +2616,6 @@ function parse_ct(data/*:?string*/, opts) {
|
||||
case '<Default': ctext[y.Extension] = y.ContentType; break;
|
||||
case '<Override':
|
||||
if(ct[ct2type[y.ContentType]] !== undefined) ct[ct2type[y.ContentType]].push(y.PartName);
|
||||
else if(opts.WTF) console.error(y);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -2943,7 +2942,7 @@ function write_ext_props(cp, opts)/*:string*/ {
|
||||
|
||||
/* TODO: HeadingPairs, TitlesOfParts */
|
||||
o[o.length] = (W('HeadingPairs', W('vt:vector', W('vt:variant', '<vt:lpstr>Worksheets</vt:lpstr>')+W('vt:variant', W('vt:i4', String(cp.Worksheets))), {size:2, baseType:"variant"})));
|
||||
o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + s + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
|
||||
o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + escapexml(s) + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
|
||||
if(o.length>2){ o[o.length] = ('</Properties>'); o[1]=o[1].replace("/>",">"); }
|
||||
return o.join("");
|
||||
}
|
||||
@ -3505,7 +3504,6 @@ function parse_XTI(blob, length) {
|
||||
function parse_RkRec(blob, length) {
|
||||
var ixfe = blob.read_shift(2);
|
||||
var RK = parse_RkNumber(blob);
|
||||
//console.log("::", ixfe, RK,";;");
|
||||
return [ixfe, RK];
|
||||
}
|
||||
|
||||
@ -4875,7 +4873,7 @@ function parse_FilePass(blob, length/*:number*/, opts) {
|
||||
|
||||
function hex2RGB(h) {
|
||||
var o = h.substr(h[0]==="#"?1:0,6);
|
||||
return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)];
|
||||
return [parseInt(o.substr(0,2),16),parseInt(o.substr(2,2),16),parseInt(o.substr(4,2),16)];
|
||||
}
|
||||
function rgb2Hex(rgb) {
|
||||
for(var i=0,o=1; i!=3; ++i) o = o*256 + (rgb[i]>255?255:rgb[i]<0?0:rgb[i]);
|
||||
@ -5617,10 +5615,15 @@ function update_xfext(xf, xfext) {
|
||||
switch(xfe[0]) { /* 2.5.108 extPropData */
|
||||
case 0x04: break; /* foreground color */
|
||||
case 0x05: break; /* background color */
|
||||
case 0x07: case 0x08: case 0x09: case 0x0a: break;
|
||||
case 0x06: break; /* gradient fill */
|
||||
case 0x07: break; /* top cell border color */
|
||||
case 0x08: break; /* bottom cell border color */
|
||||
case 0x09: break; /* left cell border color */
|
||||
case 0x0a: break; /* right cell border color */
|
||||
case 0x0b: break; /* diagonal cell border color */
|
||||
case 0x0d: break; /* text color */
|
||||
case 0x0e: break; /* font scheme */
|
||||
default: throw "bafuq" + xfe[0].toString(16);
|
||||
case 0x0f: break; /* indentation level */
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -5813,9 +5816,10 @@ var rc_to_a1 = (function(){
|
||||
};
|
||||
})();
|
||||
|
||||
/* TODO actually parse the formula */
|
||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
|
||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
|
||||
function shift_formula_str(f/*:string*/, delta/*:Cell*/)/*:string*/ {
|
||||
return f.replace(/(^|[^A-Z0-9])([$]?)([A-Z]+)([$]?)(\d+)/g, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
return f.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
return $1+($2=="$" ? $2+$3 : encode_col(decode_col($3)+delta.c))+($4=="$" ? $4+$5 : encode_row(decode_row($5) + delta.r));
|
||||
});
|
||||
}
|
||||
@ -8406,7 +8410,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
case 'inlineStr':
|
||||
cref = d.match(isregex);
|
||||
p.t = 's';
|
||||
if(cref != null) { if((sstr = parse_si(cref[1]))) p.v = sstr.t; } else p.v = "";
|
||||
if(cref != null && (sstr = parse_si(cref[1]))) p.v = sstr.t; else p.v = "";
|
||||
break; // inline string
|
||||
case 'b': p.v = parsexmlbool(p.v); break;
|
||||
case 'd':
|
||||
@ -9220,7 +9224,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
||||
/* 18.2.19 sheet CT_Sheet + */
|
||||
case '<sheet': delete y[0]; y.name = utf8read(y.name); wb.Sheets.push(y); break;
|
||||
case '<sheet': delete y[0]; y.name = unescapexml(utf8read(y.name)); wb.Sheets.push(y); break;
|
||||
case '</sheet>': break;
|
||||
|
||||
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
||||
@ -9319,7 +9323,7 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
|
||||
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb)}));
|
||||
o[o.length] = "<sheets>";
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i)
|
||||
o[o.length] = (writextag('sheet',null,{name:wb.SheetNames[i].substr(0,31), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
||||
o[o.length] = (writextag('sheet',null,{name:escapexml(wb.SheetNames[i].substr(0,31)), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
||||
o[o.length] = "</sheets>";
|
||||
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
||||
return o.join("");
|
||||
@ -9834,7 +9838,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ {
|
||||
r = c = 0;
|
||||
state.push([Rn[3], false]);
|
||||
tmp = xlml_parsexmltag(Rn[0]);
|
||||
sheetname = tmp.Name;
|
||||
sheetname = unescapexml(tmp.Name);
|
||||
cursheet = {};
|
||||
mergecells = [];
|
||||
}
|
||||
|
30
xlsx.js
30
xlsx.js
@ -5,7 +5,7 @@
|
||||
/*exported XLSX */
|
||||
var XLSX = {};
|
||||
(function make_xlsx(XLSX){
|
||||
XLSX.version = '0.9.1';
|
||||
XLSX.version = '0.9.2';
|
||||
var current_codepage = 1200, current_cptable;
|
||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||
if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js');
|
||||
@ -2566,7 +2566,6 @@ function parse_ct(data, opts) {
|
||||
case '<Default': ctext[y.Extension] = y.ContentType; break;
|
||||
case '<Override':
|
||||
if(ct[ct2type[y.ContentType]] !== undefined) ct[ct2type[y.ContentType]].push(y.PartName);
|
||||
else if(opts.WTF) console.error(y);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -2893,7 +2892,7 @@ function write_ext_props(cp, opts) {
|
||||
|
||||
/* TODO: HeadingPairs, TitlesOfParts */
|
||||
o[o.length] = (W('HeadingPairs', W('vt:vector', W('vt:variant', '<vt:lpstr>Worksheets</vt:lpstr>')+W('vt:variant', W('vt:i4', String(cp.Worksheets))), {size:2, baseType:"variant"})));
|
||||
o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + s + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
|
||||
o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + escapexml(s) + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
|
||||
if(o.length>2){ o[o.length] = ('</Properties>'); o[1]=o[1].replace("/>",">"); }
|
||||
return o.join("");
|
||||
}
|
||||
@ -3455,7 +3454,6 @@ function parse_XTI(blob, length) {
|
||||
function parse_RkRec(blob, length) {
|
||||
var ixfe = blob.read_shift(2);
|
||||
var RK = parse_RkNumber(blob);
|
||||
//console.log("::", ixfe, RK,";;");
|
||||
return [ixfe, RK];
|
||||
}
|
||||
|
||||
@ -4825,7 +4823,7 @@ function parse_FilePass(blob, length, opts) {
|
||||
|
||||
function hex2RGB(h) {
|
||||
var o = h.substr(h[0]==="#"?1:0,6);
|
||||
return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)];
|
||||
return [parseInt(o.substr(0,2),16),parseInt(o.substr(2,2),16),parseInt(o.substr(4,2),16)];
|
||||
}
|
||||
function rgb2Hex(rgb) {
|
||||
for(var i=0,o=1; i!=3; ++i) o = o*256 + (rgb[i]>255?255:rgb[i]<0?0:rgb[i]);
|
||||
@ -5567,10 +5565,15 @@ function update_xfext(xf, xfext) {
|
||||
switch(xfe[0]) { /* 2.5.108 extPropData */
|
||||
case 0x04: break; /* foreground color */
|
||||
case 0x05: break; /* background color */
|
||||
case 0x07: case 0x08: case 0x09: case 0x0a: break;
|
||||
case 0x06: break; /* gradient fill */
|
||||
case 0x07: break; /* top cell border color */
|
||||
case 0x08: break; /* bottom cell border color */
|
||||
case 0x09: break; /* left cell border color */
|
||||
case 0x0a: break; /* right cell border color */
|
||||
case 0x0b: break; /* diagonal cell border color */
|
||||
case 0x0d: break; /* text color */
|
||||
case 0x0e: break; /* font scheme */
|
||||
default: throw "bafuq" + xfe[0].toString(16);
|
||||
case 0x0f: break; /* indentation level */
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -5763,9 +5766,10 @@ var rc_to_a1 = (function(){
|
||||
};
|
||||
})();
|
||||
|
||||
/* TODO actually parse the formula */
|
||||
/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
|
||||
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)([1-9]\d{0,5}|10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6])(?![_.\(A-Za-z0-9])/g;
|
||||
function shift_formula_str(f, delta) {
|
||||
return f.replace(/(^|[^A-Z0-9])([$]?)([A-Z]+)([$]?)(\d+)/g, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
return f.replace(crefregex, function($0, $1, $2, $3, $4, $5, off, str) {
|
||||
return $1+($2=="$" ? $2+$3 : encode_col(decode_col($3)+delta.c))+($4=="$" ? $4+$5 : encode_row(decode_row($5) + delta.r));
|
||||
});
|
||||
}
|
||||
@ -8355,7 +8359,7 @@ return function parse_ws_xml_data(sdata, s, opts, guess) {
|
||||
case 'inlineStr':
|
||||
cref = d.match(isregex);
|
||||
p.t = 's';
|
||||
if(cref != null) { if((sstr = parse_si(cref[1]))) p.v = sstr.t; } else p.v = "";
|
||||
if(cref != null && (sstr = parse_si(cref[1]))) p.v = sstr.t; else p.v = "";
|
||||
break; // inline string
|
||||
case 'b': p.v = parsexmlbool(p.v); break;
|
||||
case 'd':
|
||||
@ -9169,7 +9173,7 @@ function parse_wb_xml(data, opts) {
|
||||
/* 18.2.20 sheets CT_Sheets 1 */
|
||||
case '<sheets>': case '</sheets>': break; // aggregate sheet
|
||||
/* 18.2.19 sheet CT_Sheet + */
|
||||
case '<sheet': delete y[0]; y.name = utf8read(y.name); wb.Sheets.push(y); break;
|
||||
case '<sheet': delete y[0]; y.name = unescapexml(utf8read(y.name)); wb.Sheets.push(y); break;
|
||||
case '</sheet>': break;
|
||||
|
||||
/* 18.2.15 functionGroups CT_FunctionGroups ? */
|
||||
@ -9268,7 +9272,7 @@ function write_wb_xml(wb, opts) {
|
||||
o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb)}));
|
||||
o[o.length] = "<sheets>";
|
||||
for(var i = 0; i != wb.SheetNames.length; ++i)
|
||||
o[o.length] = (writextag('sheet',null,{name:wb.SheetNames[i].substr(0,31), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
||||
o[o.length] = (writextag('sheet',null,{name:escapexml(wb.SheetNames[i].substr(0,31)), sheetId:""+(i+1), "r:id":"rId"+(i+1)}));
|
||||
o[o.length] = "</sheets>";
|
||||
if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
|
||||
return o.join("");
|
||||
@ -9781,7 +9785,7 @@ function parse_xlml_xml(d, opts) {
|
||||
r = c = 0;
|
||||
state.push([Rn[3], false]);
|
||||
tmp = xlml_parsexmltag(Rn[0]);
|
||||
sheetname = tmp.Name;
|
||||
sheetname = unescapexml(tmp.Name);
|
||||
cursheet = {};
|
||||
mergecells = [];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user