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) | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| 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