forked from sheetjs/sheetjs
		
	sheet_to_html
- added to TS definition and tests - clarified behavior of plaintext files (fixes #641 h/t @dskrvk) - removed old test files
This commit is contained in:
		
							parent
							
								
									409581b317
								
							
						
					
					
						commit
						3fde651a8c
					
				| @ -1,5 +1,6 @@ | ||||
| test_files/ | ||||
| tests/files/ | ||||
| types/ | ||||
| demos/ | ||||
| index.html | ||||
| misc/ | ||||
|  | ||||
							
								
								
									
										173
									
								
								README.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										173
									
								
								README.md
									
									
									
									
									
								
							| @ -103,6 +103,7 @@ enhancements, additional features by request, and dedicated support. | ||||
|   * [Formulae Output](#formulae-output) | ||||
|   * [Delimiter-Separated Output](#delimiter-separated-output) | ||||
|     + [UTF-16 Unicode Text](#utf-16-unicode-text) | ||||
|   * [HTML Output](#html-output) | ||||
|   * [JSON](#json) | ||||
| - [File Formats](#file-formats) | ||||
|   * [Excel 2007+ XML (XLSX/XLSM)](#excel-2007-xml-xlsxxlsm) | ||||
| @ -128,9 +129,9 @@ enhancements, additional features by request, and dedicated support. | ||||
|   * [Tested Environments](#tested-environments) | ||||
|   * [Test Files](#test-files) | ||||
| - [Contributing](#contributing) | ||||
|   * [Tests](#tests) | ||||
|   * [OSX/Linux](#osxlinux) | ||||
|   * [Windows](#windows) | ||||
|   * [Tests](#tests) | ||||
| - [License](#license) | ||||
| - [References](#references) | ||||
| 
 | ||||
| @ -457,6 +458,7 @@ files and output the contents in various formats.  The source is available at | ||||
| Some helper functions in `XLSX.utils` generate different views of the sheets: | ||||
| 
 | ||||
| - `XLSX.utils.sheet_to_csv` generates CSV | ||||
| - `XLSX.utils.sheet_to_html` generates HTML | ||||
| - `XLSX.utils.sheet_to_json` generates an array of objects | ||||
| - `XLSX.utils.sheet_to_formulae` generates a list of formulae | ||||
| 
 | ||||
| @ -485,7 +487,7 @@ Note: browser generates binary blob and forces a "download" to client.  This | ||||
| example uses [FileSaver.js](https://github.com/eligrey/FileSaver.js/): | ||||
| 
 | ||||
| ```js | ||||
| /* bookType can be any supported output type */  | ||||
| /* bookType can be any supported output type */ | ||||
| var wopts = { bookType:'xlsx', bookSST:false, type:'binary' }; | ||||
| 
 | ||||
| var wbout = XLSX.write(workbook,wopts); | ||||
| @ -514,7 +516,18 @@ take the same arguments as the normal write functions but return a readable | ||||
| stream.  They are only exposed in node. | ||||
| 
 | ||||
| - `XLSX.stream.to_csv` is the streaming version of `XLSX.utils.sheet_to_csv`. | ||||
| - `XLSX.stream.to_html` is the streaming version of the HTML output type. | ||||
| - `XLSX.stream.to_html` is the streaming version of `XLSX.utils.sheet_to_html`. | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>nodejs convert to CSV and write file</b> (click to show)</summary> | ||||
| 
 | ||||
| ```js | ||||
| var output_file_name = "out.csv"; | ||||
| var stream = XLSX.stream.to_csv(worksheet); | ||||
| stream.pipe(fs.createWriteStream(output_file_name)); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response. | ||||
| 
 | ||||
| @ -555,11 +568,13 @@ Utilities are available in the `XLSX.utils` object: | ||||
| 
 | ||||
| - `aoa_to_sheet` converts an array of arrays of JS data to a worksheet. | ||||
| - `json_to_sheet` converts an array of JS objects to a worksheet. | ||||
| - `table_to_sheet` converts a DOM TABLE element to a worksheet. | ||||
| 
 | ||||
| **Exporting:** | ||||
| 
 | ||||
| - `sheet_to_json` converts a worksheet object to an array of JSON objects. | ||||
| - `sheet_to_csv` generates delimiter-separated-values output. | ||||
| - `sheet_to_html` generates HTML output. | ||||
| - `sheet_to_formulae` generates a list of the formulae (with value fallbacks). | ||||
| 
 | ||||
| These utilities are described in [Utility Functions](#utility-functions) below. | ||||
| @ -572,6 +587,8 @@ These utilities are described in [Utility Functions](#utility-functions) below. | ||||
| - `{en,de}code_cell` converts cell addresses | ||||
| - `{en,de}code_range` converts cell ranges | ||||
| 
 | ||||
| Utilities are described in the [Utility Functions](#utility-functions) section. | ||||
| 
 | ||||
| ## Common Spreadsheet Format | ||||
| 
 | ||||
| js-xlsx conforms to the Common Spreadsheet Format (CSF): | ||||
| @ -979,23 +996,39 @@ objects which have the following properties: | ||||
| ```typescript | ||||
| type ColInfo = { | ||||
| 	/* visibility */ | ||||
| 	hidden:?boolean; // if true, the column is hidden | ||||
| 	hidden?: boolean; // if true, the column is hidden | ||||
| 
 | ||||
| 	/* column width is specified in one of the following ways: */ | ||||
| 	wpx?:number;     // width in screen pixels | ||||
| 	width:number;    // width in Excel's "Max Digit Width", width*256 is integral | ||||
| 	wch?:number;     // width in characters | ||||
| 	wpx?:    number;  // width in screen pixels | ||||
| 	width?:  number;  // width in Excel's "Max Digit Width", width*256 is integral | ||||
| 	wch?:    number;  // width in characters | ||||
| 
 | ||||
| 	/* other fields for preserving features from files */ | ||||
| 	MDW?:number;     // Excel's "Max Digit Width" unit, always integral | ||||
| 	MDW?:    number;  // Excel's "Max Digit Width" unit, always integral | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| Excel internally stores column widths in a nebulous "Max Digit Width" form.  The | ||||
| <details> | ||||
| 	<summary><b>Why are there three width types?</b> (click to show)</summary> | ||||
| 
 | ||||
| There are three different width types corresponding to the three different ways | ||||
| spreadsheets store column widths: | ||||
| 
 | ||||
| SYLK and other plaintext formats use raw character count.  Contemporaneous tools | ||||
| like Visicalc and Multiplan were character based.  Since the characters had the | ||||
| same width, it sufficed to store a count.  This tradition was continued into the | ||||
| BIFF formats. | ||||
| 
 | ||||
| SpreadsheetML (2003) tried to align with HTML by standardizing on screen pixel | ||||
| count throughout the file.  Column widths, row heights, and other measures use | ||||
| pixels.  When the pixel and character counts do not align, Excel rounds values. | ||||
| 
 | ||||
| XLSX internally stores column widths in a nebulous "Max Digit Width" form.  The | ||||
| Max Digit Width is the width of the largest digit when rendered (generally the | ||||
| "0" character is the widest).  The internal width must be an integer multiple of | ||||
| the the width divided by 256.  ECMA-376 describes a formula for converting | ||||
| between pixels and the internal width. | ||||
| between pixels and the internal width.  This represents a hybrid approach. | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Implementation details</b> (click to show)</summary> | ||||
| @ -1022,11 +1055,11 @@ objects which have the following properties: | ||||
| ```typescript | ||||
| type RowInfo = { | ||||
| 	/* visibility */ | ||||
| 	hidden:?boolean; // if true, the row is hidden | ||||
| 	hidden?: boolean; // if true, the row is hidden | ||||
| 
 | ||||
| 	/* row height is specified in one of the following ways: */ | ||||
| 	hpx?:number;     // height in screen pixels | ||||
| 	hpt?:number;     // height in points | ||||
| 	hpx?:    number;  // height in screen pixels | ||||
| 	hpt?:    number;  // height in points | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| @ -1060,7 +1093,6 @@ at index 164.  The following example creates a custom format from scratch: | ||||
| 	<summary><b>New worksheet with custom format</b> (click to show)</summary> | ||||
| 
 | ||||
| ```js | ||||
| var tbl = {}; | ||||
| var wb = { | ||||
| 	SheetNames: ["Sheet1"], | ||||
| 	Sheets: { | ||||
| @ -1285,6 +1317,24 @@ Plaintext format guessing follows the priority order: | ||||
| | PRN    | (default)                                                           | | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Why are random text files valid?</b> (click to show)</summary> | ||||
| 
 | ||||
| Excel is extremely aggressive in reading files.  Adding an XLS extension to any | ||||
| display text file  (where the only characters are ANSI display chars) tricks | ||||
| Excel into thinking that the file is potentially a CSV or TSV file, even if it | ||||
| is only one column!  This library attempts to replicate that behavior. | ||||
| 
 | ||||
| The best approach is to validate the desired worksheet and ensure it has the | ||||
| expected number of rows or columns.  Extracting the range is extremely simple: | ||||
| 
 | ||||
| ```js | ||||
| var range = XLSX.utils.decode_range(worksheet['!ref']); | ||||
| var ncols = range.e.c - range.r.c + 1, nrows = range.e.r - range.s.r + 1; | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Writing Options | ||||
| 
 | ||||
| The exported `write` and `writeFile` functions accept an options argument: | ||||
| @ -1506,6 +1556,29 @@ The `txt` output type uses the tab character as the field separator.  If the | ||||
| codepage library is available (included in the full distribution but not core), | ||||
| the output will be encoded in codepage `1200` and the BOM will be prepended. | ||||
| 
 | ||||
| ### HTML Output | ||||
| 
 | ||||
| As an alternative to the `writeFile` HTML type, `XLSX.utils.sheet_to_html` also | ||||
| produces HTML output.  The function takes an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| | editable    |  false   | If true, set `contenteditable="true"` for every TD  | | ||||
| | header      |          | Override header (default `html body table`)         | | ||||
| | footer      |          | Override footer (default `/table /body /html`)      | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| For the example sheet: | ||||
| 
 | ||||
| ```js | ||||
| > console.log(XLSX.utils.sheet_to_html(ws)); | ||||
| // ... | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### JSON | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_json` generates different types of JS objects. The function | ||||
| @ -1926,37 +1999,50 @@ Tests utilize the mocha testing framework.  Travis-CI and Sauce Labs links: | ||||
| Test files are housed in [another repo](https://github.com/SheetJS/test_files). | ||||
| 
 | ||||
| Running `make init` will refresh the `test_files` submodule and get the files. | ||||
| Note that this requires `svn`, `git`, `hg` and other commands that may not be | ||||
| available.  If `make init` fails, please download the latest version of the test | ||||
| files snapshot from [the repo](https://github.com/SheetJS/test_files/releases) | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Latest Snapshot</b> (click to show)</summary> | ||||
| 
 | ||||
| Latest test files snapshot: | ||||
| <http://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip> | ||||
| 
 | ||||
| (download and unzip to the `test_files` subdirectory) | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| ## Contributing | ||||
| 
 | ||||
| Due to the precarious nature of the Open Specifications Promise, it is very | ||||
| important to ensure code is cleanroom.  Consult CONTRIBUTING.md | ||||
| 
 | ||||
| ### Tests | ||||
| 
 | ||||
| <details> | ||||
| 	<summary>(click to show)</summary> | ||||
| 	<summary><b>File organization</b> (click to show)</summary> | ||||
| 
 | ||||
| The `test_misc` target (`make test_misc` on Linux/OSX / `make misc` on Windows) | ||||
| runs the targeted feature tests.  It should take 5-10 seconds to perform feature | ||||
| tests without testing against the entire test battery.  New features should be | ||||
| accompanied with tests for the relevant file formats and features. | ||||
| At a high level, the final script is a concatenation of the individual files in | ||||
| the `bits` folder.  Running `make` should reproduce the final output on all | ||||
| platforms.  The README is similarly split into bits in the `docbits` folder. | ||||
| 
 | ||||
| For tests involving the read side, an appropriate feature test would involve | ||||
| reading an existing file and checking the resulting workbook object.  If a | ||||
| parameter is involved, files should be read with different values for the param | ||||
| to verify that the feature is working as expected. | ||||
| Folders: | ||||
| 
 | ||||
| For tests involving a new write feature which can already be parsed, appropriate | ||||
| feature tests would involve writing a workbook with the feature and then opening | ||||
| and verifying that the feature is preserved. | ||||
| | folder       | contents                                                      | | ||||
| |:-------------|:--------------------------------------------------------------| | ||||
| | `bits`       | raw source files that make up the final script                | | ||||
| | `docbits`    | raw markdown files that make up README.md                     | | ||||
| | `bin`        | server-side bin scripts (`xlsx.njs`)                          | | ||||
| | `dist`       | dist files for web browsers and nonstandard JS environments   | | ||||
| | `demos`      | demo projects for platforms like ExtendScript and Webpack     | | ||||
| | `tests`      | browser tests (run `make ctest` to rebuild)                   | | ||||
| | `types`      | typescript definitions and tests                              | | ||||
| | `misc`       | miscellaneous supporting scripts                              | | ||||
| | `test_files` | test files (pulled from the test files repository)            | | ||||
| 
 | ||||
| For tests involving a new write feature without an existing read ability, please | ||||
| add a feature test to the kitchen sink `tests/write.js`. | ||||
| </details> | ||||
| 
 | ||||
| After cloning the repo, running `make help` will display a list of commands. | ||||
| 
 | ||||
| ### OSX/Linux | ||||
| 
 | ||||
| <details> | ||||
| @ -2007,14 +2093,29 @@ make book -- rebuild README and summary | ||||
| make help -- display this message | ||||
| ``` | ||||
| 
 | ||||
| The normal approach uses a variety of command line tools to grab the test files. | ||||
| For windows users, please download the latest version of the test files snapshot | ||||
| from [github](https://github.com/SheetJS/test_files/releases) | ||||
| </details> | ||||
| 
 | ||||
| Latest test files snapshot: | ||||
| <https://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip> | ||||
| ### Tests | ||||
| 
 | ||||
| Download and unzip to the `test_files` subdirectory. | ||||
| <details> | ||||
| 	<summary>(click to show)</summary> | ||||
| 
 | ||||
| The `test_misc` target (`make test_misc` on Linux/OSX / `make misc` on Windows) | ||||
| runs the targeted feature tests.  It should take 5-10 seconds to perform feature | ||||
| tests without testing against the entire test battery.  New features should be | ||||
| accompanied with tests for the relevant file formats and features. | ||||
| 
 | ||||
| For tests involving the read side, an appropriate feature test would involve | ||||
| reading an existing file and checking the resulting workbook object.  If a | ||||
| parameter is involved, files should be read with different values for the param | ||||
| to verify that the feature is working as expected. | ||||
| 
 | ||||
| For tests involving a new write feature which can already be parsed, appropriate | ||||
| feature tests would involve writing a workbook with the feature and then opening | ||||
| and verifying that the feature is preserved. | ||||
| 
 | ||||
| For tests involving a new write feature without an existing read ability, please | ||||
| add a feature test to the kitchen sink `tests/write.js`. | ||||
| </details> | ||||
| 
 | ||||
| ## License | ||||
|  | ||||
							
								
								
									
										15
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										15
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							| @ -91,8 +91,8 @@ function wb_fmt() { | ||||
| } | ||||
| workbook_formats.forEach(function(m) { if(program[m]) { wb_fmt(); } }); | ||||
| wb_formats_2.forEach(function(m) { if(program[m[0]]) { wb_fmt(); } }); | ||||
| if(seen); | ||||
| else if(program.formulae) opts.cellFormula = true; | ||||
| if(seen) { | ||||
| } else if(program.formulae) opts.cellFormula = true; | ||||
| else opts.cellFormula = false; | ||||
| 
 | ||||
| if(program.all) { | ||||
| @ -107,11 +107,9 @@ if(program.all) { | ||||
| if(program.sparse) opts.dense = false; else opts.dense = true; | ||||
| 
 | ||||
| if(program.dev) { | ||||
| 	X.verbose = 2; | ||||
| 	opts.WTF = true; | ||||
| 	wb = X.readFile(filename, opts); | ||||
| } | ||||
| else try { | ||||
| } else try { | ||||
| 	wb = X.readFile(filename, opts); | ||||
| } catch(e) { | ||||
| 	var msg = (program.quiet) ? "" : n + ": error parsing "; | ||||
| @ -151,7 +149,10 @@ if(target_sheet === '') { | ||||
| var ws; | ||||
| try { | ||||
| 	ws = wb.Sheets[target_sheet]; | ||||
| 	if(!ws) throw "Sheet " + target_sheet + " cannot be found"; | ||||
| 	if(!ws) { | ||||
| 		console.error("Sheet " + target_sheet + " cannot be found"); | ||||
| 		process.exit(3); | ||||
| 	} | ||||
| } catch(e) { | ||||
| 	console.error(n + ": error parsing "+filename+" "+target_sheet+": " + e); | ||||
| 	process.exit(4); | ||||
| @ -176,7 +177,7 @@ if(program.readOnly) process.exit(0); | ||||
| var oo = ""; | ||||
| var strm = false; | ||||
| if(!program.quiet) console.error(target_sheet); | ||||
| if(program.formulae) oo = X.utils.get_formulae(ws).join("\n"); | ||||
| if(program.formulae) oo = X.utils.sheet_to_formulae(ws).join("\n"); | ||||
| else if(program.json) oo = JSON.stringify(X.utils.sheet_to_json(ws)); | ||||
| else if(program.rawJs) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true})); | ||||
| else if(program.arrays) oo = JSON.stringify(X.utils.sheet_to_json(ws,{raw:true, header:1})); | ||||
|  | ||||
| @ -51,9 +51,10 @@ var HTML_ = (function() { | ||||
| 	function html_to_book(str/*:string*/, opts)/*:Workbook*/ { | ||||
| 		return sheet_to_workbook(html_to_sheet(str, opts), opts); | ||||
| 	} | ||||
| 	function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o)/*:string*/ { | ||||
| 	function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HTMLOpts*/)/*:string*/ { | ||||
| 		var M = (ws['!merges'] ||[]); | ||||
| 		var oo = []; | ||||
| 		var nullcell = "<td" + (o.editable ? ' contenteditable="true"' : "" ) + "></td>"; | ||||
| 		for(var C = r.s.c; C <= r.e.c; ++C) { | ||||
| 			var RS = 0, CS = 0; | ||||
| 			for(var j = 0; j < M.length; ++j) { | ||||
| @ -65,29 +66,36 @@ var HTML_ = (function() { | ||||
| 			if(RS < 0) continue; | ||||
| 			var coord = encode_cell({r:R,c:C}); | ||||
| 			var cell = o.dense ? (ws[R]||[])[C] : ws[coord]; | ||||
| 			if(!cell || cell.v == null) { oo.push("<td></td>"); continue; } | ||||
| 			if(!cell || cell.v == null) { oo.push(nullcell); continue; } | ||||
| 			/* TODO: html entities */ | ||||
| 			var w = cell.h || escapexml(cell.w || (format_cell(cell), cell.w) || ""); | ||||
| 			var sp = {}; | ||||
| 			if(RS > 1) sp.rowspan = RS; | ||||
| 			if(CS > 1) sp.colspan = CS; | ||||
| 			if(o.editable) sp.contenteditable = "true"; | ||||
| 			oo.push(writextag('td', w, sp)); | ||||
| 		} | ||||
| 		return "<tr>" + oo.join("") + "</tr>"; | ||||
| 	} | ||||
| 	function sheet_to_html(ws/*:Worksheet*/, opts/*:Sheet2HTMLOpts*/)/*:string*/ { | ||||
| 	var _BEGIN = "<html><head><title>SheetJS Table Export</title></head><body><table>"; | ||||
| 	var _END = "</table></body></html>"; | ||||
| 	function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/)/*:string*/ { | ||||
| 		var o = opts || {}; | ||||
| 		var out/*:Array<string>*/ = []; | ||||
| 		var r = decode_range(ws['!ref']); | ||||
| 		o.dense = Array.isArray(ws); | ||||
| 		for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o)); | ||||
| 		return "<html><body><table>" + out.join("") + "</table></body></html>"; | ||||
| 		var header = o.header != null ? o.header : _BEGIN; | ||||
| 		var footer = o.footer != null ? o.footer : _END; | ||||
| 		return header + out.join("") + footer ; | ||||
| 	} | ||||
| 
 | ||||
| 	return { | ||||
| 		to_workbook: html_to_book, | ||||
| 		to_sheet: html_to_sheet, | ||||
| 		_row: make_html_row, | ||||
| 		BEGIN: _BEGIN, | ||||
| 		END: _END, | ||||
| 		from_sheet: sheet_to_html | ||||
| 	}; | ||||
| })(); | ||||
|  | ||||
| @ -211,6 +211,7 @@ var utils/*:any*/ = { | ||||
| 	table_to_book: table_to_book, | ||||
| 	sheet_to_csv: sheet_to_csv, | ||||
| 	sheet_to_json: sheet_to_json, | ||||
| 	sheet_to_html: HTML_.from_sheet, | ||||
| 	sheet_to_formulae: sheet_to_formulae, | ||||
| 	sheet_to_row_object_array: sheet_to_json | ||||
| }; | ||||
|  | ||||
| @ -29,22 +29,19 @@ if(has_buf && typeof require != 'undefined') (function() { | ||||
| 		return stream; | ||||
| 	}; | ||||
| 
 | ||||
| 	var HTML_BEGIN = "<html><body><table>"; | ||||
| 	var HTML_END = "</table></body></html>"; | ||||
| 
 | ||||
| 	var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) { | ||||
| 		var stream = Readable(); | ||||
| 
 | ||||
| 		var o = opts == null ? {} : opts; | ||||
| 		var r = decode_range(sheet['!ref']), cell/*:Cell*/; | ||||
| 		o.dense = Array.isArray(sheet); | ||||
| 		stream.push(HTML_BEGIN); | ||||
| 		stream.push(HTML_.BEGIN); | ||||
| 
 | ||||
| 		var R = r.s.r; | ||||
| 		var end = false; | ||||
| 		stream._read = function() { | ||||
| 			if(R > r.e.r) { | ||||
| 				if(!end) { end = true; stream.push(HTML_END); } | ||||
| 				if(!end) { end = true; stream.push(HTML_.END); } | ||||
| 				return stream.push(null); | ||||
| 			} | ||||
| 			while(R <= r.e.r) { | ||||
|  | ||||
| @ -29,6 +29,7 @@ files and output the contents in various formats.  The source is available at | ||||
| Some helper functions in `XLSX.utils` generate different views of the sheets: | ||||
| 
 | ||||
| - `XLSX.utils.sheet_to_csv` generates CSV | ||||
| - `XLSX.utils.sheet_to_html` generates HTML | ||||
| - `XLSX.utils.sheet_to_json` generates an array of objects | ||||
| - `XLSX.utils.sheet_to_formulae` generates a list of formulae | ||||
| 
 | ||||
|  | ||||
| @ -23,7 +23,7 @@ Note: browser generates binary blob and forces a "download" to client.  This | ||||
| example uses [FileSaver.js](https://github.com/eligrey/FileSaver.js/): | ||||
| 
 | ||||
| ```js | ||||
| /* bookType can be any supported output type */  | ||||
| /* bookType can be any supported output type */ | ||||
| var wopts = { bookType:'xlsx', bookSST:false, type:'binary' }; | ||||
| 
 | ||||
| var wbout = XLSX.write(workbook,wopts); | ||||
|  | ||||
| @ -5,7 +5,18 @@ take the same arguments as the normal write functions but return a readable | ||||
| stream.  They are only exposed in node. | ||||
| 
 | ||||
| - `XLSX.stream.to_csv` is the streaming version of `XLSX.utils.sheet_to_csv`. | ||||
| - `XLSX.stream.to_html` is the streaming version of the HTML output type. | ||||
| - `XLSX.stream.to_html` is the streaming version of `XLSX.utils.sheet_to_html`. | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>nodejs convert to CSV and write file</b> (click to show)</summary> | ||||
| 
 | ||||
| ```js | ||||
| var output_file_name = "out.csv"; | ||||
| var stream = XLSX.stream.to_csv(worksheet); | ||||
| stream.pipe(fs.createWriteStream(output_file_name)); | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
| <https://github.com/sheetjs/sheetaki> pipes write streams to nodejs response. | ||||
| 
 | ||||
|  | ||||
| @ -35,11 +35,13 @@ Utilities are available in the `XLSX.utils` object: | ||||
| 
 | ||||
| - `aoa_to_sheet` converts an array of arrays of JS data to a worksheet. | ||||
| - `json_to_sheet` converts an array of JS objects to a worksheet. | ||||
| - `table_to_sheet` converts a DOM TABLE element to a worksheet. | ||||
| 
 | ||||
| **Exporting:** | ||||
| 
 | ||||
| - `sheet_to_json` converts a worksheet object to an array of JSON objects. | ||||
| - `sheet_to_csv` generates delimiter-separated-values output. | ||||
| - `sheet_to_html` generates HTML output. | ||||
| - `sheet_to_formulae` generates a list of the formulae (with value fallbacks). | ||||
| 
 | ||||
| These utilities are described in [Utility Functions](#utility-functions) below. | ||||
| @ -52,3 +54,5 @@ These utilities are described in [Utility Functions](#utility-functions) below. | ||||
| - `{en,de}code_cell` converts cell addresses | ||||
| - `{en,de}code_range` converts cell ranges | ||||
| 
 | ||||
| Utilities are described in the [Utility Functions](#utility-functions) section. | ||||
| 
 | ||||
|  | ||||
| @ -6,23 +6,39 @@ objects which have the following properties: | ||||
| ```typescript | ||||
| type ColInfo = { | ||||
| 	/* visibility */ | ||||
| 	hidden:?boolean; // if true, the column is hidden | ||||
| 	hidden?: boolean; // if true, the column is hidden | ||||
| 
 | ||||
| 	/* column width is specified in one of the following ways: */ | ||||
| 	wpx?:number;     // width in screen pixels | ||||
| 	width?:number;    // width in Excel's "Max Digit Width", width*256 is integral | ||||
| 	wch?:number;     // width in characters | ||||
| 	wpx?:    number;  // width in screen pixels | ||||
| 	width?:  number;  // width in Excel's "Max Digit Width", width*256 is integral | ||||
| 	wch?:    number;  // width in characters | ||||
| 
 | ||||
| 	/* other fields for preserving features from files */ | ||||
| 	MDW?:number;     // Excel's "Max Digit Width" unit, always integral | ||||
| 	MDW?:    number;  // Excel's "Max Digit Width" unit, always integral | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| Excel internally stores column widths in a nebulous "Max Digit Width" form.  The | ||||
| <details> | ||||
| 	<summary><b>Why are there three width types?</b> (click to show)</summary> | ||||
| 
 | ||||
| There are three different width types corresponding to the three different ways | ||||
| spreadsheets store column widths: | ||||
| 
 | ||||
| SYLK and other plaintext formats use raw character count.  Contemporaneous tools | ||||
| like Visicalc and Multiplan were character based.  Since the characters had the | ||||
| same width, it sufficed to store a count.  This tradition was continued into the | ||||
| BIFF formats. | ||||
| 
 | ||||
| SpreadsheetML (2003) tried to align with HTML by standardizing on screen pixel | ||||
| count throughout the file.  Column widths, row heights, and other measures use | ||||
| pixels.  When the pixel and character counts do not align, Excel rounds values. | ||||
| 
 | ||||
| XLSX internally stores column widths in a nebulous "Max Digit Width" form.  The | ||||
| Max Digit Width is the width of the largest digit when rendered (generally the | ||||
| "0" character is the widest).  The internal width must be an integer multiple of | ||||
| the the width divided by 256.  ECMA-376 describes a formula for converting | ||||
| between pixels and the internal width. | ||||
| between pixels and the internal width.  This represents a hybrid approach. | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Implementation details</b> (click to show)</summary> | ||||
| @ -49,11 +65,11 @@ objects which have the following properties: | ||||
| ```typescript | ||||
| type RowInfo = { | ||||
| 	/* visibility */ | ||||
| 	hidden?:boolean; // if true, the row is hidden | ||||
| 	hidden?: boolean; // if true, the row is hidden | ||||
| 
 | ||||
| 	/* row height is specified in one of the following ways: */ | ||||
| 	hpx?:number;     // height in screen pixels | ||||
| 	hpt?:number;     // height in points | ||||
| 	hpx?:    number;  // height in screen pixels | ||||
| 	hpt?:    number;  // height in points | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
|  | ||||
| @ -14,7 +14,6 @@ at index 164.  The following example creates a custom format from scratch: | ||||
| 	<summary><b>New worksheet with custom format</b> (click to show)</summary> | ||||
| 
 | ||||
| ```js | ||||
| var tbl = {}; | ||||
| var wb = { | ||||
| 	SheetNames: ["Sheet1"], | ||||
| 	Sheets: { | ||||
|  | ||||
| @ -90,3 +90,21 @@ Plaintext format guessing follows the priority order: | ||||
| | PRN    | (default)                                                           | | ||||
| </details> | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Why are random text files valid?</b> (click to show)</summary> | ||||
| 
 | ||||
| Excel is extremely aggressive in reading files.  Adding an XLS extension to any | ||||
| display text file  (where the only characters are ANSI display chars) tricks | ||||
| Excel into thinking that the file is potentially a CSV or TSV file, even if it | ||||
| is only one column!  This library attempts to replicate that behavior. | ||||
| 
 | ||||
| The best approach is to validate the desired worksheet and ensure it has the | ||||
| expected number of rows or columns.  Extracting the range is extremely simple: | ||||
| 
 | ||||
| ```js | ||||
| var range = XLSX.utils.decode_range(worksheet['!ref']); | ||||
| var ncols = range.e.c - range.r.c + 1, nrows = range.e.r - range.s.r + 1; | ||||
| ``` | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
|  | ||||
| @ -152,6 +152,29 @@ The `txt` output type uses the tab character as the field separator.  If the | ||||
| codepage library is available (included in the full distribution but not core), | ||||
| the output will be encoded in codepage `1200` and the BOM will be prepended. | ||||
| 
 | ||||
| ### HTML Output | ||||
| 
 | ||||
| As an alternative to the `writeFile` HTML type, `XLSX.utils.sheet_to_html` also | ||||
| produces HTML output.  The function takes an options argument: | ||||
| 
 | ||||
| | Option Name |  Default | Description                                         | | ||||
| | :---------- | :------: | :-------------------------------------------------- | | ||||
| | editable    |  false   | If true, set `contenteditable="true"` for every TD  | | ||||
| | header      |          | Override header (default `html body table`)         | | ||||
| | footer      |          | Override footer (default `/table /body /html`)      | | ||||
| 
 | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Examples</b> (click to show)</summary> | ||||
| 
 | ||||
| For the example sheet: | ||||
| 
 | ||||
| ```js | ||||
| > console.log(XLSX.utils.sheet_to_html(ws)); | ||||
| // ... | ||||
| ``` | ||||
| </details> | ||||
| 
 | ||||
| ### JSON | ||||
| 
 | ||||
| `XLSX.utils.sheet_to_json` generates different types of JS objects. The function | ||||
|  | ||||
| @ -84,6 +84,17 @@ Tests utilize the mocha testing framework.  Travis-CI and Sauce Labs links: | ||||
| Test files are housed in [another repo](https://github.com/SheetJS/test_files). | ||||
| 
 | ||||
| Running `make init` will refresh the `test_files` submodule and get the files. | ||||
| Note that this requires `svn`, `git`, `hg` and other commands that may not be | ||||
| available.  If `make init` fails, please download the latest version of the test | ||||
| files snapshot from [the repo](https://github.com/SheetJS/test_files/releases) | ||||
| 
 | ||||
| <details> | ||||
| 	<summary><b>Latest Snapshot</b> (click to show)</summary> | ||||
| 
 | ||||
| Latest test files snapshot: | ||||
| <http://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip> | ||||
| 
 | ||||
| (download and unzip to the `test_files` subdirectory) | ||||
| 
 | ||||
| </details> | ||||
| 
 | ||||
|  | ||||
| @ -3,29 +3,31 @@ | ||||
| Due to the precarious nature of the Open Specifications Promise, it is very | ||||
| important to ensure code is cleanroom.  Consult CONTRIBUTING.md | ||||
| 
 | ||||
| ### Tests | ||||
| 
 | ||||
| <details> | ||||
| 	<summary>(click to show)</summary> | ||||
| 	<summary><b>File organization</b> (click to show)</summary> | ||||
| 
 | ||||
| The `test_misc` target (`make test_misc` on Linux/OSX / `make misc` on Windows) | ||||
| runs the targeted feature tests.  It should take 5-10 seconds to perform feature | ||||
| tests without testing against the entire test battery.  New features should be | ||||
| accompanied with tests for the relevant file formats and features. | ||||
| At a high level, the final script is a concatenation of the individual files in | ||||
| the `bits` folder.  Running `make` should reproduce the final output on all | ||||
| platforms.  The README is similarly split into bits in the `docbits` folder. | ||||
| 
 | ||||
| For tests involving the read side, an appropriate feature test would involve | ||||
| reading an existing file and checking the resulting workbook object.  If a | ||||
| parameter is involved, files should be read with different values for the param | ||||
| to verify that the feature is working as expected. | ||||
| Folders: | ||||
| 
 | ||||
| For tests involving a new write feature which can already be parsed, appropriate | ||||
| feature tests would involve writing a workbook with the feature and then opening | ||||
| and verifying that the feature is preserved. | ||||
| | folder       | contents                                                      | | ||||
| |:-------------|:--------------------------------------------------------------| | ||||
| | `bits`       | raw source files that make up the final script                | | ||||
| | `docbits`    | raw markdown files that make up README.md                     | | ||||
| | `bin`        | server-side bin scripts (`xlsx.njs`)                          | | ||||
| | `dist`       | dist files for web browsers and nonstandard JS environments   | | ||||
| | `demos`      | demo projects for platforms like ExtendScript and Webpack     | | ||||
| | `tests`      | browser tests (run `make ctest` to rebuild)                   | | ||||
| | `types`      | typescript definitions and tests                              | | ||||
| | `misc`       | miscellaneous supporting scripts                              | | ||||
| | `test_files` | test files (pulled from the test files repository)            | | ||||
| 
 | ||||
| For tests involving a new write feature without an existing read ability, please | ||||
| add a feature test to the kitchen sink `tests/write.js`. | ||||
| </details> | ||||
| 
 | ||||
| After cloning the repo, running `make help` will display a list of commands. | ||||
| 
 | ||||
| ### OSX/Linux | ||||
| 
 | ||||
| <details> | ||||
| @ -76,13 +78,28 @@ make book -- rebuild README and summary | ||||
| make help -- display this message | ||||
| ``` | ||||
| 
 | ||||
| The normal approach uses a variety of command line tools to grab the test files. | ||||
| For windows users, please download the latest version of the test files snapshot | ||||
| from [github](https://github.com/SheetJS/test_files/releases) | ||||
| 
 | ||||
| Latest test files snapshot: | ||||
| <https://github.com/SheetJS/test_files/releases/download/20170409/test_files.zip> | ||||
| 
 | ||||
| Download and unzip to the `test_files` subdirectory. | ||||
| </details> | ||||
| 
 | ||||
| ### Tests | ||||
| 
 | ||||
| <details> | ||||
| 	<summary>(click to show)</summary> | ||||
| 
 | ||||
| The `test_misc` target (`make test_misc` on Linux/OSX / `make misc` on Windows) | ||||
| runs the targeted feature tests.  It should take 5-10 seconds to perform feature | ||||
| tests without testing against the entire test battery.  New features should be | ||||
| accompanied with tests for the relevant file formats and features. | ||||
| 
 | ||||
| For tests involving the read side, an appropriate feature test would involve | ||||
| reading an existing file and checking the resulting workbook object.  If a | ||||
| parameter is involved, files should be read with different values for the param | ||||
| to verify that the feature is working as expected. | ||||
| 
 | ||||
| For tests involving a new write feature which can already be parsed, appropriate | ||||
| feature tests would involve writing a workbook with the feature and then opening | ||||
| and verifying that the feature is preserved. | ||||
| 
 | ||||
| For tests involving a new write feature without an existing read ability, please | ||||
| add a feature test to the kitchen sink `tests/write.js`. | ||||
| </details> | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										4
									
								
								jszip.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								jszip.js
									
									
									
									
									
								
							| @ -9,7 +9,7 @@ Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/js | ||||
| JSZip uses the library pako released under the MIT license : | ||||
| https://github.com/nodeca/pako/blob/master/LICENSE
 | ||||
| */ | ||||
| !function(e){ | ||||
| (function(e){ | ||||
| 	if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e(); | ||||
| 	else if("function"==typeof define&&define.amd){JSZip=e();define([],e);} | ||||
| 	else{ | ||||
| @ -8985,4 +8985,4 @@ function ZStream() { | ||||
| module.exports = ZStream; | ||||
| },{}]},{},[9]) | ||||
| (9) | ||||
| }); | ||||
| })); | ||||
|  | ||||
| @ -51,6 +51,7 @@ | ||||
|   * [Formulae Output](README.md#formulae-output) | ||||
|   * [Delimiter-Separated Output](README.md#delimiter-separated-output) | ||||
|     + [UTF-16 Unicode Text](README.md#utf-16-unicode-text) | ||||
|   * [HTML Output](README.md#html-output) | ||||
|   * [JSON](README.md#json) | ||||
| - [File Formats](README.md#file-formats) | ||||
|   * [Excel 2007+ XML (XLSX/XLSM)](README.md#excel-2007-xml-xlsxxlsm) | ||||
| @ -76,8 +77,8 @@ | ||||
|   * [Tested Environments](README.md#tested-environments) | ||||
|   * [Test Files](README.md#test-files) | ||||
| - [Contributing](README.md#contributing) | ||||
|   * [Tests](README.md#tests) | ||||
|   * [OSX/Linux](README.md#osxlinux) | ||||
|   * [Windows](README.md#windows) | ||||
|   * [Tests](README.md#tests) | ||||
| - [License](README.md#license) | ||||
| - [References](README.md#references) | ||||
|  | ||||
| @ -29,8 +29,10 @@ | ||||
| 		"mocha":"", | ||||
| 		"xlsjs":"", | ||||
| 		"@sheetjs/uglify-js":"", | ||||
| 		"@types/node":"", | ||||
| 		"@types/commander":"", | ||||
| 		"dtslint": "^0.1.2", | ||||
| 		"typescript": "^2.2.0" | ||||
| 		"typescript": "2.2.0" | ||||
| 	}, | ||||
| 	"repository": { "type":"git", "url":"git://github.com/SheetJS/js-xlsx.git" }, | ||||
| 	"scripts": { | ||||
|  | ||||
| @ -1,25 +0,0 @@ | ||||
| var XLSX = require('../'); | ||||
| 
 | ||||
| var tests = { | ||||
| 	'should be able to open workbook': function (file) { | ||||
| 		var xlsx = XLSX.readFile('tests/files/' + file); | ||||
| 		expect(xlsx).toBeTruthy(); | ||||
| 		expect(xlsx).toEqual(jasmine.any(Object)); | ||||
| 	}, | ||||
| 	'should define all api properties correctly': function (file) { | ||||
| 		var xlsx = XLSX.readFile('tests/files/' + file); | ||||
| 		expect(xlsx.Workbook).toEqual(jasmine.any(Object)); | ||||
| 		expect(xlsx.Props).toBeDefined(); | ||||
| 		expect(xlsx.Deps).toBeDefined(); | ||||
| 		expect(xlsx.Sheets).toEqual(jasmine.any(Object)); | ||||
| 		expect(xlsx.SheetNames).toEqual(jasmine.any(Array)); | ||||
| 		expect(xlsx.Strings).toBeDefined(); | ||||
| 		expect(xlsx.Styles).toBeDefined(); | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| module.exports = function (file) { | ||||
| 	for (var key in tests) { | ||||
| 		it(key, tests[key].bind(undefined, file)); | ||||
| 	} | ||||
| }; | ||||
| @ -1,8 +0,0 @@ | ||||
| var XLSX = require('../'); | ||||
| var testCommon = require('./Common.js'); | ||||
| 
 | ||||
| var file = 'חישוב_נקודות_זיכוי.xlsx'; | ||||
| 
 | ||||
| describe(file, function () { | ||||
| 	testCommon(file); | ||||
| }); | ||||
| @ -1,9 +0,0 @@ | ||||
| var XLSX = require('../'); | ||||
| var testCommon = require('./Common.js'); | ||||
| 
 | ||||
| var file = 'formula_stress_test.xlsx'; | ||||
| 
 | ||||
| describe(file, function () { | ||||
| 	// Opening the file currently crashes node
 | ||||
| 	//testCommon(file);
 | ||||
| }); | ||||
| @ -1,8 +0,0 @@ | ||||
| var XLSX = require('../'); | ||||
| var testCommon = require('./Common.js'); | ||||
| 
 | ||||
| var file = 'interview.xlsx'; | ||||
| 
 | ||||
| describe(file, function () { | ||||
| 	testCommon(file); | ||||
| }); | ||||
| @ -1,8 +0,0 @@ | ||||
| var XLSX = require('../'); | ||||
| var testCommon = require('./Common.js'); | ||||
| 
 | ||||
| var file = 'issue.xlsx'; | ||||
| 
 | ||||
| describe(file, function () { | ||||
| 	testCommon(file); | ||||
| }); | ||||
| @ -1,8 +0,0 @@ | ||||
| var XLSX = require('../'); | ||||
| var testCommon = require('./Common.js'); | ||||
| 
 | ||||
| var file = 'mixed_sheets.xlsx'; | ||||
| 
 | ||||
| describe(file, function () { | ||||
| 	testCommon(file); | ||||
| }); | ||||
| @ -1,8 +0,0 @@ | ||||
| var XLSX = require('../'); | ||||
| var testCommon = require('./Common.js'); | ||||
| 
 | ||||
| var file = 'named_ranges_2011.xlsx'; | ||||
| 
 | ||||
| describe(file, function () { | ||||
| 	testCommon(file); | ||||
| }); | ||||
							
								
								
									
										3
									
								
								types/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								types/Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| .PHONY: tslint | ||||
| tslint: | ||||
| 	@make -C.. tslint | ||||
							
								
								
									
										195
									
								
								types/bin_xlsx.ts
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										195
									
								
								types/bin_xlsx.ts
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,195 @@ | ||||
| /* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */ | ||||
| /* eslint-env node */ | ||||
| const n = "xlsx"; | ||||
| /* vim: set ts=2 ft=javascript: */ | ||||
| import XLSX = require("xlsx"); | ||||
| import 'exit-on-epipe'; | ||||
| import * as fs from 'fs'; | ||||
| import program = require('commander'); | ||||
| program | ||||
| 	.version(XLSX.version) | ||||
| 	.usage('[options] <file> [sheetname]') | ||||
| 	.option('-f, --file <file>', 'use specified workbook') | ||||
| 	.option('-s, --sheet <sheet>', 'print specified sheet (default first sheet)') | ||||
| 	.option('-N, --sheet-index <idx>', 'use specified sheet index (0-based)') | ||||
| 	.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('-6, --xlml', 'emit SSML to <sheetname> or <file>.xls (2003 XML)') | ||||
| 	.option('-T, --fods', 'emit FODS to <sheetname> or <file>.fods (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)') | ||||
| 	.option('-A, --arrays', 'emit rows as JS objects (raw numbers)') | ||||
| 	.option('-H, --html', 'emit HTML') | ||||
| 	.option('-D, --dif', 'emit data interchange format (dif)') | ||||
| 	.option('-K, --sylk', 'emit symbolic link (sylk)') | ||||
| 	.option('-P, --prn', 'emit formatted text (prn)') | ||||
| 	.option('-t, --txt', 'emit delimited text (txt)') | ||||
| 
 | ||||
| 	.option('-F, --field-sep <sep>', 'CSV field separator', ",") | ||||
| 	.option('-R, --row-sep <sep>', 'CSV row separator', "\n") | ||||
| 	.option('-n, --sheet-rows <num>', 'Number of rows to process (0=all rows)') | ||||
| 	.option('--sst', 'generate shared string table for XLS* formats') | ||||
| 	.option('--compress', 'use compression when writing XLSX/M/B and ODS') | ||||
| 	.option('--read-only', 'do not generate output') | ||||
| 	.option('--all', 'parse everything; write as much as possible') | ||||
| 	.option('--dev', 'development mode') | ||||
| 	.option('--read', 'read but do not print out contents') | ||||
| 	.option('-q, --quiet', 'quiet mode'); | ||||
| 
 | ||||
| program.on('--help', function() { | ||||
| 	console.log('  Default output format is CSV'); | ||||
| 	console.log('  Support email: dev@sheetjs.com'); | ||||
| 	console.log('  Web Demo: http://oss.sheetjs.com/js-'+n+'/'); | ||||
| }); | ||||
| 
 | ||||
| /* output formats, update list with full option name */ | ||||
| const workbook_formats = ['xlsx', 'xlsm', 'xlsb', 'ods', 'fods']; | ||||
| /* flag, bookType, default ext */ | ||||
| const wb_formats_2 = [ | ||||
| 	['xlml', 'xlml', 'xls'] | ||||
| ]; | ||||
| program.parse(process.argv); | ||||
| 
 | ||||
| let filename = '', sheetname = ''; | ||||
| if(program.args[0]) { | ||||
| 	filename = program.args[0]; | ||||
| 	if(program.args[1]) sheetname = program.args[1]; | ||||
| } | ||||
| if(program.sheet) sheetname = program.sheet; | ||||
| if(program.file) filename = program.file; | ||||
| 
 | ||||
| if(!filename) { | ||||
| 	console.error(n + ": must specify a filename"); | ||||
| 	process.exit(1); | ||||
| } | ||||
| /*:: if(filename) { */ | ||||
| if(!fs.existsSync(filename)) { | ||||
| 	console.error(n + ": " + filename + ": No such file or directory"); | ||||
| 	process.exit(2); | ||||
| } | ||||
| 
 | ||||
| let opts: XLSX.ParsingOptions = {}; | ||||
| let wb: XLSX.WorkBook; | ||||
| if(program.listSheets) opts.bookSheets = true; | ||||
| if(program.sheetRows) opts.sheetRows = program.sheetRows; | ||||
| if(program.password) opts.password = program.password; | ||||
| let seen = false; | ||||
| function wb_fmt() { | ||||
| 	seen = true; | ||||
| 	opts.cellFormula = true; | ||||
| 	opts.cellNF = true; | ||||
| 	if(program.output) sheetname = program.output; | ||||
| } | ||||
| workbook_formats.forEach(function(m) { if(program[m]) { wb_fmt(); } }); | ||||
| wb_formats_2.forEach(function(m) { if(program[m[0]]) { wb_fmt(); } }); | ||||
| if(seen) { | ||||
| } else if(program.formulae) opts.cellFormula = true; | ||||
| else opts.cellFormula = false; | ||||
| 
 | ||||
| if(program.all) { | ||||
| 	opts.cellFormula = true; | ||||
| 	opts.bookVBA = true; | ||||
| 	opts.cellNF = true; | ||||
| 	opts.cellHTML = true; | ||||
| 	opts.cellStyles = true; | ||||
| 	opts.sheetStubs = true; | ||||
| 	opts.cellDates = true; | ||||
| } | ||||
| 
 | ||||
| if(program.dev) { | ||||
| 	opts.WTF = true; | ||||
| 	wb = XLSX.readFile(filename, opts); | ||||
| } else try { | ||||
| 	wb = XLSX.readFile(filename, opts); | ||||
| } catch(e) { | ||||
| 	let msg = (program.quiet) ? "" : n + ": error parsing "; | ||||
| 	msg += filename + ": " + e; | ||||
| 	console.error(msg); | ||||
| 	process.exit(3); | ||||
| } | ||||
| if(program.read) process.exit(0); | ||||
| 
 | ||||
| /*::   if(wb) { */ | ||||
| if(program.listSheets) { | ||||
| 	console.log((wb.SheetNames||[]).join("\n")); | ||||
| 	process.exit(0); | ||||
| } | ||||
| 
 | ||||
| let wopts: XLSX.WritingOptions = ({WTF:opts.WTF, bookSST:program.sst}/*:any*/); | ||||
| if(program.compress) wopts.compression = true; | ||||
| 
 | ||||
| /* full workbook formats */ | ||||
| workbook_formats.forEach(function(m) { if(program[m]) { | ||||
| 		XLSX.writeFile(wb, sheetname || ((filename || "") + "." + m), wopts); | ||||
| 		process.exit(0); | ||||
| } }); | ||||
| 
 | ||||
| wb_formats_2.forEach(function(m) { if(program[m[0]]) { | ||||
| 		wopts.bookType = <XLSX.BookType>(m[1]); | ||||
| 		XLSX.writeFile(wb, sheetname || ((filename || "") + "." + m[2]), wopts); | ||||
| 		process.exit(0); | ||||
| } }); | ||||
| 
 | ||||
| let target_sheet = sheetname || ''; | ||||
| if(target_sheet === '') { | ||||
| 	if(program.sheetIndex < (wb.SheetNames||[]).length) target_sheet = wb.SheetNames[program.sheetIndex]; | ||||
| 	else target_sheet = (wb.SheetNames||[""])[0]; | ||||
| } | ||||
| 
 | ||||
| let ws: XLSX.WorkSheet; | ||||
| try { | ||||
| 	ws = wb.Sheets[target_sheet]; | ||||
| 	if(!ws) { | ||||
| 		console.error("Sheet " + target_sheet + " cannot be found"); | ||||
| 		process.exit(3); | ||||
| 	} | ||||
| } catch(e) { | ||||
| 	console.error(n + ": error parsing "+filename+" "+target_sheet+": " + e); | ||||
| 	process.exit(4); | ||||
| } | ||||
| 
 | ||||
| if(program.readOnly) process.exit(0); | ||||
| 
 | ||||
| /* single worksheet formats */ | ||||
| [ | ||||
| 	['biff2', '.xls'], | ||||
| 	['sylk', '.slk'], | ||||
| 	['html', '.html'], | ||||
| 	['prn', '.prn'], | ||||
| 	['txt', '.txt'], | ||||
| 	['dif', '.dif'] | ||||
| ].forEach(function(m) { if(program[m[0]]) { | ||||
| 		wopts.bookType = <XLSX.BookType>(m[1]); | ||||
| 		XLSX.writeFile(wb, sheetname || ((filename || "") + m[1]), wopts); | ||||
| 		process.exit(0); | ||||
| } }); | ||||
| 
 | ||||
| let oo = ""; | ||||
| let strm = false; | ||||
| if(!program.quiet) console.error(target_sheet); | ||||
| if(program.formulae) oo = XLSX.utils.sheet_to_formulae(ws).join("\n"); | ||||
| else if(program.json) oo = JSON.stringify(XLSX.utils.sheet_to_json(ws)); | ||||
| else if(program.rawJs) oo = JSON.stringify(XLSX.utils.sheet_to_json(ws,{raw:true})); | ||||
| else if(program.arrays) oo = JSON.stringify(XLSX.utils.sheet_to_json(ws,{raw:true, header:1})); | ||||
| else { | ||||
| 	strm = true; | ||||
| 	let stream: NodeJS.ReadableStream = XLSX.stream.to_csv(ws, {FS:program.fieldSep, RS:program.rowSep}); | ||||
| 	if(program.output) stream.pipe(fs.createWriteStream(program.output)); | ||||
| 	else stream.pipe(process.stdout); | ||||
| } | ||||
| 
 | ||||
| if(!strm) { | ||||
| 	if(program.output) fs.writeFileSync(program.output, oo); | ||||
| 	else console.log(oo); | ||||
| } | ||||
| /*::   } */ | ||||
| /*:: } */ | ||||
							
								
								
									
										406
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										406
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -1,28 +1,50 @@ | ||||
| /* index.d.ts (C) 2015-present SheetJS and contributors */ | ||||
| // TypeScript Version: 2.2
 | ||||
| 
 | ||||
| /** Version string */ | ||||
| export const version: string; | ||||
| 
 | ||||
| /** Attempts to read filename and parse */ | ||||
| export function readFile(filename: string, opts?: ParsingOptions): WorkBook; | ||||
| /** Attempts to parse data */ | ||||
| export function read(data: any, opts?: ParsingOptions): WorkBook; | ||||
| /** Attempts to write workbook data to filename */ | ||||
| /** NODE ONLY! Attempts to write workbook data to filename */ | ||||
| export function writeFile(data: WorkBook, filename: string, opts?: WritingOptions): any; | ||||
| /** Attempts to write the workbook data */ | ||||
| export function write(data: WorkBook, opts?: WritingOptions): any; | ||||
| 
 | ||||
| export const utils: Utils; | ||||
| export const stream: StreamUtils; | ||||
| 
 | ||||
| /** Number Format (either a string or an index to the format table) */ | ||||
| export type NumberFormat = string | number; | ||||
| 
 | ||||
| /** Basic File Properties */ | ||||
| export interface Properties { | ||||
|     /** Summary tab "Title" */ | ||||
|     Title?: string; | ||||
|     /** Summary tab "Subject" */ | ||||
|     Subject?: string; | ||||
|     /** Summary tab "Author" */ | ||||
|     Author?: string; | ||||
|     /** Summary tab "Manager" */ | ||||
|     Manager?: string; | ||||
|     /** Summary tab "Company" */ | ||||
|     Company?: string; | ||||
|     /** Summary tab "Category" */ | ||||
|     Category?: string; | ||||
|     /** Summary tab "Keywords" */ | ||||
|     Keywords?: string; | ||||
|     /** Summary tab "Comments" */ | ||||
|     Comments?: string; | ||||
|     /** Statistics tab "Last saved by" */ | ||||
|     LastAuthor?: string; | ||||
|     /** Statistics tab "Created" */ | ||||
|     CreatedDate?: Date; | ||||
| } | ||||
| 
 | ||||
| /** Other supported properties */ | ||||
| export interface FullProperties extends Properties { | ||||
|     ModifiedDate?: Date; | ||||
|     Application?: string; | ||||
|     AppVersion?: string; | ||||
| @ -33,13 +55,33 @@ export interface Properties { | ||||
|     ScaleCrop?: boolean; | ||||
|     Worksheets?: number; | ||||
|     SheetNames?: string[]; | ||||
|     ContentStatus?: string; | ||||
|     LastPrinted?: string; | ||||
|     Revision?: string | number; | ||||
|     Version?: string; | ||||
|     Identifier?: string; | ||||
|     Language?: string; | ||||
| } | ||||
| 
 | ||||
| export interface ParsingOptions { | ||||
| export interface CommonOptions { | ||||
|     /** | ||||
|      * Input data encoding | ||||
|      * If true, throw errors when features are not understood | ||||
|      * @default false | ||||
|      */ | ||||
|     type?: 'base64' | 'binary' | 'buffer' | 'array' | 'file'; | ||||
|     WTF?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * When reading a file, store dates as type d (default is n) | ||||
|      * When writing XLSX/XLSM file, use native date (default uses date codes) | ||||
|      * @default false | ||||
|      */ | ||||
|     cellDates?: boolean; | ||||
| } | ||||
| 
 | ||||
| /** Options for read and readFile */ | ||||
| export interface ParsingOptions extends CommonOptions { | ||||
|     /** Input data encoding */ | ||||
|     type?: 'base64' | 'binary' | 'buffer' | 'file' | 'array'; | ||||
| 
 | ||||
|     /** | ||||
|      * Save formulae to the .f field | ||||
| @ -66,10 +108,13 @@ export interface ParsingOptions { | ||||
|     cellStyles?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Store dates as type d (default is n) | ||||
|      * @default false | ||||
|      * Generate formatted text to the .w field | ||||
|      * @default true | ||||
|      */ | ||||
|     cellDates?: boolean; | ||||
|     cellText?: boolean; | ||||
| 
 | ||||
|     /** Override default date format (code 14) */ | ||||
|     dateNF?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Create cell objects for stub cells | ||||
| @ -120,18 +165,11 @@ export interface ParsingOptions { | ||||
|     password?: string; | ||||
| } | ||||
| 
 | ||||
| export interface WritingOptions { | ||||
|     /** | ||||
|      * Output data encoding | ||||
|      */ | ||||
| /** Options for write and writeFile */ | ||||
| export interface WritingOptions extends CommonOptions { | ||||
|     /** Output data encoding */ | ||||
|     type?: 'base64' | 'binary' | 'buffer' | 'file'; | ||||
| 
 | ||||
|     /** | ||||
|      * Store dates as type d (default is n) | ||||
|      * @default false | ||||
|      */ | ||||
|     cellDates?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Generate Shared String Table | ||||
|      * @default false | ||||
| @ -139,13 +177,13 @@ export interface WritingOptions { | ||||
|     bookSST?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Type of Workbook | ||||
|      * File format of generated workbook | ||||
|      * @default 'xlsx' | ||||
|      */ | ||||
|     bookType?: 'xlsx' | 'xlsm' | 'xlsb' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'prn'; | ||||
|     bookType?: BookType; | ||||
| 
 | ||||
|     /** | ||||
|      * Name of Worksheet for single-sheet formats | ||||
|      * Name of Worksheet (for single-sheet formats) | ||||
|      * @default '' | ||||
|      */ | ||||
|     sheet?: string; | ||||
| @ -155,8 +193,12 @@ export interface WritingOptions { | ||||
|      * @default false | ||||
|      */ | ||||
|     compression?: boolean; | ||||
| 
 | ||||
|     /** Override workbook properties on save */ | ||||
|     Props?: Properties; | ||||
| } | ||||
| 
 | ||||
| /** Workbook Object */ | ||||
| export interface WorkBook { | ||||
|     /** | ||||
|      * A dictionary of the worksheets in the workbook. | ||||
| @ -164,59 +206,72 @@ export interface WorkBook { | ||||
|      */ | ||||
|     Sheets: { [sheet: string]: WorkSheet }; | ||||
| 
 | ||||
|     /** | ||||
|      * ordered list of the sheet names in the workbook | ||||
|      */ | ||||
|     /** Ordered list of the sheet names in the workbook */ | ||||
|     SheetNames: string[]; | ||||
| 
 | ||||
|     /** | ||||
|      * an object storing the standard properties. wb.Custprops stores custom properties. | ||||
|      * Since the XLS standard properties deviate from the XLSX standard, XLS parsing stores core properties in both places. | ||||
|      */ | ||||
|     Props?: Properties; | ||||
|     Props?: FullProperties; | ||||
| 
 | ||||
|     Workbook?: WBProps; | ||||
| } | ||||
| 
 | ||||
| export interface SheetProps { | ||||
|     /** Sheet Visibility (0=Visible 1=Hidden 2=VeryHidden) */ | ||||
|     Hidden?: 0 | 1 | 2; | ||||
| } | ||||
| 
 | ||||
| export interface DefinedName { | ||||
|     Name: string; | ||||
|     Ref: string; | ||||
|     Sheet?: number; | ||||
|     Comment?: string; | ||||
| } | ||||
| 
 | ||||
| /** Workbook-Level Attributes */ | ||||
| export interface WBProps { | ||||
|     Sheets?: any[]; | ||||
|     /** Sheet Properties */ | ||||
|     Sheets?: SheetProps[]; | ||||
| 
 | ||||
|     /** Defined Names */ | ||||
|     Names?: DefinedName[]; | ||||
| } | ||||
| 
 | ||||
| export interface ColInfo { | ||||
|     /** | ||||
|      * Excel's "Max Digit Width" unit, always integral | ||||
|      */ | ||||
|     MDW?: number; | ||||
|     /** | ||||
|      * width in Excel's "Max Digit Width", width*256 is integral | ||||
|      */ | ||||
|     width?: number; | ||||
|     /** | ||||
|      * width in screen pixels | ||||
|      */ | ||||
|     wpx?: number; | ||||
|     /** | ||||
|      * intermediate character calculation | ||||
|      */ | ||||
|     wch?: number; | ||||
|     /** | ||||
|      * if true, the column is hidden | ||||
|      */ | ||||
|     /* --- visibility --- */ | ||||
| 
 | ||||
|     /** if true, the column is hidden */ | ||||
|     hidden?: boolean; | ||||
| 
 | ||||
|     /* --- column width --- */ | ||||
| 
 | ||||
|     /** width in Excel's "Max Digit Width", width*256 is integral */ | ||||
|     width?: number; | ||||
| 
 | ||||
|     /** width in screen pixels */ | ||||
|     wpx?: number; | ||||
| 
 | ||||
|     /** width in "characters" */ | ||||
|     wch?: number; | ||||
| 
 | ||||
|     /** Excel's "Max Digit Width" unit, always integral */ | ||||
|     MDW?: number; | ||||
| } | ||||
| export interface RowInfo { | ||||
|     /** | ||||
|      * height in screen pixels | ||||
|      */ | ||||
|     hpx?: number; | ||||
|     /** | ||||
|      * height in points | ||||
|      */ | ||||
|     hpt?: number; | ||||
|     /** | ||||
|      * if true, the column is hidden | ||||
|      */ | ||||
|     /* --- visibility --- */ | ||||
| 
 | ||||
|     /** if true, the column is hidden */ | ||||
|     hidden?: boolean; | ||||
| 
 | ||||
|     /* --- row height --- */ | ||||
| 
 | ||||
|     /** height in screen pixels */ | ||||
|     hpx?: number; | ||||
| 
 | ||||
|     /** height in points */ | ||||
|     hpt?: number; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -305,31 +360,62 @@ export interface ProtectInfo { | ||||
|     scenarios?: boolean; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * object representing any sheet (worksheet or chartsheet) | ||||
|  */ | ||||
| export interface Sheet { | ||||
|     '!ref'?: string; | ||||
|     '!margins'?: { | ||||
|         left: number, | ||||
|         right: number, | ||||
|         top: number, | ||||
|         bottom: number, | ||||
|         header: number, | ||||
|         footer: number, | ||||
|     }; | ||||
| /** Page Margins -- see Excel Page Setup .. Margins diagram for explanation */ | ||||
| export interface MarginInfo { | ||||
|     /** Left side margin (inches) */ | ||||
|     left?: number; | ||||
|     /** Right side margin (inches) */ | ||||
|     right?: number; | ||||
|     /** Top side margin (inches) */ | ||||
|     top?: number; | ||||
|     /** Bottom side margin (inches) */ | ||||
|     bottom?: number; | ||||
|     /** Header top margin (inches) */ | ||||
|     header?: number; | ||||
|     /** Footer bottom height (inches) */ | ||||
|     footer?: number; | ||||
| } | ||||
| export type SheetType = 'sheet' | 'chart'; | ||||
| export type SheetKeys = string | MarginInfo | SheetType; | ||||
| /** General object representing a Sheet (worksheet or chartsheet) */ | ||||
| export interface Sheet { | ||||
|     /** | ||||
|      * Indexing with a cell address string maps to a cell object | ||||
|      * Special keys start with '!' | ||||
|      */ | ||||
|     [cell: string]: CellObject | SheetKeys | any; | ||||
| 
 | ||||
|     /** Sheet type */ | ||||
|     '!type'?: SheetType; | ||||
| 
 | ||||
|     /** Sheet Range */ | ||||
|     '!ref'?: string; | ||||
| 
 | ||||
|     /** Page Margins */ | ||||
|     '!margins'?: MarginInfo; | ||||
| } | ||||
| 
 | ||||
| /** AutoFilter properties */ | ||||
| export interface AutoFilterInfo { | ||||
|     /** Range of the AutoFilter table */ | ||||
|     ref: string; | ||||
| } | ||||
| export type WSKeys = SheetKeys | ColInfo[] | RowInfo[] | Range[] | ProtectInfo | AutoFilterInfo; | ||||
| 
 | ||||
| /** | ||||
|  * object representing the worksheet | ||||
|  */ | ||||
| export interface WorkSheet extends Sheet { | ||||
|     [cell: string]: CellObject | any; | ||||
|     /** | ||||
|      * Indexing with a cell address string maps to a cell object | ||||
|      * Special keys start with '!' | ||||
|      */ | ||||
|     [cell: string]: CellObject | WSKeys | any; | ||||
|     '!cols'?: ColInfo[]; | ||||
|     '!rows'?: RowInfo[]; | ||||
|     '!merges'?: Range[]; | ||||
|     '!protect'?: ProtectInfo; | ||||
|     '!autofilter'?: {ref: string}; | ||||
|     '!autofilter'?: AutoFilterInfo; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
| @ -338,61 +424,63 @@ export interface WorkSheet extends Sheet { | ||||
|  */ | ||||
| export type ExcelDataType = 'b' | 'n' | 'e' | 's' | 'd' | 'z'; | ||||
| 
 | ||||
| export interface CellObject { | ||||
|     /** | ||||
|      * The raw value of the cell. | ||||
|      */ | ||||
|     v: string | number | boolean | Date; | ||||
| /** | ||||
|  * Type of generated workbook | ||||
|  * @default 'xlsx' | ||||
|  */ | ||||
| export type BookType = 'xlsx' | 'xlsm' | 'xlsb' | 'biff2' | 'xlml' | 'ods' | 'fods' | 'csv' | 'txt' | 'sylk' | 'html' | 'dif' | 'prn'; | ||||
| 
 | ||||
|     /** | ||||
|      * Formatted text (if applicable) | ||||
|      */ | ||||
| export interface Comment { | ||||
|     /** Author of the comment block */ | ||||
|     a?: string; | ||||
| 
 | ||||
|     /** Plaintext of the comment */ | ||||
|     t: string; | ||||
| } | ||||
| 
 | ||||
| export interface Hyperlink { | ||||
|     /** Target of the link (HREF) */ | ||||
|     Target: string; | ||||
| 
 | ||||
|     /** Plaintext tooltip to display when mouse is over cell */ | ||||
|     Tooltip?: string; | ||||
| } | ||||
| 
 | ||||
| export interface CellObject { | ||||
|     /** The raw value of the cell.  Can be omitted if a formula is specified */ | ||||
|     v?: string | number | boolean | Date; | ||||
| 
 | ||||
|     /** Formatted text (if applicable) */ | ||||
|     w?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * The Excel Data Type of the cell. | ||||
|      * b Boolean, n Number, e error, s String, d Date | ||||
|      * b Boolean, n Number, e Error, s String, d Date, z Empty | ||||
|      */ | ||||
|     t: ExcelDataType; | ||||
| 
 | ||||
|     /** | ||||
|      * Cell formula (if applicable) | ||||
|      */ | ||||
|     /** Cell formula (if applicable) */ | ||||
|     f?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Range of enclosing array if formula is array formula (if applicable) | ||||
|      */ | ||||
|     /** Range of enclosing array if formula is array formula (if applicable) */ | ||||
|     F?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Rich text encoding (if applicable) | ||||
|      */ | ||||
|     r?: string; | ||||
|     /** Rich text encoding (if applicable) */ | ||||
|     r?: any; | ||||
| 
 | ||||
|     /** | ||||
|      * HTML rendering of the rich text (if applicable) | ||||
|      */ | ||||
|     /** HTML rendering of the rich text (if applicable) */ | ||||
|     h?: string; | ||||
| 
 | ||||
|     /** | ||||
|      * Comments associated with the cell ** | ||||
|      */ | ||||
|     c?: string; | ||||
|     /** Comments associated with the cell */ | ||||
|     c?: Comment[]; | ||||
| 
 | ||||
|     /** | ||||
|      * Number format string associated with the cell (if requested) | ||||
|      */ | ||||
|     z?: string; | ||||
|     /** Number format string associated with the cell (if requested) */ | ||||
|     z?: NumberFormat; | ||||
| 
 | ||||
|     /** | ||||
|      * Cell hyperlink object (.Target holds link, .tooltip is tooltip) | ||||
|      */ | ||||
|     l?: object; | ||||
|     /** Cell hyperlink object (.Target holds link, .tooltip is tooltip) */ | ||||
|     l?: Hyperlink; | ||||
| 
 | ||||
|     /** | ||||
|      * The style/theme of the cell (if applicable) | ||||
|      */ | ||||
|     /** The style/theme of the cell (if applicable) */ | ||||
|     s?: object; | ||||
| } | ||||
| 
 | ||||
| @ -403,6 +491,9 @@ export interface CellAddress { | ||||
|     r: number; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Range object (representing ranges like "A1:B2") | ||||
|  */ | ||||
| export interface Range { | ||||
|     /** Starting cell */ | ||||
|     s: CellAddress; | ||||
| @ -410,24 +501,94 @@ export interface Range { | ||||
|     e: CellAddress; | ||||
| } | ||||
| 
 | ||||
| export interface Utils { | ||||
|     /* --- Cell Address Utilities --- */ | ||||
| export interface Sheet2CSVOpts { | ||||
|     /** Field Separator ("delimiter") */ | ||||
|     FS?: string; | ||||
| 
 | ||||
|     /** converts an array of arrays of JS data to a worksheet. */ | ||||
|     aoa_to_sheet<T>(data: T[], opts?: any): WorkSheet; | ||||
|     /** Record Separator ("row separator") */ | ||||
|     RS?: string; | ||||
| 
 | ||||
|     /** Use specified date format */ | ||||
|     dateNF?: NumberFormat; | ||||
| } | ||||
| 
 | ||||
| export interface Sheet2HTMLOpts { | ||||
|     editable?: boolean; | ||||
|     header?: string; | ||||
|     footer?: string; | ||||
| } | ||||
| 
 | ||||
| export interface Sheet2JSONOpts { | ||||
|     /** Use specified date format */ | ||||
|     dateNF?: NumberFormat; | ||||
| 
 | ||||
|     header?: "A"|number|string[]; | ||||
| 
 | ||||
|     range?: any; | ||||
| 
 | ||||
|     raw?: boolean; | ||||
| } | ||||
| 
 | ||||
| export interface AOA2SheetOpts { | ||||
|     /** Use specified date format */ | ||||
|     dateNF?: NumberFormat; | ||||
| 
 | ||||
|     /** | ||||
|      * Store dates as type d (default is n) | ||||
|      * @default false | ||||
|      */ | ||||
|     cellDates?: boolean; | ||||
| 
 | ||||
|     /** | ||||
|      * Create cell objects for stub cells | ||||
|      * @default false | ||||
|      */ | ||||
|     sheetStubs?: boolean; | ||||
| } | ||||
| 
 | ||||
| export interface JSON2SheetOpts { | ||||
|     /** Use specified date format */ | ||||
|     dateNF?: NumberFormat; | ||||
| } | ||||
| 
 | ||||
| export interface Table2SheetOpts { | ||||
|     /** Use specified date format */ | ||||
|     dateNF?: NumberFormat; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * General utilities | ||||
|  */ | ||||
| export interface Utils { | ||||
|     /* --- Import Functions --- */ | ||||
| 
 | ||||
|     /** Converts an array of arrays of JS data to a worksheet. */ | ||||
|     aoa_to_sheet<T>(data: T[][], opts?: AOA2SheetOpts): WorkSheet; | ||||
|     aoa_to_sheet(data: any[][], opts?: AOA2SheetOpts): WorkSheet; | ||||
| 
 | ||||
|     /** Converts an array of JS objects to a worksheet. */ | ||||
|     json_to_sheet<T>(data: T[], opts?: JSON2SheetOpts): WorkSheet; | ||||
|     json_to_sheet(data: any[], opts?: JSON2SheetOpts): WorkSheet; | ||||
| 
 | ||||
|     /** Converts a TABLE DOM element to a worksheet. */ | ||||
|     table_to_sheet(data: HTMLTableElement,  opts?: Table2SheetOpts): WorkSheet; | ||||
|     table_to_book(data: HTMLTableElement,  opts?: Table2SheetOpts): WorkBook; | ||||
| 
 | ||||
|     /* --- Export Functions --- */ | ||||
| 
 | ||||
|     /** Converts a worksheet object to an array of JSON objects */ | ||||
|     sheet_to_json<T>(worksheet: WorkSheet, opts?: { | ||||
|         raw?: boolean; | ||||
|         range?: any; | ||||
|         header?: "A"|number|string[]; | ||||
|     }): T[]; | ||||
|     sheet_to_json<T>(worksheet: WorkSheet, opts?: Sheet2JSONOpts): T[]; | ||||
|     sheet_to_json(worksheet: WorkSheet, opts?: Sheet2JSONOpts): any[][]; | ||||
|     sheet_to_json(worksheet: WorkSheet, opts?: Sheet2JSONOpts): any[]; | ||||
| 
 | ||||
|     /** Generates delimiter-separated-values output */ | ||||
|     sheet_to_csv(worksheet: WorkSheet, options?: { FS: string, RS: string }): string; | ||||
|     sheet_to_csv(worksheet: WorkSheet, options?: Sheet2CSVOpts): string; | ||||
| 
 | ||||
|     /** Generates HTML */ | ||||
|     sheet_to_html(worksheet: WorkSheet, options?: Sheet2HTMLOpts): string; | ||||
| 
 | ||||
|     /** Generates a list of the formulae (with value fallbacks) */ | ||||
|     sheet_to_formulae(worksheet: WorkSheet): any; | ||||
|     sheet_to_formulae(worksheet: WorkSheet): string[]; | ||||
| 
 | ||||
|     /* --- Cell Address Utilities --- */ | ||||
| 
 | ||||
| @ -442,6 +603,7 @@ export interface Utils { | ||||
| 
 | ||||
|     /** Converts 0-indexed range to A1 form */ | ||||
|     encode_range(s: CellAddress, e: CellAddress): string; | ||||
|     encode_range(r: Range): string; | ||||
| 
 | ||||
|     /** Converts A1 cell address to 0-indexed form */ | ||||
|     decode_cell(address: string): CellAddress; | ||||
| @ -455,3 +617,11 @@ export interface Utils { | ||||
|     /** Converts A1 range to 0-indexed form */ | ||||
|     decode_range(range: string): Range; | ||||
| } | ||||
| 
 | ||||
| /** NODE ONLY! these return Readable Streams */ | ||||
| export interface StreamUtils { | ||||
|     /** CSV output stream, generate one line at a time */ | ||||
|     to_csv(sheet: WorkSheet, opts?: Sheet2CSVOpts): any; | ||||
|     /** HTML output stream, generate one line at a time */ | ||||
|     to_html(sheet: WorkSheet, opts?: Sheet2HTMLOpts): any; | ||||
| } | ||||
|  | ||||
| @ -1,10 +1,7 @@ | ||||
| { | ||||
|     "compilerOptions": { | ||||
|         "module": "commonjs", | ||||
|         "lib": [ | ||||
|             "es6", | ||||
|             "dom" | ||||
|         ], | ||||
|         "lib": [ "es5", "dom" ], | ||||
|         "noImplicitAny": true, | ||||
|         "noImplicitThis": true, | ||||
|         "strictNullChecks": false, | ||||
|  | ||||
| @ -3,6 +3,8 @@ | ||||
| 	"rules": { | ||||
| 		"whitespace": false, | ||||
| 		"no-sparse-arrays": false, | ||||
| 		"no-consecutive-blank-lines": false | ||||
| 		"only-arrow-functions": false, | ||||
| 		"no-consecutive-blank-lines": false, | ||||
| 		"one-variable-per-declaration": false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| /* vim: set ts=2 ft=javascript: */ | ||||
| 
 | ||||
| /* original data */ | ||||
| let data = [ | ||||
| let data: any[][] = [ | ||||
| 	[1, 2, 3], | ||||
| 	[true, false, null, "sheetjs"], | ||||
| 	["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"], | ||||
| @ -13,7 +13,7 @@ let data = [ | ||||
| 
 | ||||
| const ws_name = "SheetJS"; | ||||
| 
 | ||||
| let wscols = [ | ||||
| let wscols: XLSX.ColInfo[] = [ | ||||
| 	{wch: 6}, // "characters"
 | ||||
| 	{wpx: 50}, // "pixels"
 | ||||
| 	, | ||||
| @ -21,7 +21,7 @@ let wscols = [ | ||||
| ]; | ||||
| 
 | ||||
| /* At 96 PPI, 1 pt = 1 px */ | ||||
| let wsrows = [ | ||||
| let wsrows: XLSX.RowInfo[] = [ | ||||
| 	{hpt: 12}, // "points"
 | ||||
| 	{hpx: 16}, // "pixels"
 | ||||
| 	, | ||||
| @ -46,14 +46,14 @@ let wb: XLSX.WorkBook = { SheetNames: <string[]>[], Sheets: {} }; | ||||
| 
 | ||||
| 
 | ||||
| /* convert an array of arrays in JS to a CSF spreadsheet */ | ||||
| let ws = XLSX.utils.aoa_to_sheet(data, {cellDates:true}); | ||||
| let ws: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet(data, {cellDates:true}); | ||||
| 
 | ||||
| /* TEST: add worksheet to workbook */ | ||||
| wb.SheetNames.push(ws_name); | ||||
| wb.Sheets[ws_name] = ws; | ||||
| 
 | ||||
| /* TEST: simple formula */ | ||||
| ws['C1'].f = "A1+B1"; | ||||
| (<XLSX.CellObject>ws['C1']).f = "A1+B1"; | ||||
| ws['C2'] = {t:'n', f:"A1+B1"}; | ||||
| 
 | ||||
| /* TEST: single-cell array formula */ | ||||
| @ -75,14 +75,14 @@ ws['!cols'] = wscols; | ||||
| ws['!rows'] = wsrows; | ||||
| 
 | ||||
| /* TEST: hyperlink note: Excel does not automatically style hyperlinks */ | ||||
| ws['A3'].l = { Target: "http://sheetjs.com", Tooltip: "Visit us <SheetJS.com!>" }; | ||||
| (<XLSX.CellObject>ws['A3']).l = { Target: "http://sheetjs.com", Tooltip: "Visit us <SheetJS.com!>" }; | ||||
| 
 | ||||
| /* TEST: built-in format */ | ||||
| ws['B1'].z = "0%"; // Format Code 9
 | ||||
| (<XLSX.CellObject>ws['B1']).z = "0%"; // Format Code 9
 | ||||
| 
 | ||||
| /* TEST: custom format */ | ||||
| const custfmt = "\"This is \"\\ 0.0"; | ||||
| ws['C2'].z = custfmt; | ||||
| (<XLSX.CellObject>ws['C2']).z = custfmt; | ||||
| 
 | ||||
| /* TEST: page margins */ | ||||
| ws['!margins'] =  { left:1.0, right:1.0, top:1.0, bottom:1.0, header:0.5, footer:0.5 }; | ||||
| @ -112,8 +112,8 @@ wb.Props = { | ||||
| 
 | ||||
| /* TEST: comments */ | ||||
| 
 | ||||
| ws['A4'].c = []; | ||||
| ws['A4'].c.push({a:"SheetJS",t:"I'm a little comment, short and stout!\n\nWell, Stout may be the wrong word"}); | ||||
| (<XLSX.CellObject>ws['A4']).c = []; | ||||
| (<XLSX.CellObject>ws['A4']).c.push({a:"SheetJS",t:"I'm a little comment, short and stout!\n\nWell, Stout may be the wrong word"}); | ||||
| 
 | ||||
| 
 | ||||
| /* TEST: sheet protection */ | ||||
|  | ||||
| @ -4,16 +4,16 @@ const options: XLSX.ParsingOptions = { | ||||
|     cellDates: true | ||||
| }; | ||||
| 
 | ||||
| const workbook = XLSX.readFile('test.xlsx', options); | ||||
| const otherworkbook = XLSX.readFile('test.xlsx', {type: 'file'}); | ||||
| const workbook: XLSX.WorkBook = XLSX.readFile('test.xlsx', options); | ||||
| const otherworkbook: XLSX.WorkBook = XLSX.readFile('test.xlsx', {type: 'file'}); | ||||
| 
 | ||||
| console.log(workbook.Props.Author); | ||||
| const author: string = workbook.Props.Author; | ||||
| 
 | ||||
| const firstsheet: string = workbook.SheetNames[0]; | ||||
| 
 | ||||
| const firstworksheet = workbook.Sheets[firstsheet]; | ||||
| const firstworksheet: XLSX.WorkSheet = workbook.Sheets[firstsheet]; | ||||
| 
 | ||||
| console.log(firstworksheet["A1"]); | ||||
| const WB1A1: XLSX.CellObject = (firstworksheet["A1"]); | ||||
| 
 | ||||
| interface Tester { | ||||
|     name: string; | ||||
| @ -21,5 +21,21 @@ interface Tester { | ||||
| } | ||||
| 
 | ||||
| const jsonvalues: Tester[] = XLSX.utils.sheet_to_json<Tester>(firstworksheet); | ||||
| const csv = XLSX.utils.sheet_to_csv(firstworksheet); | ||||
| const formulae = XLSX.utils.sheet_to_formulae(firstworksheet); | ||||
| const csv: string = XLSX.utils.sheet_to_csv(firstworksheet); | ||||
| const formulae: string[] = XLSX.utils.sheet_to_formulae(firstworksheet); | ||||
| const aoa: any[][] = XLSX.utils.sheet_to_json<any[]>(firstworksheet, {raw:true, header:1}); | ||||
| 
 | ||||
| const aoa2: XLSX.WorkSheet = XLSX.utils.aoa_to_sheet<number>([ | ||||
| 	[1,2,3,4,5,6,7], | ||||
| 	[2,3,4,5,6,7,8] | ||||
| ]); | ||||
| 
 | ||||
| const js2ws: XLSX.WorkSheet = XLSX.utils.json_to_sheet<Tester>([ | ||||
| 	{name:"Sheet", age: 12}, | ||||
| 	{name:"JS", age: 24} | ||||
| ]); | ||||
| 
 | ||||
| const WBProps = workbook.Workbook; | ||||
| const WBSheets = WBProps.Sheets; | ||||
| const WBSheet0 = WBSheets[0]; | ||||
| console.log(WBSheet0.Hidden); | ||||
|  | ||||
							
								
								
									
										24
									
								
								xlsx.flow.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										24
									
								
								xlsx.flow.js
									
									
									
									
									
								
							| @ -16099,9 +16099,10 @@ var HTML_ = (function() { | ||||
| 	function html_to_book(str/*:string*/, opts)/*:Workbook*/ { | ||||
| 		return sheet_to_workbook(html_to_sheet(str, opts), opts); | ||||
| 	} | ||||
| 	function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o)/*:string*/ { | ||||
| 	function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HTMLOpts*/)/*:string*/ { | ||||
| 		var M = (ws['!merges'] ||[]); | ||||
| 		var oo = []; | ||||
| 		var nullcell = "<td" + (o.editable ? ' contenteditable="true"' : "" ) + "></td>"; | ||||
| 		for(var C = r.s.c; C <= r.e.c; ++C) { | ||||
| 			var RS = 0, CS = 0; | ||||
| 			for(var j = 0; j < M.length; ++j) { | ||||
| @ -16113,29 +16114,36 @@ var HTML_ = (function() { | ||||
| 			if(RS < 0) continue; | ||||
| 			var coord = encode_cell({r:R,c:C}); | ||||
| 			var cell = o.dense ? (ws[R]||[])[C] : ws[coord]; | ||||
| 			if(!cell || cell.v == null) { oo.push("<td></td>"); continue; } | ||||
| 			if(!cell || cell.v == null) { oo.push(nullcell); continue; } | ||||
| 			/* TODO: html entities */ | ||||
| 			var w = cell.h || escapexml(cell.w || (format_cell(cell), cell.w) || ""); | ||||
| 			var sp = {}; | ||||
| 			if(RS > 1) sp.rowspan = RS; | ||||
| 			if(CS > 1) sp.colspan = CS; | ||||
| 			if(o.editable) sp.contenteditable = "true"; | ||||
| 			oo.push(writextag('td', w, sp)); | ||||
| 		} | ||||
| 		return "<tr>" + oo.join("") + "</tr>"; | ||||
| 	} | ||||
| 	function sheet_to_html(ws/*:Worksheet*/, opts/*:Sheet2HTMLOpts*/)/*:string*/ { | ||||
| 	var _BEGIN = "<html><head><title>SheetJS Table Export</title></head><body><table>"; | ||||
| 	var _END = "</table></body></html>"; | ||||
| 	function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/)/*:string*/ { | ||||
| 		var o = opts || {}; | ||||
| 		var out/*:Array<string>*/ = []; | ||||
| 		var r = decode_range(ws['!ref']); | ||||
| 		o.dense = Array.isArray(ws); | ||||
| 		for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o)); | ||||
| 		return "<html><body><table>" + out.join("") + "</table></body></html>"; | ||||
| 		var header = o.header != null ? o.header : _BEGIN; | ||||
| 		var footer = o.footer != null ? o.footer : _END; | ||||
| 		return header + out.join("") + footer ; | ||||
| 	} | ||||
| 
 | ||||
| 	return { | ||||
| 		to_workbook: html_to_book, | ||||
| 		to_sheet: html_to_sheet, | ||||
| 		_row: make_html_row, | ||||
| 		BEGIN: _BEGIN, | ||||
| 		END: _END, | ||||
| 		from_sheet: sheet_to_html | ||||
| 	}; | ||||
| })(); | ||||
| @ -17623,6 +17631,7 @@ var utils/*:any*/ = { | ||||
| 	table_to_book: table_to_book, | ||||
| 	sheet_to_csv: sheet_to_csv, | ||||
| 	sheet_to_json: sheet_to_json, | ||||
| 	sheet_to_html: HTML_.from_sheet, | ||||
| 	sheet_to_formulae: sheet_to_formulae, | ||||
| 	sheet_to_row_object_array: sheet_to_json | ||||
| }; | ||||
| @ -17764,22 +17773,19 @@ if(has_buf && typeof require != 'undefined') (function() { | ||||
| 		return stream; | ||||
| 	}; | ||||
| 
 | ||||
| 	var HTML_BEGIN = "<html><body><table>"; | ||||
| 	var HTML_END = "</table></body></html>"; | ||||
| 
 | ||||
| 	var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) { | ||||
| 		var stream = Readable(); | ||||
| 
 | ||||
| 		var o = opts == null ? {} : opts; | ||||
| 		var r = decode_range(sheet['!ref']), cell/*:Cell*/; | ||||
| 		o.dense = Array.isArray(sheet); | ||||
| 		stream.push(HTML_BEGIN); | ||||
| 		stream.push(HTML_.BEGIN); | ||||
| 
 | ||||
| 		var R = r.s.r; | ||||
| 		var end = false; | ||||
| 		stream._read = function() { | ||||
| 			if(R > r.e.r) { | ||||
| 				if(!end) { end = true; stream.push(HTML_END); } | ||||
| 				if(!end) { end = true; stream.push(HTML_.END); } | ||||
| 				return stream.push(null); | ||||
| 			} | ||||
| 			while(R <= r.e.r) { | ||||
|  | ||||
							
								
								
									
										20
									
								
								xlsx.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										20
									
								
								xlsx.js
									
									
									
									
									
								
							| @ -16032,6 +16032,7 @@ var HTML_ = (function() { | ||||
| 	function make_html_row(ws, r, R, o) { | ||||
| 		var M = (ws['!merges'] ||[]); | ||||
| 		var oo = []; | ||||
| 		var nullcell = "<td" + (o.editable ? ' contenteditable="true"' : "" ) + "></td>"; | ||||
| 		for(var C = r.s.c; C <= r.e.c; ++C) { | ||||
| 			var RS = 0, CS = 0; | ||||
| 			for(var j = 0; j < M.length; ++j) { | ||||
| @ -16043,29 +16044,36 @@ var HTML_ = (function() { | ||||
| 			if(RS < 0) continue; | ||||
| 			var coord = encode_cell({r:R,c:C}); | ||||
| 			var cell = o.dense ? (ws[R]||[])[C] : ws[coord]; | ||||
| 			if(!cell || cell.v == null) { oo.push("<td></td>"); continue; } | ||||
| 			if(!cell || cell.v == null) { oo.push(nullcell); continue; } | ||||
| 			/* TODO: html entities */ | ||||
| 			var w = cell.h || escapexml(cell.w || (format_cell(cell), cell.w) || ""); | ||||
| 			var sp = {}; | ||||
| 			if(RS > 1) sp.rowspan = RS; | ||||
| 			if(CS > 1) sp.colspan = CS; | ||||
| 			if(o.editable) sp.contenteditable = "true"; | ||||
| 			oo.push(writextag('td', w, sp)); | ||||
| 		} | ||||
| 		return "<tr>" + oo.join("") + "</tr>"; | ||||
| 	} | ||||
| 	var _BEGIN = "<html><head><title>SheetJS Table Export</title></head><body><table>"; | ||||
| 	var _END = "</table></body></html>"; | ||||
| 	function sheet_to_html(ws, opts) { | ||||
| 		var o = opts || {}; | ||||
| 		var out = []; | ||||
| 		var r = decode_range(ws['!ref']); | ||||
| 		o.dense = Array.isArray(ws); | ||||
| 		for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o)); | ||||
| 		return "<html><body><table>" + out.join("") + "</table></body></html>"; | ||||
| 		var header = o.header != null ? o.header : _BEGIN; | ||||
| 		var footer = o.footer != null ? o.footer : _END; | ||||
| 		return header + out.join("") + footer ; | ||||
| 	} | ||||
| 
 | ||||
| 	return { | ||||
| 		to_workbook: html_to_book, | ||||
| 		to_sheet: html_to_sheet, | ||||
| 		_row: make_html_row, | ||||
| 		BEGIN: _BEGIN, | ||||
| 		END: _END, | ||||
| 		from_sheet: sheet_to_html | ||||
| 	}; | ||||
| })(); | ||||
| @ -17549,6 +17557,7 @@ var utils = { | ||||
| 	table_to_book: table_to_book, | ||||
| 	sheet_to_csv: sheet_to_csv, | ||||
| 	sheet_to_json: sheet_to_json, | ||||
| 	sheet_to_html: HTML_.from_sheet, | ||||
| 	sheet_to_formulae: sheet_to_formulae, | ||||
| 	sheet_to_row_object_array: sheet_to_json | ||||
| }; | ||||
| @ -17690,22 +17699,19 @@ if(has_buf && typeof require != 'undefined') (function() { | ||||
| 		return stream; | ||||
| 	}; | ||||
| 
 | ||||
| 	var HTML_BEGIN = "<html><body><table>"; | ||||
| 	var HTML_END = "</table></body></html>"; | ||||
| 
 | ||||
| 	var write_html_stream = function(sheet, opts) { | ||||
| 		var stream = Readable(); | ||||
| 
 | ||||
| 		var o = opts == null ? {} : opts; | ||||
| 		var r = decode_range(sheet['!ref']), cell; | ||||
| 		o.dense = Array.isArray(sheet); | ||||
| 		stream.push(HTML_BEGIN); | ||||
| 		stream.push(HTML_.BEGIN); | ||||
| 
 | ||||
| 		var R = r.s.r; | ||||
| 		var end = false; | ||||
| 		stream._read = function() { | ||||
| 			if(R > r.e.r) { | ||||
| 				if(!end) { end = true; stream.push(HTML_END); } | ||||
| 				if(!end) { end = true; stream.push(HTML_.END); } | ||||
| 				return stream.push(null); | ||||
| 			} | ||||
| 			while(R <= r.e.r) { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user