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