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