forked from sheetjs/sheetjs
version bump 0.18.3
- XLSX / XLSB dynamic array formulae - use Uint8Array when available in write (fixes #2539 h/t @RScherzer) - mini build cleanup to satiate webpack (fixes #2526 #2530)
This commit is contained in:
parent
4f6a849a59
commit
e14aee3e51
.spellingMakefileREADME.md
bin
bits
01_version.js19_fsutils.js28_binstructs.js30_ctype.js51_xlmeta.js62_fxls.js67_wsxml.js68_wsbin.js74_xmlbin.js77_parsetab.js85_parsezip.js86_writezip.js88_write.js95_api.js
demos/server
dist
xlsx.core.min.jsxlsx.core.min.mapxlsx.extendscript.jsxlsx.full.min.jsxlsx.full.min.mapxlsx.mini.min.jsxlsx.mini.min.map
docbits
00_intro.md10_install.md13_usage.md16_demos.md20_import.md22_ingress.md25_manip.md32_egress.md51_cell.md61_formulae.md
mini.lstmisc
modules
package.jsontest_filestypes
xlsx.flow.jsxlsx.jsxlsx.mini.flow.jsxlsx.mini.jsxlsx.mjs@ -41,6 +41,7 @@ ExtendScript
|
|||||||
IndexedDB
|
IndexedDB
|
||||||
JavaScriptCore
|
JavaScriptCore
|
||||||
LocalStorage
|
LocalStorage
|
||||||
|
NestJS
|
||||||
NPM
|
NPM
|
||||||
Nuxt.js
|
Nuxt.js
|
||||||
Redis
|
Redis
|
||||||
|
7
Makefile
7
Makefile
@ -18,6 +18,7 @@ ESMJSDEPS=$(shell cat misc/mjs.lst)
|
|||||||
ULIB=$(shell echo $(LIB) | tr a-z A-Z)
|
ULIB=$(shell echo $(LIB) | tr a-z A-Z)
|
||||||
DEPS=$(sort $(wildcard bits/*.js))
|
DEPS=$(sort $(wildcard bits/*.js))
|
||||||
TSBITS=$(patsubst modules/%,bits/%,$(wildcard modules/[0-9][0-9]_*.js))
|
TSBITS=$(patsubst modules/%,bits/%,$(wildcard modules/[0-9][0-9]_*.js))
|
||||||
|
MTSBITS=$(patsubst modules/%,misc/%,$(wildcard modules/[0-9][0-9]_*.js))
|
||||||
TARGET=$(LIB).js
|
TARGET=$(LIB).js
|
||||||
FLOWTARGET=$(LIB).flow.js
|
FLOWTARGET=$(LIB).flow.js
|
||||||
FLOWAUX=$(patsubst %.js,%.flow.js,$(AUXTARGETS))
|
FLOWAUX=$(patsubst %.js,%.flow.js,$(AUXTARGETS))
|
||||||
@ -52,6 +53,9 @@ bits/18_cfb.js: node_modules/cfb/xlscfb.flow.js
|
|||||||
$(TSBITS): bits/%: modules/%
|
$(TSBITS): bits/%: modules/%
|
||||||
cp $^ $@
|
cp $^ $@
|
||||||
|
|
||||||
|
$(MTSBITS): misc/%: modules/%
|
||||||
|
cp $^ $@
|
||||||
|
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: ## Remove targets and build artifacts
|
clean: ## Remove targets and build artifacts
|
||||||
@ -82,6 +86,7 @@ dist: dist-deps $(TARGET) bower.json ## Prepare JS files for distribution
|
|||||||
uglifyjs $(REQS) dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).core.min.js --source-map dist/$(LIB).core.min.map --preamble "$$(head -n 1 bits/00_header.js)"
|
uglifyjs $(REQS) dist/$(TARGET) $(UGLIFYOPTS) -o dist/$(LIB).core.min.js --source-map dist/$(LIB).core.min.map --preamble "$$(head -n 1 bits/00_header.js)"
|
||||||
misc/strip_sourcemap.sh dist/$(LIB).core.min.js
|
misc/strip_sourcemap.sh dist/$(LIB).core.min.js
|
||||||
@# full
|
@# full
|
||||||
|
#cat <(head -n 1 bits/00_header.js) $(DISTHDR) $(REQS) $(ADDONS) dist/$(TARGET) $(AUXTARGETS) > dist/$(LIB).full.js
|
||||||
uglifyjs $(DISTHDR) $(REQS) $(ADDONS) dist/$(TARGET) $(AUXTARGETS) $(UGLIFYOPTS) -o dist/$(LIB).full.min.js --source-map dist/$(LIB).full.min.map --preamble "$$(head -n 1 bits/00_header.js)"
|
uglifyjs $(DISTHDR) $(REQS) $(ADDONS) dist/$(TARGET) $(AUXTARGETS) $(UGLIFYOPTS) -o dist/$(LIB).full.min.js --source-map dist/$(LIB).full.min.map --preamble "$$(head -n 1 bits/00_header.js)"
|
||||||
misc/strip_sourcemap.sh dist/$(LIB).full.min.js
|
misc/strip_sourcemap.sh dist/$(LIB).full.min.js
|
||||||
@# mini
|
@# mini
|
||||||
@ -101,7 +106,7 @@ dist-deps: ## Copy dependencies for distribution
|
|||||||
aux: $(AUXTARGETS)
|
aux: $(AUXTARGETS)
|
||||||
|
|
||||||
BYTEFILEC=dist/xlsx.{full,core,mini}.min.js
|
BYTEFILEC=dist/xlsx.{full,core,mini}.min.js
|
||||||
BYTEFILER=dist/xlsx.extendscript.js
|
BYTEFILER=dist/xlsx.extendscript.js xlsx.mjs
|
||||||
.PHONY: bytes
|
.PHONY: bytes
|
||||||
bytes: ## Display minified and gzipped file sizes
|
bytes: ## Display minified and gzipped file sizes
|
||||||
@for i in $(BYTEFILEC); do printj "%-30s %7d %10d" $$i $$(wc -c < $$i) $$(gzip --best --stdout $$i | wc -c); done
|
@for i in $(BYTEFILEC); do printj "%-30s %7d %10d" $$i $$(wc -c < $$i) $$(gzip --best --stdout $$i | wc -c); done
|
||||||
|
572
README.md
572
README.md
@ -24,12 +24,8 @@ port calculations to web apps; automate common spreadsheet tasks, and much more!
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
<details><summary><b>Diagram Legend</b> (click to show)</summary>
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@ -46,14 +42,17 @@ port calculations to web apps; automate common spreadsheet tasks, and much more!
|
|||||||
* [Parsing Workbooks](#parsing-workbooks)
|
* [Parsing Workbooks](#parsing-workbooks)
|
||||||
* [Processing JSON and JS Data](#processing-json-and-js-data)
|
* [Processing JSON and JS Data](#processing-json-and-js-data)
|
||||||
* [Processing HTML Tables](#processing-html-tables)
|
* [Processing HTML Tables](#processing-html-tables)
|
||||||
- [Working with the Workbook](#working-with-the-workbook)
|
- [Processing Data](#processing-data)
|
||||||
* [Parsing and Writing Examples](#parsing-and-writing-examples)
|
* [Modifying Workbook Structure](#modifying-workbook-structure)
|
||||||
|
* [Modifying Cell Values](#modifying-cell-values)
|
||||||
|
* [Modifying Other Worksheet / Workbook / Cell Properties](#modifying-other-worksheet--workbook--cell-properties)
|
||||||
- [Packaging and Releasing Data](#packaging-and-releasing-data)
|
- [Packaging and Releasing Data](#packaging-and-releasing-data)
|
||||||
* [Writing Workbooks](#writing-workbooks)
|
* [Writing Workbooks](#writing-workbooks)
|
||||||
* [Writing Examples](#writing-examples)
|
* [Writing Examples](#writing-examples)
|
||||||
* [Streaming Write](#streaming-write)
|
* [Streaming Write](#streaming-write)
|
||||||
* [Generating JSON and JS Data](#generating-json-and-js-data)
|
* [Generating JSON and JS Data](#generating-json-and-js-data)
|
||||||
* [Generating HTML Tables](#generating-html-tables)
|
* [Generating HTML Tables](#generating-html-tables)
|
||||||
|
* [Generating Single-Worksheet Snapshots](#generating-single-worksheet-snapshots)
|
||||||
- [Interface](#interface)
|
- [Interface](#interface)
|
||||||
* [Parsing functions](#parsing-functions)
|
* [Parsing functions](#parsing-functions)
|
||||||
* [Writing functions](#writing-functions)
|
* [Writing functions](#writing-functions)
|
||||||
@ -150,10 +149,11 @@ For example, `unpkg` makes the latest version available at:
|
|||||||
|
|
||||||
The complete single-file version is generated at `dist/xlsx.full.min.js`
|
The complete single-file version is generated at `dist/xlsx.full.min.js`
|
||||||
|
|
||||||
|
`dist/xlsx.core.min.js` omits codepage library (no support for XLS encodings)
|
||||||
|
|
||||||
A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
||||||
- codepage library skipped (no support for XLS encodings)
|
- codepage library skipped (no support for XLS encodings)
|
||||||
- XLSX compression option not currently available
|
- no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003 / Numbers
|
||||||
- no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003
|
|
||||||
- node stream utils removed
|
- node stream utils removed
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
@ -317,6 +317,18 @@ and approaches for steps 1 and 5.
|
|||||||
|
|
||||||
Utility functions help with step 3.
|
Utility functions help with step 3.
|
||||||
|
|
||||||
|
["Acquiring and Extracting Data"](#acquiring-and-extracting-data) describes
|
||||||
|
solutions for common data import scenarios.
|
||||||
|
|
||||||
|
["Packaging and Releasing Data"](#packaging-and-releasing-data) describes
|
||||||
|
solutions for common data export scenarios.
|
||||||
|
|
||||||
|
["Processing Data"](#packaging-and-releasing-data) describes solutions for
|
||||||
|
common workbook processing and manipulation scenarios.
|
||||||
|
|
||||||
|
["Utility Functions"](#utility-functions) details utility functions for
|
||||||
|
translating JSON Arrays and other common JS structures into worksheet objects.
|
||||||
|
|
||||||
### The Zen of SheetJS
|
### The Zen of SheetJS
|
||||||
|
|
||||||
_Data processing should fit in any workflow_
|
_Data processing should fit in any workflow_
|
||||||
@ -325,15 +337,6 @@ The library does not impose a separate lifecycle. It fits nicely in websites
|
|||||||
and apps built using any framework. The plain JS data objects play nice with
|
and apps built using any framework. The plain JS data objects play nice with
|
||||||
Web Workers and future APIs.
|
Web Workers and future APIs.
|
||||||
|
|
||||||
["Acquiring and Extracting Data"](#acquiring-and-extracting-data) describes
|
|
||||||
solutions for common data import scenarios.
|
|
||||||
|
|
||||||
["Writing Workbooks"](#writing-workbooks) describes solutions for common data
|
|
||||||
export scenarios involving actual spreadsheet files.
|
|
||||||
|
|
||||||
["Utility Functions"](#utility-functions) details utility functions for
|
|
||||||
translating JSON Arrays and other common JS structures into worksheet objects.
|
|
||||||
|
|
||||||
_JavaScript is a powerful language for data processing_
|
_JavaScript is a powerful language for data processing_
|
||||||
|
|
||||||
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
||||||
@ -576,6 +579,12 @@ The [`demos` directory](demos/) includes sample projects for:
|
|||||||
|
|
||||||
Other examples are included in the [showcase](demos/showcase/).
|
Other examples are included in the [showcase](demos/showcase/).
|
||||||
|
|
||||||
|
<https://sheetjs.com/demos/modify.html> shows a complete example of reading,
|
||||||
|
modifying, and writing files.
|
||||||
|
|
||||||
|
<https://github.com/SheetJS/sheetjs/blob/HEAD/bin/xlsx.njs> is the command-line
|
||||||
|
tool included with node installations, reading spreadsheet files and exporting
|
||||||
|
the contents in various formats.
|
||||||
## Acquiring and Extracting Data
|
## Acquiring and Extracting Data
|
||||||
|
|
||||||
### Parsing Workbooks
|
### Parsing Workbooks
|
||||||
@ -1018,12 +1027,13 @@ const workbook = XLSX.read(data);
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
More detailed examples are covered in the [included demos](demos/)
|
More detailed examples are covered in the [included demos](demos/)
|
||||||
|
|
||||||
### Processing JSON and JS Data
|
### Processing JSON and JS Data
|
||||||
|
|
||||||
JSON and JS data tend to represent single worksheets. This section will use a
|
JSON and JS data tend to represent single worksheets. This section will use a
|
||||||
few utility functions to generate workbooks:
|
few utility functions to generate workbooks.
|
||||||
|
|
||||||
_Create a new Worksheet_
|
_Create a new Workbook_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var workbook = XLSX.utils.book_new();
|
var workbook = XLSX.utils.book_new();
|
||||||
@ -1031,16 +1041,9 @@ var workbook = XLSX.utils.book_new();
|
|||||||
|
|
||||||
The `book_new` utility function creates an empty workbook with no worksheets.
|
The `book_new` utility function creates an empty workbook with no worksheets.
|
||||||
|
|
||||||
|
Spreadsheet software generally require at least one worksheet and enforce the
|
||||||
_Append a Worksheet to a Workbook_
|
requirement in the user interface. This library enforces the requirement at
|
||||||
|
write time, throwing errors if an empty workbook is passed to write functions.
|
||||||
```js
|
|
||||||
XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name);
|
|
||||||
```
|
|
||||||
|
|
||||||
The `book_append_sheet` utility function appends a worksheet to the workbook.
|
|
||||||
The third argument specifies the desired worksheet name. Multiple worksheets can
|
|
||||||
be added to a workbook by calling the function multiple times.
|
|
||||||
|
|
||||||
|
|
||||||
**API**
|
**API**
|
||||||
@ -1053,14 +1056,14 @@ var worksheet = XLSX.utils.aoa_to_sheet(aoa, opts);
|
|||||||
|
|
||||||
The `aoa_to_sheet` utility function walks an "array of arrays" in row-major
|
The `aoa_to_sheet` utility function walks an "array of arrays" in row-major
|
||||||
order, generating a worksheet object. The following snippet generates a sheet
|
order, generating a worksheet object. The following snippet generates a sheet
|
||||||
with cell `A1` set to the string `A1`, cell `B1` set to `B2`, etc:
|
with cell `A1` set to the string `A1`, cell `B1` set to `B1`, etc:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var worksheet = XLSX.utils.aoa_to_sheet([
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
["A1", "B1", "C1"],
|
["A1", "B1", "C1"],
|
||||||
["A2", "B2", "C2"],
|
["A2", "B2", "C2"],
|
||||||
["A3", "B3", "C3"]
|
["A3", "B3", "C3"]
|
||||||
])
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
||||||
@ -1361,41 +1364,57 @@ const workbook = XLSX.utils.table_to_book(doc);
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Working with the Workbook
|
## Processing Data
|
||||||
|
|
||||||
The full object format is described later in this README.
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
||||||
|
representation of the core concepts of a workbook. The utility functions work
|
||||||
|
with the object representation and are intended to handle common use cases.
|
||||||
|
|
||||||
<details>
|
### Modifying Workbook Structure
|
||||||
<summary><b>Reading a specific cell </b> (click to show)</summary>
|
|
||||||
|
|
||||||
This example extracts the value stored in cell A1 from the first worksheet:
|
**API**
|
||||||
|
|
||||||
|
_Append a Worksheet to a Workbook_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var first_sheet_name = workbook.SheetNames[0];
|
XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name);
|
||||||
var address_of_cell = 'A1';
|
|
||||||
|
|
||||||
/* Get worksheet */
|
|
||||||
var worksheet = workbook.Sheets[first_sheet_name];
|
|
||||||
|
|
||||||
/* Find desired cell */
|
|
||||||
var desired_cell = worksheet[address_of_cell];
|
|
||||||
|
|
||||||
/* Get the value */
|
|
||||||
var desired_value = (desired_cell ? desired_cell.v : undefined);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
The `book_append_sheet` utility function appends a worksheet to the workbook.
|
||||||
|
The third argument specifies the desired worksheet name. Multiple worksheets can
|
||||||
|
be added to a workbook by calling the function multiple times.
|
||||||
|
|
||||||
|
_List the Worksheet names in tab order_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var wsnames = workbook.SheetNames;
|
||||||
|
```
|
||||||
|
|
||||||
|
The `SheetNames` property of the workbook object is a list of the worksheet
|
||||||
|
names in "tab order". API functions will look at this array.
|
||||||
|
|
||||||
|
_Replace a Worksheet in place_
|
||||||
|
|
||||||
|
```js
|
||||||
|
workbook.Sheets[sheet_name] = new_worksheet;
|
||||||
|
```
|
||||||
|
|
||||||
|
The `Sheets` property of the workbook object is an object whose keys are names
|
||||||
|
and whose values are worksheet objects. By reassigning to a property of the
|
||||||
|
`Sheets` object, the worksheet object can be changed without disrupting the
|
||||||
|
rest of the worksheet structure.
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Adding a new worksheet to a workbook</b> (click to show)</summary>
|
<summary><b>Add a new worksheet to a workbook</b> (click to show)</summary>
|
||||||
|
|
||||||
This example uses [`XLSX.utils.aoa_to_sheet`](#array-of-arrays-input) to make a
|
This example uses [`XLSX.utils.aoa_to_sheet`](#array-of-arrays-input).
|
||||||
sheet and `XLSX.utils.book_append_sheet` to append the sheet to the workbook:
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var ws_name = "SheetJS";
|
var ws_name = "SheetJS";
|
||||||
|
|
||||||
/* make worksheet */
|
/* Create worksheet */
|
||||||
var ws_data = [
|
var ws_data = [
|
||||||
[ "S", "h", "e", "e", "t", "J", "S" ],
|
[ "S", "h", "e", "e", "t", "J", "S" ],
|
||||||
[ 1 , 2 , 3 , 4 , 5 ]
|
[ 1 , 2 , 3 , 4 , 5 ]
|
||||||
@ -1408,41 +1427,60 @@ XLSX.utils.book_append_sheet(wb, ws, ws_name);
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
### Modifying Cell Values
|
||||||
<summary><b>Creating a new workbook from scratch</b> (click to show)</summary>
|
|
||||||
|
|
||||||
The workbook object contains a `SheetNames` array of names and a `Sheets` object
|
**API**
|
||||||
mapping sheet names to sheet objects. The `XLSX.utils.book_new` utility function
|
|
||||||
creates a new workbook object:
|
_Modify a single cell value in a worksheet_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/* create a new blank workbook */
|
XLSX.utils.sheet_add_aoa(worksheet, [[new_value]], { origin: address });
|
||||||
var wb = XLSX.utils.book_new();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The new workbook is blank and contains no worksheets. The write functions will
|
_Modify multiple cell values in a worksheet_
|
||||||
error if the workbook is empty.
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, aoa, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `sheet_add_aoa` utility function modifies cell values in a worksheet. The
|
||||||
|
first argument is the worksheet object. The second argument is an array of
|
||||||
|
arrays of values. The `origin` key of the third argument controls where cells
|
||||||
|
will be written. The following snippet sets `B3=1` and `E5="abc"`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, [
|
||||||
|
[1], // <-- Write 1 to cell B3
|
||||||
|
, // <-- Do nothing in row 4
|
||||||
|
[/*B5*/, /*C5*/, /*D5*/, "abc"] // <-- Write "abc" to cell E5
|
||||||
|
], { origin: "B3" });
|
||||||
|
```
|
||||||
|
|
||||||
|
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
||||||
|
optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Appending rows to a worksheet</b> (click to show)</summary>
|
||||||
|
|
||||||
|
The special origin value `-1` instructs `sheet_add_aoa` to start in column A of
|
||||||
|
the row after the last row in the range, appending the data:
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, [
|
||||||
|
["first row after data", 1],
|
||||||
|
["second row after data", 2]
|
||||||
|
], { origin: -1 });
|
||||||
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
### Parsing and Writing Examples
|
### Modifying Other Worksheet / Workbook / Cell Properties
|
||||||
|
|
||||||
- <https://sheetjs.com/demos/modify.html> read + modify + write files
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) section describes
|
||||||
|
the object structures in greater detail.
|
||||||
- <https://github.com/SheetJS/sheetjs/blob/HEAD/bin/xlsx.njs> node
|
|
||||||
|
|
||||||
The node version installs a command line tool `xlsx` which can read spreadsheet
|
|
||||||
files and output the contents in various formats. The source is available at
|
|
||||||
`xlsx.njs` in the bin directory.
|
|
||||||
|
|
||||||
Some helper functions in `XLSX.utils` generate different views of the sheets:
|
|
||||||
|
|
||||||
- `XLSX.utils.sheet_to_csv` generates CSV
|
|
||||||
- `XLSX.utils.sheet_to_txt` generates UTF16 Formatted Text
|
|
||||||
- `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
|
|
||||||
|
|
||||||
## Packaging and Releasing Data
|
## Packaging and Releasing Data
|
||||||
|
|
||||||
@ -1963,6 +2001,45 @@ The [`vuejs` demo](demos/vue) includes more React examples.
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### Generating Single-Worksheet Snapshots
|
||||||
|
|
||||||
|
The `sheet_to_*` functions accept a worksheet object.
|
||||||
|
|
||||||
|
**API**
|
||||||
|
|
||||||
|
_Generate a CSV from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var csv = XLSX.utils.sheet_to_csv(worksheet, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot is designed to replicate the "CSV UTF8 (`.csv`)" output type.
|
||||||
|
["Delimiter-Separated Output"](#delimiter-separated-output) describes the
|
||||||
|
function and the optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
_Generate "Text" from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var txt = XLSX.utils.sheet_to_txt(worksheet, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot is designed to replicate the "UTF16 Text (`.txt`)" output type.
|
||||||
|
["Delimiter-Separated Output"](#delimiter-separated-output) describes the
|
||||||
|
function and the optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
_Generate a list of formulae from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var fmla = XLSX.utils.sheet_to_formulae(worksheet);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot generates an array of entries representing the embedded formulae.
|
||||||
|
Array formulae are rendered in the form `range=formula` while plain cells are
|
||||||
|
rendered in the form `cell=formula or value`. String literals are prefixed with
|
||||||
|
an apostrophe `'`, consistent with Excel's formula bar display.
|
||||||
|
|
||||||
|
["Formulae Output"](#formulae-output) describes the function in more detail.
|
||||||
|
|
||||||
## Interface
|
## Interface
|
||||||
|
|
||||||
`XLSX` is the exposed variable in the browser and the exported node variable
|
`XLSX` is the exposed variable in the browser and the exported node variable
|
||||||
@ -2065,6 +2142,7 @@ Cell objects are plain JS objects with keys and values following the convention:
|
|||||||
| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub |
|
| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub |
|
||||||
| `f` | cell formula encoded as an A1-style string (if applicable) |
|
| `f` | cell formula encoded as an A1-style string (if applicable) |
|
||||||
| `F` | range of enclosing array if formula is array formula (if applicable) |
|
| `F` | range of enclosing array if formula is array formula (if applicable) |
|
||||||
|
| `D` | if true, array formula is dynamic (if applicable) |
|
||||||
| `r` | rich text encoding (if applicable) |
|
| `r` | rich text encoding (if applicable) |
|
||||||
| `h` | HTML rendering of the rich text (if applicable) |
|
| `h` | HTML rendering of the rich text (if applicable) |
|
||||||
| `c` | comments associated with the cell |
|
| `c` | comments associated with the cell |
|
||||||
@ -2416,79 +2494,7 @@ Even though some formats store formulae with a leading equal sign, CSF formulae
|
|||||||
do not start with `=`.
|
do not start with `=`.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Representation of A1=1, A2=2, A3=A1+A2</b> (click to show)</summary>
|
<summary><b>Formulae File Format Support</b> (click to show)</summary>
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"!ref": "A1:A3",
|
|
||||||
A1: { t:'n', v:1 },
|
|
||||||
A2: { t:'n', v:2 },
|
|
||||||
A3: { t:'n', v:3, f:'A1+A2' }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
Shared formulae are decompressed and each cell has the formula corresponding to
|
|
||||||
its cell. Writers generally do not attempt to generate shared formulae.
|
|
||||||
|
|
||||||
Cells with formula entries but no value will be serialized in a way that Excel
|
|
||||||
and other spreadsheet tools will recognize. This library will not automatically
|
|
||||||
compute formula results! For example, to compute `BESSELJ` in a worksheet:
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><b>Formula without known value</b> (click to show)</summary>
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"!ref": "A1:A3",
|
|
||||||
A1: { t:'n', v:3.14159 },
|
|
||||||
A2: { t:'n', v:2 },
|
|
||||||
A3: { t:'n', f:'BESSELJ(A1,A2)' }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
**Array Formulae**
|
|
||||||
|
|
||||||
Array formulae are stored in the top-left cell of the array block. All cells
|
|
||||||
of an array formula have a `F` field corresponding to the range. A single-cell
|
|
||||||
formula can be distinguished from a plain formula by the presence of `F` field.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><b>Array Formula examples</b> (click to show)</summary>
|
|
||||||
|
|
||||||
For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" };
|
|
||||||
```
|
|
||||||
|
|
||||||
For a multi-cell array formula, every cell has the same array range but only the
|
|
||||||
first cell specifies the formula. Consider `D1:D3=A1:A3*B1:B3`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" };
|
|
||||||
worksheet['D2'] = { t:'n', F:"D1:D3" };
|
|
||||||
worksheet['D3'] = { t:'n', F:"D1:D3" };
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
Utilities and writers are expected to check for the presence of a `F` field and
|
|
||||||
ignore any possible formula element `f` in cells other than the starting cell.
|
|
||||||
They are not expected to perform validation of the formulae!
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><b>Formula Output Utility Function</b> (click to show)</summary>
|
|
||||||
|
|
||||||
The `sheet_to_formulae` method generates one line per formula or array formula.
|
|
||||||
Array formulae are rendered in the form `range=formula` while plain cells are
|
|
||||||
rendered in the form `cell=formula or value`. Note that string literals are
|
|
||||||
prefixed with an apostrophe `'`, consistent with Excel's formula bar display.
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><b>Formulae File Format Details</b> (click to show)</summary>
|
|
||||||
|
|
||||||
| Storage Representation | Formats | Read | Write |
|
| Storage Representation | Formats | Read | Write |
|
||||||
|:-----------------------|:-------------------------|:-----:|:-----:|
|
|:-----------------------|:-------------------------|:-----:|:-----:|
|
||||||
@ -2502,6 +2508,272 @@ Since Excel prohibits named cells from colliding with names of A1 or RC style
|
|||||||
cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed
|
cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed
|
||||||
formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula
|
formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula
|
||||||
formulae can be converted with regular expressions.
|
formulae can be converted with regular expressions.
|
||||||
|
|
||||||
|
Shared formulae are decompressed and each cell has the formula corresponding to
|
||||||
|
its cell. Writers generally do not attempt to generate shared formulae.
|
||||||
|
</details>
|
||||||
|
|
||||||
|
**Single-Cell Formulae**
|
||||||
|
|
||||||
|
For simple formulae, the `f` key of the desired cell can be set to the actual
|
||||||
|
formula text. This worksheet represents `A1=1`, `A2=2`, and `A3=A1+A2`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = {
|
||||||
|
"!ref": "A1:A3",
|
||||||
|
A1: { t:'n', v:1 },
|
||||||
|
A2: { t:'n', v:2 },
|
||||||
|
A3: { t:'n', v:3, f:'A1+A2' }
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Utilities like `aoa_to_sheet` will accept cell objects in lieu of values:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
[ 1 ], // A1
|
||||||
|
[ 2 ], // A2
|
||||||
|
[ {t: "n", v: 3, f: "A1+A2"} ] // A3
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Cells with formula entries but no value will be serialized in a way that Excel
|
||||||
|
and other spreadsheet tools will recognize. This library will not automatically
|
||||||
|
compute formula results! For example, the following worksheet will include the
|
||||||
|
`BESSELJ` function but the result will not be available in JavaScript:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
[ 3.14159, 2 ], // Row "1"
|
||||||
|
[ { t:'n', f:'BESSELJ(A1,B1)' } ] // Row "2" will be calculated on file open
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the actual results are needed in JS, [SheetJS Pro](https://sheetjs.com/pro)
|
||||||
|
offers a formula calculator component for evaluating expressions, updating
|
||||||
|
values and dependent cells, and refreshing entire workbooks.
|
||||||
|
|
||||||
|
|
||||||
|
**Array Formulae**
|
||||||
|
|
||||||
|
_Assign an array formula_
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, range, formula);
|
||||||
|
```
|
||||||
|
|
||||||
|
Array formulae are stored in the top-left cell of the array block. All cells
|
||||||
|
of an array formula have a `F` field corresponding to the range. A single-cell
|
||||||
|
formula can be distinguished from a plain formula by the presence of `F` field.
|
||||||
|
|
||||||
|
For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "SUM(A1:A3*B1:B3)");
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" };
|
||||||
|
```
|
||||||
|
|
||||||
|
For a multi-cell array formula, every cell has the same array range but only the
|
||||||
|
first cell specifies the formula. Consider `D1:D3=A1:A3*B1:B3`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "D1:D3", "A1:A3*B1:B3");
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" };
|
||||||
|
worksheet['D2'] = { t:'n', F:"D1:D3" };
|
||||||
|
worksheet['D3'] = { t:'n', F:"D1:D3" };
|
||||||
|
```
|
||||||
|
|
||||||
|
Utilities and writers are expected to check for the presence of a `F` field and
|
||||||
|
ignore any possible formula element `f` in cells other than the starting cell.
|
||||||
|
They are not expected to perform validation of the formulae!
|
||||||
|
|
||||||
|
|
||||||
|
**Dynamic Array Formulae**
|
||||||
|
|
||||||
|
_Assign a dynamic array formula_
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, range, formula, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
Released in 2020, Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB
|
||||||
|
file formats. They are represented like normal array formulae but have special
|
||||||
|
cell metadata indicating that the formula should be allowed to adjust the range.
|
||||||
|
|
||||||
|
An array formula can be marked as dynamic by setting the cell's `D` property to
|
||||||
|
true. The `F` range is expected but can be the set to the current cell:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1);
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['C1'] = { t: "s", f: "_xlfn.UNIQUE(A1:A3)", F:"C1", D: 1 }; // dynamic
|
||||||
|
```
|
||||||
|
|
||||||
|
**Localization with Function Names**
|
||||||
|
|
||||||
|
SheetJS operates at the file level. Excel stores formula expressions using the
|
||||||
|
English (United States) function names. For non-English users, Excel uses a
|
||||||
|
localized set of function names.
|
||||||
|
|
||||||
|
For example, when the computer language and region is set to French (France),
|
||||||
|
Excel interprets `=SOMME(A1:C3)` as if `SOMME` is the `SUM` function. However,
|
||||||
|
in the actual file, Excel stores `SUM(A1:C3)`.
|
||||||
|
|
||||||
|
**Prefixed "Future Functions"**
|
||||||
|
|
||||||
|
Functions introduced in newer versions of Excel are prefixed with `_xlfn.` when
|
||||||
|
stored in files. When writing formula expressions using these functions, the
|
||||||
|
prefix is required for maximal compatibility:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Broadest compatibility
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1);
|
||||||
|
|
||||||
|
// Can cause errors in spreadsheet software
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "UNIQUE(A1:A3)", 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
When reading a file, the `xlfn` option preserves the prefixes.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b> Functions requiring `_xlfn.` prefix</b> (click to show)</summary>
|
||||||
|
|
||||||
|
This list is growing with each Excel release.
|
||||||
|
|
||||||
|
```
|
||||||
|
ACOT
|
||||||
|
ACOTH
|
||||||
|
AGGREGATE
|
||||||
|
ARABIC
|
||||||
|
BASE
|
||||||
|
BETA.DIST
|
||||||
|
BETA.INV
|
||||||
|
BINOM.DIST
|
||||||
|
BINOM.DIST.RANGE
|
||||||
|
BINOM.INV
|
||||||
|
BITAND
|
||||||
|
BITLSHIFT
|
||||||
|
BITOR
|
||||||
|
BITRSHIFT
|
||||||
|
BITXOR
|
||||||
|
BYCOL
|
||||||
|
BYROW
|
||||||
|
CEILING.MATH
|
||||||
|
CEILING.PRECISE
|
||||||
|
CHISQ.DIST
|
||||||
|
CHISQ.DIST.RT
|
||||||
|
CHISQ.INV
|
||||||
|
CHISQ.INV.RT
|
||||||
|
CHISQ.TEST
|
||||||
|
COMBINA
|
||||||
|
CONFIDENCE.NORM
|
||||||
|
CONFIDENCE.T
|
||||||
|
COT
|
||||||
|
COTH
|
||||||
|
COVARIANCE.P
|
||||||
|
COVARIANCE.S
|
||||||
|
CSC
|
||||||
|
CSCH
|
||||||
|
DAYS
|
||||||
|
DECIMAL
|
||||||
|
ERF.PRECISE
|
||||||
|
ERFC.PRECISE
|
||||||
|
EXPON.DIST
|
||||||
|
F.DIST
|
||||||
|
F.DIST.RT
|
||||||
|
F.INV
|
||||||
|
F.INV.RT
|
||||||
|
F.TEST
|
||||||
|
FIELDVALUE
|
||||||
|
FILTERXML
|
||||||
|
FLOOR.MATH
|
||||||
|
FLOOR.PRECISE
|
||||||
|
FORMULATEXT
|
||||||
|
GAMMA
|
||||||
|
GAMMA.DIST
|
||||||
|
GAMMA.INV
|
||||||
|
GAMMALN.PRECISE
|
||||||
|
GAUSS
|
||||||
|
HYPGEOM.DIST
|
||||||
|
IFNA
|
||||||
|
IMCOSH
|
||||||
|
IMCOT
|
||||||
|
IMCSC
|
||||||
|
IMCSCH
|
||||||
|
IMSEC
|
||||||
|
IMSECH
|
||||||
|
IMSINH
|
||||||
|
IMTAN
|
||||||
|
ISFORMULA
|
||||||
|
ISOMITTED
|
||||||
|
ISOWEEKNUM
|
||||||
|
LAMBDA
|
||||||
|
LET
|
||||||
|
LOGNORM.DIST
|
||||||
|
LOGNORM.INV
|
||||||
|
MAKEARRAY
|
||||||
|
MAP
|
||||||
|
MODE.MULT
|
||||||
|
MODE.SNGL
|
||||||
|
MUNIT
|
||||||
|
NEGBINOM.DIST
|
||||||
|
NORM.DIST
|
||||||
|
NORM.INV
|
||||||
|
NORM.S.DIST
|
||||||
|
NORM.S.INV
|
||||||
|
NUMBERVALUE
|
||||||
|
PDURATION
|
||||||
|
PERCENTILE.EXC
|
||||||
|
PERCENTILE.INC
|
||||||
|
PERCENTRANK.EXC
|
||||||
|
PERCENTRANK.INC
|
||||||
|
PERMUTATIONA
|
||||||
|
PHI
|
||||||
|
POISSON.DIST
|
||||||
|
QUARTILE.EXC
|
||||||
|
QUARTILE.INC
|
||||||
|
QUERYSTRING
|
||||||
|
RANDARRAY
|
||||||
|
RANK.AVG
|
||||||
|
RANK.EQ
|
||||||
|
REDUCE
|
||||||
|
RRI
|
||||||
|
SCAN
|
||||||
|
SEC
|
||||||
|
SECH
|
||||||
|
SEQUENCE
|
||||||
|
SHEET
|
||||||
|
SHEETS
|
||||||
|
SKEW.P
|
||||||
|
SORTBY
|
||||||
|
STDEV.P
|
||||||
|
STDEV.S
|
||||||
|
T.DIST
|
||||||
|
T.DIST.2T
|
||||||
|
T.DIST.RT
|
||||||
|
T.INV
|
||||||
|
T.INV.2T
|
||||||
|
T.TEST
|
||||||
|
UNICHAR
|
||||||
|
UNICODE
|
||||||
|
UNIQUE
|
||||||
|
VAR.P
|
||||||
|
VAR.S
|
||||||
|
WEBSERVICE
|
||||||
|
WEIBULL.DIST
|
||||||
|
XLOOKUP
|
||||||
|
XOR
|
||||||
|
Z.TEST
|
||||||
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
#### Row and Column Properties
|
#### Row and Column Properties
|
||||||
|
@ -129,6 +129,7 @@ function wb_fmt() {
|
|||||||
seen = true;
|
seen = true;
|
||||||
opts.cellFormula = true;
|
opts.cellFormula = true;
|
||||||
opts.cellNF = true;
|
opts.cellNF = true;
|
||||||
|
opts.xlfn = true;
|
||||||
if(program.output) sheetname = program.output;
|
if(program.output) sheetname = program.output;
|
||||||
}
|
}
|
||||||
function isfmt(m/*:string*/)/*:boolean*/ {
|
function isfmt(m/*:string*/)/*:boolean*/ {
|
||||||
|
@ -1 +1 @@
|
|||||||
XLSX.version = '0.18.2';
|
XLSX.version = '0.18.3';
|
||||||
|
@ -13,7 +13,7 @@ function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
|
|||||||
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
||||||
if(typeof Deno !== 'undefined') {
|
if(typeof Deno !== 'undefined') {
|
||||||
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
||||||
if(enc) switch(enc) {
|
if(enc && typeof payload == "string") switch(enc) {
|
||||||
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
||||||
case "binary": payload = s2ab(payload); break;
|
case "binary": payload = s2ab(payload); break;
|
||||||
/* TODO: binary equivalent */
|
/* TODO: binary equivalent */
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
function parse_Int32LE(data) {
|
||||||
|
return data.read_shift(4, 'i');
|
||||||
|
}
|
||||||
function write_UInt32LE(x/*:number*/, o) {
|
function write_UInt32LE(x/*:number*/, o) {
|
||||||
if (!o) o = new_buf(4);
|
if (!o) o = new_buf(4);
|
||||||
o.write_shift(4, x);
|
o.write_shift(4, x);
|
||||||
|
@ -61,8 +61,8 @@ var ct2type/*{[string]:string}*/ = ({
|
|||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
||||||
|
|
||||||
/* Metadata */
|
/* Metadata */
|
||||||
"application/vnd.ms-excel.sheetMetadata": "TODO",
|
"application/vnd.ms-excel.sheetMetadata": "metadata",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "TODO",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "metadata",
|
||||||
|
|
||||||
/* PivotCache */
|
/* PivotCache */
|
||||||
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
||||||
@ -179,6 +179,10 @@ var CT_LIST = (function(){
|
|||||||
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
||||||
xlsb: "application/vnd.ms-excel.macrosheet"
|
xlsb: "application/vnd.ms-excel.macrosheet"
|
||||||
},
|
},
|
||||||
|
metadata: { /* Metadata (Stock/Geography and Dynamic Array) */
|
||||||
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
|
||||||
|
xlsb: "application/vnd.ms-excel.sheetMetadata"
|
||||||
|
},
|
||||||
styles: { /* Styles */
|
styles: { /* Styles */
|
||||||
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
||||||
xlsb: "application/vnd.ms-excel.styles"
|
xlsb: "application/vnd.ms-excel.styles"
|
||||||
@ -198,7 +202,7 @@ function new_ct()/*:any*/ {
|
|||||||
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
||||||
rels:[], strs:[], comments:[], links:[],
|
rels:[], strs:[], comments:[], links:[],
|
||||||
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
||||||
calcchains:[], vba: [], drawings: [],
|
calcchains:[], vba: [], drawings: [], metadata: [],
|
||||||
TODO:[], xmlns: "" }/*:any*/);
|
TODO:[], xmlns: "" }/*:any*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,6 +301,7 @@ function write_ct(ct, opts)/*:string*/ {
|
|||||||
f3('vba');
|
f3('vba');
|
||||||
f3('comments');
|
f3('comments');
|
||||||
f3('drawings');
|
f3('drawings');
|
||||||
|
f2('metadata');
|
||||||
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
||||||
return o.join("");
|
return o.join("");
|
||||||
}
|
}
|
||||||
|
151
bits/51_xlmeta.js
Normal file
151
bits/51_xlmeta.js
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
function parse_xlmeta_xml(data, name, opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
if (!data)
|
||||||
|
return out;
|
||||||
|
var pass = false;
|
||||||
|
data.replace(tagregex, function(x, idx) {
|
||||||
|
var y = parsexmltag(x);
|
||||||
|
switch (strip_ns(y[0])) {
|
||||||
|
case "<?xml":
|
||||||
|
break;
|
||||||
|
case "<metadata":
|
||||||
|
case "</metadata>":
|
||||||
|
break;
|
||||||
|
case "<metadataTypes":
|
||||||
|
case "</metadataTypes>":
|
||||||
|
break;
|
||||||
|
case "<metadataType":
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
case "<futureMetadata":
|
||||||
|
break;
|
||||||
|
case "</futureMetadata>":
|
||||||
|
break;
|
||||||
|
case "<bk>":
|
||||||
|
break;
|
||||||
|
case "</bk>":
|
||||||
|
break;
|
||||||
|
case "<rc":
|
||||||
|
break;
|
||||||
|
case "</rc>":
|
||||||
|
break;
|
||||||
|
case "<cellMetadata":
|
||||||
|
case "</cellMetadata>":
|
||||||
|
break;
|
||||||
|
case "<valueMetadata":
|
||||||
|
break;
|
||||||
|
case "</valueMetadata>":
|
||||||
|
break;
|
||||||
|
case "<extLst":
|
||||||
|
case "<extLst>":
|
||||||
|
case "</extLst>":
|
||||||
|
case "<extLst/>":
|
||||||
|
break;
|
||||||
|
case "<ext":
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case "</ext>":
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!pass && opts.WTF)
|
||||||
|
throw new Error("unrecognized " + y[0] + " in metadata");
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_xml() {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
|
||||||
|
return o.join("");
|
||||||
|
}
|
||||||
|
function parse_BrtMdtinfo(data, length) {
|
||||||
|
return {
|
||||||
|
flags: data.read_shift(4),
|
||||||
|
version: data.read_shift(4),
|
||||||
|
name: parse_XLWideString(data, length - 8)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function write_BrtMdtinfo(data) {
|
||||||
|
var o = new_buf(12 + 2 * data.name.length);
|
||||||
|
o.write_shift(4, data.flags);
|
||||||
|
o.write_shift(4, data.version);
|
||||||
|
write_XLWideString(data.name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtMdb(mdb) {
|
||||||
|
var o = new_buf(4 + 8 * mdb.length);
|
||||||
|
o.write_shift(4, mdb.length);
|
||||||
|
for (var i = 0; i < mdb.length; ++i) {
|
||||||
|
o.write_shift(4, mdb[i][0]);
|
||||||
|
o.write_shift(4, mdb[i][1]);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsfmd(cnt, name) {
|
||||||
|
var o = new_buf(8 + 2 * name.length);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
write_XLWideString(name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsmdb(cnt, cm) {
|
||||||
|
var o = new_buf(8);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
o.write_shift(4, cm ? 1 : 0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function parse_xlmeta_bin(data, name, _opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
var opts = _opts || {};
|
||||||
|
var state = [];
|
||||||
|
var pass = false;
|
||||||
|
recordhopper(data, function(val, R_n, RT) {
|
||||||
|
switch (RT) {
|
||||||
|
case 335:
|
||||||
|
out.Types.push({ name: val.name });
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.push(R_n);
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.pop();
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((R_n || "").indexOf("Begin") > 0) {
|
||||||
|
} else if ((R_n || "").indexOf("End") > 0) {
|
||||||
|
} else if (!pass || opts.WTF && state[state.length - 1] != "BrtFRTBegin")
|
||||||
|
throw new Error("Unexpected record " + RT + " " + R_n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_bin() {
|
||||||
|
var ba = buf_array();
|
||||||
|
write_record(ba, "BrtBeginMetadata");
|
||||||
|
write_record(ba, "BrtBeginEsmdtinfo", write_UInt32LE(1));
|
||||||
|
write_record(ba, "BrtMdtinfo", write_BrtMdtinfo({
|
||||||
|
name: "XLDAPR",
|
||||||
|
version: 12e4,
|
||||||
|
flags: 3496657072
|
||||||
|
}));
|
||||||
|
write_record(ba, "BrtEndEsmdtinfo");
|
||||||
|
write_record(ba, "BrtBeginEsfmd", write_BrtBeginEsfmd(1, "XLDAPR"));
|
||||||
|
write_record(ba, "BrtBeginFmd");
|
||||||
|
write_record(ba, "BrtFRTBegin", write_UInt32LE(514));
|
||||||
|
write_record(ba, "BrtBeginDynamicArrayPr", write_UInt32LE(0));
|
||||||
|
write_record(ba, "BrtEndDynamicArrayPr", writeuint16(1));
|
||||||
|
write_record(ba, "BrtFRTEnd");
|
||||||
|
write_record(ba, "BrtEndFmd");
|
||||||
|
write_record(ba, "BrtEndEsfmd");
|
||||||
|
write_record(ba, "BrtBeginEsmdb", write_BrtBeginEsmdb(1, true));
|
||||||
|
write_record(ba, "BrtMdb", write_BrtMdb([[1, 0]]));
|
||||||
|
write_record(ba, "BrtEndEsmdb");
|
||||||
|
write_record(ba, "BrtEndMetadata");
|
||||||
|
return ba.end();
|
||||||
|
}
|
@ -870,7 +870,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
|||||||
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
||||||
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
||||||
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
||||||
if(name && name.slice(0,6) == "_xlfn.") name = name.slice(6);
|
if(name && name.slice(0,6) == "_xlfn." && !opts.xlfn) name = name.slice(6);
|
||||||
stack.push(name);
|
stack.push(name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -300,6 +300,7 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string
|
|||||||
}
|
}
|
||||||
if(cell.l) ws['!links'].push([ref, cell.l]);
|
if(cell.l) ws['!links'].push([ref, cell.l]);
|
||||||
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
||||||
|
if(cell.D) o.cm = 1;
|
||||||
return writextag('c', v, o);
|
return writextag('c', v, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,6 +477,10 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||||||
}
|
}
|
||||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
safe_format(p, fmtid, fillid, opts, themes, styles);
|
||||||
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
||||||
|
if(tag.cm && opts.xlmeta) {
|
||||||
|
var cm = (opts.xlmeta.Types||[])[+tag.cm-1];
|
||||||
|
if(cm && cm.name == 'XLDAPR') p.D = true;
|
||||||
|
}
|
||||||
if(dense) {
|
if(dense) {
|
||||||
var _r = decode_cell(tag.r);
|
var _r = decode_cell(tag.r);
|
||||||
if(!s[_r.r]) s[_r.r] = [];
|
if(!s[_r.r]) s[_r.r] = [];
|
||||||
|
@ -538,6 +538,8 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
|
|
||||||
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
||||||
|
|
||||||
|
var cm, vm;
|
||||||
|
|
||||||
recordhopper(data, function ws_parse(val, R_n, RT) {
|
recordhopper(data, function ws_parse(val, R_n, RT) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
switch(RT) {
|
switch(RT) {
|
||||||
@ -595,6 +597,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
}
|
}
|
||||||
if(!af && val.length > 3) p.f = val[3];
|
if(!af && val.length > 3) p.f = val[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
@ -602,12 +605,17 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
||||||
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
||||||
}
|
}
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0001: /* 'BrtCellBlank' */
|
case 0x0001: /* 'BrtCellBlank' */
|
||||||
case 0x000C: /* 'BrtShortBlank' */
|
case 0x000C: /* 'BrtShortBlank' */
|
||||||
if(!opts.sheetStubs || pass) break;
|
if(!opts.sheetStubs || pass) break;
|
||||||
p = ({t:'z',v:undefined}/*:any*/);
|
p = ({t:'z',v:void 0}/*:any*/);
|
||||||
C = val[0].c == -1 ? C + 1 : val[0].c;
|
C = val[0].c == -1 ? C + 1 : val[0].c;
|
||||||
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
||||||
else s[encode_col(C) + rr] = p;
|
else s[encode_col(C) + rr] = p;
|
||||||
@ -615,11 +623,20 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
if(refguess.e.c < C) refguess.e.c = C;
|
if(refguess.e.c < C) refguess.e.c = C;
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x00B0: /* 'BrtMergeCell' */
|
case 0x00B0: /* 'BrtMergeCell' */
|
||||||
merges.push(val); break;
|
merges.push(val); break;
|
||||||
|
|
||||||
|
case 0x0031: { /* 'BrtCellMeta' */
|
||||||
|
cm = ((opts.xlmeta||{}).Types||[])[val-1];
|
||||||
|
} break;
|
||||||
|
|
||||||
case 0x01EE: /* 'BrtHLink' */
|
case 0x01EE: /* 'BrtHLink' */
|
||||||
var rel = rels['!id'][val.relId];
|
var rel = rels['!id'][val.relId];
|
||||||
if(rel) {
|
if(rel) {
|
||||||
@ -707,7 +724,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
case 0x041A: /* 'BrtCFVO14' */
|
case 0x041A: /* 'BrtCFVO14' */
|
||||||
case 0x0289: /* 'BrtCellIgnoreEC' */
|
case 0x0289: /* 'BrtCellIgnoreEC' */
|
||||||
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
||||||
case 0x0031: /* 'BrtCellMeta' */
|
|
||||||
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
||||||
case 0x025F: /* 'BrtCellWatch' */
|
case 0x025F: /* 'BrtCellWatch' */
|
||||||
case 0x0234: /* 'BrtColor' */
|
case 0x0234: /* 'BrtColor' */
|
||||||
|
@ -52,6 +52,11 @@ function parse_xlink(data, rel, name/*:string*/, opts) {
|
|||||||
return parse_xlink_xml((data/*:any*/), rel, name, opts);
|
return parse_xlink_xml((data/*:any*/), rel, name, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_xlmeta(data, name/*:string*/, opts) {
|
||||||
|
if(name.slice(-4)===".bin") return parse_xlmeta_bin((data/*:any*/), name, opts);
|
||||||
|
return parse_xlmeta_xml((data/*:any*/), name, opts);
|
||||||
|
}
|
||||||
|
|
||||||
function write_wb(wb, name/*:string*/, opts) {
|
function write_wb(wb, name/*:string*/, opts) {
|
||||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||||
}
|
}
|
||||||
@ -81,3 +86,7 @@ function write_cc(data, name:string, opts) {
|
|||||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function write_xlmeta(name/*:string*/) {
|
||||||
|
return (name.slice(-4)===".bin" ? write_xlmeta_bin : write_xlmeta_xml)();
|
||||||
|
}
|
||||||
|
@ -48,7 +48,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parse_BrtBorder },
|
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parse_BrtBorder },
|
||||||
/*::[*/0x002F/*::]*/: { n:"BrtXF", f:parse_BrtXF },
|
/*::[*/0x002F/*::]*/: { n:"BrtXF", f:parse_BrtXF },
|
||||||
/*::[*/0x0030/*::]*/: { n:"BrtStyle" },
|
/*::[*/0x0030/*::]*/: { n:"BrtStyle" },
|
||||||
/*::[*/0x0031/*::]*/: { n:"BrtCellMeta" },
|
/*::[*/0x0031/*::]*/: { n:"BrtCellMeta", f:parse_Int32LE },
|
||||||
/*::[*/0x0032/*::]*/: { n:"BrtValueMeta" },
|
/*::[*/0x0032/*::]*/: { n:"BrtValueMeta" },
|
||||||
/*::[*/0x0033/*::]*/: { n:"BrtMdb" },
|
/*::[*/0x0033/*::]*/: { n:"BrtMdb" },
|
||||||
/*::[*/0x0034/*::]*/: { n:"BrtBeginFmd" },
|
/*::[*/0x0034/*::]*/: { n:"BrtBeginFmd" },
|
||||||
@ -274,7 +274,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x014C/*::]*/: { n:"BrtBeginMetadata" },
|
/*::[*/0x014C/*::]*/: { n:"BrtBeginMetadata" },
|
||||||
/*::[*/0x014D/*::]*/: { n:"BrtEndMetadata" },
|
/*::[*/0x014D/*::]*/: { n:"BrtEndMetadata" },
|
||||||
/*::[*/0x014E/*::]*/: { n:"BrtBeginEsmdtinfo" },
|
/*::[*/0x014E/*::]*/: { n:"BrtBeginEsmdtinfo" },
|
||||||
/*::[*/0x014F/*::]*/: { n:"BrtMdtinfo" },
|
/*::[*/0x014F/*::]*/: { n:"BrtMdtinfo", f:parse_BrtMdtinfo },
|
||||||
/*::[*/0x0150/*::]*/: { n:"BrtEndEsmdtinfo" },
|
/*::[*/0x0150/*::]*/: { n:"BrtEndEsmdtinfo" },
|
||||||
/*::[*/0x0151/*::]*/: { n:"BrtBeginEsmdb" },
|
/*::[*/0x0151/*::]*/: { n:"BrtBeginEsmdb" },
|
||||||
/*::[*/0x0152/*::]*/: { n:"BrtEndEsmdb" },
|
/*::[*/0x0152/*::]*/: { n:"BrtEndEsmdb" },
|
||||||
@ -795,7 +795,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x0835/*::]*/: { n:"BrtEndTimelineStyleElements" },
|
/*::[*/0x0835/*::]*/: { n:"BrtEndTimelineStyleElements" },
|
||||||
/*::[*/0x0836/*::]*/: { n:"BrtDxf15" },
|
/*::[*/0x0836/*::]*/: { n:"BrtDxf15" },
|
||||||
/*::[*/0x0837/*::]*/: { n:"BrtBeginDxfs15" },
|
/*::[*/0x0837/*::]*/: { n:"BrtBeginDxfs15" },
|
||||||
/*::[*/0x0838/*::]*/: { n:"brtEndDxfs15" },
|
/*::[*/0x0838/*::]*/: { n:"BrtEndDxfs15" },
|
||||||
/*::[*/0x0839/*::]*/: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
/*::[*/0x0839/*::]*/: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
||||||
/*::[*/0x083A/*::]*/: { n:"BrtBeginItemUniqueNames" },
|
/*::[*/0x083A/*::]*/: { n:"BrtBeginItemUniqueNames" },
|
||||||
/*::[*/0x083B/*::]*/: { n:"BrtEndItemUniqueNames" },
|
/*::[*/0x083B/*::]*/: { n:"BrtEndItemUniqueNames" },
|
||||||
@ -835,9 +835,27 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x085D/*::]*/: { n:"BrtModelTimeGroupingCalcCol" },
|
/*::[*/0x085D/*::]*/: { n:"BrtModelTimeGroupingCalcCol" },
|
||||||
/*::[*/0x0C00/*::]*/: { n:"BrtUid" },
|
/*::[*/0x0C00/*::]*/: { n:"BrtUid" },
|
||||||
/*::[*/0x0C01/*::]*/: { n:"BrtRevisionPtr" },
|
/*::[*/0x0C01/*::]*/: { n:"BrtRevisionPtr" },
|
||||||
/*::[*/0x13e7/*::]*/: { n:"BrtBeginCalcFeatures" },
|
/*::[*/0x1000/*::]*/: { n:"BrtBeginDynamicArrayPr" },
|
||||||
/*::[*/0x13e8/*::]*/: { n:"BrtEndCalcFeatures" },
|
/*::[*/0x1001/*::]*/: { n:"BrtEndDynamicArrayPr" },
|
||||||
/*::[*/0x13e9/*::]*/: { n:"BrtCalcFeature" },
|
/*::[*/0x138A/*::]*/: { n:"BrtBeginRichValueBlock" },
|
||||||
|
/*::[*/0x138B/*::]*/: { n:"BrtEndRichValueBlock" },
|
||||||
|
/*::[*/0x13D9/*::]*/: { n:"BrtBeginRichFilters" },
|
||||||
|
/*::[*/0x13DA/*::]*/: { n:"BrtEndRichFilters" },
|
||||||
|
/*::[*/0x13DB/*::]*/: { n:"BrtRichFilter" },
|
||||||
|
/*::[*/0x13DC/*::]*/: { n:"BrtBeginRichFilterColumn" },
|
||||||
|
/*::[*/0x13DD/*::]*/: { n:"BrtEndRichFilterColumn" },
|
||||||
|
/*::[*/0x13DE/*::]*/: { n:"BrtBeginCustomRichFilters" },
|
||||||
|
/*::[*/0x13DF/*::]*/: { n:"BrtEndCustomRichFilters" },
|
||||||
|
/*::[*/0x13E0/*::]*/: { n:"BrtCustomRichFilter" },
|
||||||
|
/*::[*/0x13E1/*::]*/: { n:"BrtTop10RichFilter" },
|
||||||
|
/*::[*/0x13E2/*::]*/: { n:"BrtDynamicRichFilter" },
|
||||||
|
/*::[*/0x13E4/*::]*/: { n:"BrtBeginRichSortCondition" },
|
||||||
|
/*::[*/0x13E5/*::]*/: { n:"BrtEndRichSortCondition" },
|
||||||
|
/*::[*/0x13E6/*::]*/: { n:"BrtRichFilterDateGroupItem" },
|
||||||
|
/*::[*/0x13E7/*::]*/: { n:"BrtBeginCalcFeatures" },
|
||||||
|
/*::[*/0x13E8/*::]*/: { n:"BrtEndCalcFeatures" },
|
||||||
|
/*::[*/0x13E9/*::]*/: { n:"BrtCalcFeature" },
|
||||||
|
/*::[*/0x13EB/*::]*/: { n:"BrtExternalLinksPr" },
|
||||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,9 +161,16 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
|||||||
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
||||||
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
||||||
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
||||||
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile);
|
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile.replace(/_rels.*/, "s5s"));
|
||||||
|
|
||||||
|
if((dir.metadata || []).length >= 1) {
|
||||||
|
/* TODO: MDX and other types of metadata */
|
||||||
|
opts.xlmeta = parse_xlmeta(getzipdata(zip, strip_front_slash(dir.metadata[0])),dir.metadata[0],opts);
|
||||||
|
}
|
||||||
|
|
||||||
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
||||||
|
|
||||||
|
|
||||||
/* Numbers iOS hack */
|
/* Numbers iOS hack */
|
||||||
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
||||||
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
||||||
|
@ -124,6 +124,11 @@ function write_zip_xlsxb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta(f));
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -132,7 +137,7 @@ function write_zip_xlsxb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
return zip;
|
return zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this version does not reference XLSB write functions */
|
||||||
function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||||
_shapeid = 1024;
|
_shapeid = 1024;
|
||||||
if(wb && !wb.SSF) {
|
if(wb && !wb.SSF) {
|
||||||
@ -254,6 +259,11 @@ function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta_xml());
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
|
@ -45,14 +45,15 @@ function write_zip_typeXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
|
|||||||
}
|
}
|
||||||
function write_zip_denouement(z/*:any*/, o/*:?WriteOpts*/)/*:any*/ {
|
function write_zip_denouement(z/*:any*/, o/*:?WriteOpts*/)/*:any*/ {
|
||||||
var oopts = {};
|
var oopts = {};
|
||||||
|
var ftype = has_buf ? "nodebuffer" : (typeof Uint8Array !== "undefined" ? "array" : "string");
|
||||||
if(o.compression) oopts.compression = 'DEFLATE';
|
if(o.compression) oopts.compression = 'DEFLATE';
|
||||||
if(o.password) oopts.type = has_buf ? "nodebuffer" : "string";
|
if(o.password) oopts.type = ftype;
|
||||||
else switch(o.type) {
|
else switch(o.type) {
|
||||||
case "base64": oopts.type = "base64"; break;
|
case "base64": oopts.type = "base64"; break;
|
||||||
case "binary": oopts.type = "string"; break;
|
case "binary": oopts.type = "string"; break;
|
||||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
||||||
case "buffer":
|
case "buffer":
|
||||||
case "file": oopts.type = has_buf ? "nodebuffer" : "string"; break;
|
case "file": oopts.type = ftype; break;
|
||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
||||||
|
@ -98,7 +98,7 @@ utils.cell_add_comment = function(cell/*:Cell*/, text/*:string*/, author/*:?stri
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* set array formula and flush related cells */
|
/* set array formula and flush related cells */
|
||||||
utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:string*/) {
|
utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:string*/, dynamic/*:boolean*/) {
|
||||||
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
||||||
var rngstr = typeof range == "string" ? range : encode_range(range);
|
var rngstr = typeof range == "string" ? range : encode_range(range);
|
||||||
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
||||||
@ -106,7 +106,10 @@ utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:stri
|
|||||||
cell.t = 'n';
|
cell.t = 'n';
|
||||||
cell.F = rngstr;
|
cell.F = rngstr;
|
||||||
delete cell.v;
|
delete cell.v;
|
||||||
if(R == rng.s.r && C == rng.s.c) cell.f = formula;
|
if(R == rng.s.r && C == rng.s.c) {
|
||||||
|
cell.f = formula;
|
||||||
|
if(dynamic) cell.D = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ws;
|
return ws;
|
||||||
};
|
};
|
||||||
|
@ -169,8 +169,8 @@ curl -X GET http://localhost:7262/?f=sheetjs.xlsb
|
|||||||
|
|
||||||
[NestJS](https://nestjs.com/) is a Node.js framework for server-side web applications.
|
[NestJS](https://nestjs.com/) is a Node.js framework for server-side web applications.
|
||||||
|
|
||||||
This demo uses SheetJS to injest a spreadsheet via a POST API endpoint. The file
|
This demo uses SheetJS to parse a spreadsheet via a POST API endpoint. The file
|
||||||
arrive to the endpoint as body `form-data`, accessible using the `file` key.
|
arrives to the endpoint as body `form-data`, accessible using the `file` key.
|
||||||
After parsing the file, CSV contents of the first worksheet will be returned.
|
After parsing the file, CSV contents of the first worksheet will be returned.
|
||||||
[Body parsing uses `multer`](https://docs.nestjs.com/techniques/file-upload).
|
[Body parsing uses `multer`](https://docs.nestjs.com/techniques/file-upload).
|
||||||
|
|
||||||
|
30
dist/xlsx.core.min.js
generated
vendored
30
dist/xlsx.core.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.core.min.map
generated
vendored
2
dist/xlsx.core.min.map
generated
vendored
File diff suppressed because one or more lines are too long
322
dist/xlsx.extendscript.js
generated
vendored
322
dist/xlsx.extendscript.js
generated
vendored
@ -160,7 +160,7 @@ var DO_NOT_EXPORT_CODEPAGE = true;
|
|||||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||||
var XLSX = {};
|
var XLSX = {};
|
||||||
function make_xlsx_lib(XLSX){
|
function make_xlsx_lib(XLSX){
|
||||||
XLSX.version = '0.18.2';
|
XLSX.version = '0.18.3';
|
||||||
var current_codepage = 1200, current_ansi = 1252;
|
var current_codepage = 1200, current_ansi = 1252;
|
||||||
/*global cptable:true, window */
|
/*global cptable:true, window */
|
||||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||||
@ -288,7 +288,7 @@ var Base64 = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
var has_buf = (typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && !!process.versions.node);
|
var has_buf = (typeof Buffer !== 'undefined' && typeof undefined !== 'undefined' && typeof ({}) !== 'undefined' && !!({}).node);
|
||||||
|
|
||||||
var Buffer_from = function(){};
|
var Buffer_from = function(){};
|
||||||
|
|
||||||
@ -1640,7 +1640,7 @@ function parse_extra_field(blob) {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
var fs;
|
var fs;
|
||||||
function get_fs() { return fs || (fs = require('fs')); }
|
function get_fs() { return fs || (fs = undefined); }
|
||||||
function parse(file, options) {
|
function parse(file, options) {
|
||||||
if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options);
|
if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options);
|
||||||
if((file[0] | 0x20) == 0x6d && (file[1]|0x20) == 0x69) return parse_mad(file, options);
|
if((file[0] | 0x20) == 0x6d && (file[1]|0x20) == 0x69) return parse_mad(file, options);
|
||||||
@ -3256,7 +3256,7 @@ return exports;
|
|||||||
|
|
||||||
if(typeof require !== 'undefined' && typeof module !== 'undefined' && typeof DO_NOT_EXPORT_CFB === 'undefined') { module.exports = CFB; }
|
if(typeof require !== 'undefined' && typeof module !== 'undefined' && typeof DO_NOT_EXPORT_CFB === 'undefined') { module.exports = CFB; }
|
||||||
var _fs;
|
var _fs;
|
||||||
if(typeof require !== 'undefined') try { _fs = require('fs'); } catch(e) {}
|
if(typeof require !== 'undefined') try { _fs = undefined; } catch(e) {}
|
||||||
|
|
||||||
/* normalize data for blob ctor */
|
/* normalize data for blob ctor */
|
||||||
function blobify(data) {
|
function blobify(data) {
|
||||||
@ -3270,7 +3270,7 @@ function write_dl(fname, payload, enc) {
|
|||||||
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
||||||
if(typeof Deno !== 'undefined') {
|
if(typeof Deno !== 'undefined') {
|
||||||
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
||||||
if(enc) switch(enc) {
|
if(enc && typeof payload == "string") switch(enc) {
|
||||||
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
||||||
case "binary": payload = s2ab(payload); break;
|
case "binary": payload = s2ab(payload); break;
|
||||||
/* TODO: binary equivalent */
|
/* TODO: binary equivalent */
|
||||||
@ -4213,43 +4213,6 @@ function encode_range_xls(r, opts) {
|
|||||||
}
|
}
|
||||||
return encode_cell_xls(r.s, opts.biff) + ":" + encode_cell_xls(r.e, opts.biff);
|
return encode_cell_xls(r.s, opts.biff) + ":" + encode_cell_xls(r.e, opts.biff);
|
||||||
}
|
}
|
||||||
var OFFCRYPTO = {};
|
|
||||||
|
|
||||||
var make_offcrypto = function(O, _crypto) {
|
|
||||||
var crypto;
|
|
||||||
if(typeof _crypto !== 'undefined') crypto = _crypto;
|
|
||||||
else if(typeof require !== 'undefined') {
|
|
||||||
try { crypto = undefined; }
|
|
||||||
catch(e) { crypto = null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
O.rc4 = function(key, data) {
|
|
||||||
var S = new Array(256);
|
|
||||||
var c = 0, i = 0, j = 0, t = 0;
|
|
||||||
for(i = 0; i != 256; ++i) S[i] = i;
|
|
||||||
for(i = 0; i != 256; ++i) {
|
|
||||||
j = (j + S[i] + (key[i%key.length]).charCodeAt(0))&255;
|
|
||||||
t = S[i]; S[i] = S[j]; S[j] = t;
|
|
||||||
}
|
|
||||||
// $FlowIgnore
|
|
||||||
i = j = 0; var out = new_raw_buf(data.length);
|
|
||||||
for(c = 0; c != data.length; ++c) {
|
|
||||||
i = (i + 1)&255;
|
|
||||||
j = (j + S[i])%256;
|
|
||||||
t = S[i]; S[i] = S[j]; S[j] = t;
|
|
||||||
out[c] = (data[c] ^ S[(S[i]+S[j])&255]);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
O.md5 = function(hex) {
|
|
||||||
if(!crypto) throw new Error("Unsupported crypto");
|
|
||||||
return crypto.createHash('md5').update(hex).digest('hex');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/*global crypto:true */
|
|
||||||
make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined);
|
|
||||||
|
|
||||||
function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; }
|
function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; }
|
||||||
function encode_row(row) { return "" + (row + 1); }
|
function encode_row(row) { return "" + (row + 1); }
|
||||||
function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
|
function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
|
||||||
@ -4414,6 +4377,9 @@ function sheet_add_aoa(_ws, data, opts) {
|
|||||||
}
|
}
|
||||||
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
|
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
|
||||||
|
|
||||||
|
function parse_Int32LE(data) {
|
||||||
|
return data.read_shift(4, 'i');
|
||||||
|
}
|
||||||
function write_UInt32LE(x, o) {
|
function write_UInt32LE(x, o) {
|
||||||
if (!o) o = new_buf(4);
|
if (!o) o = new_buf(4);
|
||||||
o.write_shift(4, x);
|
o.write_shift(4, x);
|
||||||
@ -5079,8 +5045,8 @@ var ct2type/*{[string]:string}*/ = ({
|
|||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
||||||
|
|
||||||
/* Metadata */
|
/* Metadata */
|
||||||
"application/vnd.ms-excel.sheetMetadata": "TODO",
|
"application/vnd.ms-excel.sheetMetadata": "metadata",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "TODO",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "metadata",
|
||||||
|
|
||||||
/* PivotCache */
|
/* PivotCache */
|
||||||
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
||||||
@ -5197,6 +5163,10 @@ var CT_LIST = (function(){
|
|||||||
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
||||||
xlsb: "application/vnd.ms-excel.macrosheet"
|
xlsb: "application/vnd.ms-excel.macrosheet"
|
||||||
},
|
},
|
||||||
|
metadata: { /* Metadata (Stock/Geography and Dynamic Array) */
|
||||||
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
|
||||||
|
xlsb: "application/vnd.ms-excel.sheetMetadata"
|
||||||
|
},
|
||||||
styles: { /* Styles */
|
styles: { /* Styles */
|
||||||
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
||||||
xlsb: "application/vnd.ms-excel.styles"
|
xlsb: "application/vnd.ms-excel.styles"
|
||||||
@ -5216,7 +5186,7 @@ function new_ct() {
|
|||||||
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
||||||
rels:[], strs:[], comments:[], links:[],
|
rels:[], strs:[], comments:[], links:[],
|
||||||
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
||||||
calcchains:[], vba: [], drawings: [],
|
calcchains:[], vba: [], drawings: [], metadata: [],
|
||||||
TODO:[], xmlns: "" });
|
TODO:[], xmlns: "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5315,6 +5285,7 @@ function write_ct(ct, opts) {
|
|||||||
f3('vba');
|
f3('vba');
|
||||||
f3('comments');
|
f3('comments');
|
||||||
f3('drawings');
|
f3('drawings');
|
||||||
|
f2('metadata');
|
||||||
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
||||||
return o.join("");
|
return o.join("");
|
||||||
}
|
}
|
||||||
@ -5381,7 +5352,9 @@ var RELS_EXTERN = [RELS.HLINK, RELS.XPATH, RELS.XMISS];
|
|||||||
function add_rels(rels, rId, f, type, relobj, targetmode) {
|
function add_rels(rels, rId, f, type, relobj, targetmode) {
|
||||||
if(!relobj) relobj = {};
|
if(!relobj) relobj = {};
|
||||||
if(!rels['!id']) rels['!id'] = {};
|
if(!rels['!id']) rels['!id'] = {};
|
||||||
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
if(!rels['!idx']) rels['!idx'] = 1;
|
||||||
|
if(rId < 0) for(rId = rels['!idx']; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
||||||
|
rels['!idx'] = rId + 1;
|
||||||
relobj.Id = 'rId' + rId;
|
relobj.Id = 'rId' + rId;
|
||||||
relobj.Type = type;
|
relobj.Type = type;
|
||||||
relobj.Target = f;
|
relobj.Target = f;
|
||||||
@ -11365,6 +11338,157 @@ function update_xfext(xf, xfext) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
function parse_xlmeta_xml(data, name, opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
if (!data)
|
||||||
|
return out;
|
||||||
|
var pass = false;
|
||||||
|
data.replace(tagregex, function(x, idx) {
|
||||||
|
var y = parsexmltag(x);
|
||||||
|
switch (strip_ns(y[0])) {
|
||||||
|
case "<?xml":
|
||||||
|
break;
|
||||||
|
case "<metadata":
|
||||||
|
case "</metadata>":
|
||||||
|
break;
|
||||||
|
case "<metadataTypes":
|
||||||
|
case "</metadataTypes>":
|
||||||
|
break;
|
||||||
|
case "<metadataType":
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
case "<futureMetadata":
|
||||||
|
break;
|
||||||
|
case "</futureMetadata>":
|
||||||
|
break;
|
||||||
|
case "<bk>":
|
||||||
|
break;
|
||||||
|
case "</bk>":
|
||||||
|
break;
|
||||||
|
case "<rc":
|
||||||
|
break;
|
||||||
|
case "</rc>":
|
||||||
|
break;
|
||||||
|
case "<cellMetadata":
|
||||||
|
case "</cellMetadata>":
|
||||||
|
break;
|
||||||
|
case "<valueMetadata":
|
||||||
|
break;
|
||||||
|
case "</valueMetadata>":
|
||||||
|
break;
|
||||||
|
case "<extLst":
|
||||||
|
case "<extLst>":
|
||||||
|
case "</extLst>":
|
||||||
|
case "<extLst/>":
|
||||||
|
break;
|
||||||
|
case "<ext":
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case "</ext>":
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!pass && opts.WTF)
|
||||||
|
throw new Error("unrecognized " + y[0] + " in metadata");
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_xml() {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
|
||||||
|
return o.join("");
|
||||||
|
}
|
||||||
|
function parse_BrtMdtinfo(data, length) {
|
||||||
|
return {
|
||||||
|
flags: data.read_shift(4),
|
||||||
|
version: data.read_shift(4),
|
||||||
|
name: parse_XLWideString(data, length - 8)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function write_BrtMdtinfo(data) {
|
||||||
|
var o = new_buf(12 + 2 * data.name.length);
|
||||||
|
o.write_shift(4, data.flags);
|
||||||
|
o.write_shift(4, data.version);
|
||||||
|
write_XLWideString(data.name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtMdb(mdb) {
|
||||||
|
var o = new_buf(4 + 8 * mdb.length);
|
||||||
|
o.write_shift(4, mdb.length);
|
||||||
|
for (var i = 0; i < mdb.length; ++i) {
|
||||||
|
o.write_shift(4, mdb[i][0]);
|
||||||
|
o.write_shift(4, mdb[i][1]);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsfmd(cnt, name) {
|
||||||
|
var o = new_buf(8 + 2 * name.length);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
write_XLWideString(name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsmdb(cnt, cm) {
|
||||||
|
var o = new_buf(8);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
o.write_shift(4, cm ? 1 : 0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function parse_xlmeta_bin(data, name, _opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
var opts = _opts || {};
|
||||||
|
var state = [];
|
||||||
|
var pass = false;
|
||||||
|
recordhopper(data, function(val, R_n, RT) {
|
||||||
|
switch (RT) {
|
||||||
|
case 335:
|
||||||
|
out.Types.push({ name: val.name });
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.push(R_n);
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.pop();
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((R_n || "").indexOf("Begin") > 0) {
|
||||||
|
} else if ((R_n || "").indexOf("End") > 0) {
|
||||||
|
} else if (!pass || opts.WTF && state[state.length - 1] != "BrtFRTBegin")
|
||||||
|
throw new Error("Unexpected record " + RT + " " + R_n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_bin() {
|
||||||
|
var ba = buf_array();
|
||||||
|
write_record(ba, "BrtBeginMetadata");
|
||||||
|
write_record(ba, "BrtBeginEsmdtinfo", write_UInt32LE(1));
|
||||||
|
write_record(ba, "BrtMdtinfo", write_BrtMdtinfo({
|
||||||
|
name: "XLDAPR",
|
||||||
|
version: 12e4,
|
||||||
|
flags: 3496657072
|
||||||
|
}));
|
||||||
|
write_record(ba, "BrtEndEsmdtinfo");
|
||||||
|
write_record(ba, "BrtBeginEsfmd", write_BrtBeginEsfmd(1, "XLDAPR"));
|
||||||
|
write_record(ba, "BrtBeginFmd");
|
||||||
|
write_record(ba, "BrtFRTBegin", write_UInt32LE(514));
|
||||||
|
write_record(ba, "BrtBeginDynamicArrayPr", write_UInt32LE(0));
|
||||||
|
write_record(ba, "BrtEndDynamicArrayPr", writeuint16(1));
|
||||||
|
write_record(ba, "BrtFRTEnd");
|
||||||
|
write_record(ba, "BrtEndFmd");
|
||||||
|
write_record(ba, "BrtEndEsfmd");
|
||||||
|
write_record(ba, "BrtBeginEsmdb", write_BrtBeginEsmdb(1, true));
|
||||||
|
write_record(ba, "BrtMdb", write_BrtMdb([[1, 0]]));
|
||||||
|
write_record(ba, "BrtEndEsmdb");
|
||||||
|
write_record(ba, "BrtEndMetadata");
|
||||||
|
return ba.end();
|
||||||
|
}
|
||||||
/* 18.6 Calculation Chain */
|
/* 18.6 Calculation Chain */
|
||||||
function parse_cc_xml(data) {
|
function parse_cc_xml(data) {
|
||||||
var d = [];
|
var d = [];
|
||||||
@ -12690,7 +12814,7 @@ ixti = f[1][1]; r = f[1][2];
|
|||||||
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
||||||
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
||||||
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
||||||
if(name && name.slice(0,6) == "_xlfn.") name = name.slice(6);
|
if(name && name.slice(0,6) == "_xlfn." && !opts.xlfn) name = name.slice(6);
|
||||||
stack.push(name);
|
stack.push(name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -14588,6 +14712,7 @@ function write_ws_xml_cell(cell, ref, ws, opts) {
|
|||||||
}
|
}
|
||||||
if(cell.l) ws['!links'].push([ref, cell.l]);
|
if(cell.l) ws['!links'].push([ref, cell.l]);
|
||||||
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
||||||
|
if(cell.D) o.cm = 1;
|
||||||
return writextag('c', v, o);
|
return writextag('c', v, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14764,6 +14889,10 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||||||
}
|
}
|
||||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
safe_format(p, fmtid, fillid, opts, themes, styles);
|
||||||
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
||||||
|
if(tag.cm && opts.xlmeta) {
|
||||||
|
var cm = (opts.xlmeta.Types||[])[+tag.cm-1];
|
||||||
|
if(cm && cm.name == 'XLDAPR') p.D = true;
|
||||||
|
}
|
||||||
if(dense) {
|
if(dense) {
|
||||||
var _r = decode_cell(tag.r);
|
var _r = decode_cell(tag.r);
|
||||||
if(!s[_r.r]) s[_r.r] = [];
|
if(!s[_r.r]) s[_r.r] = [];
|
||||||
@ -14846,7 +14975,7 @@ function write_ws_xml(idx, opts, wb, rels) {
|
|||||||
|
|
||||||
o[o.length] = write_ws_xml_sheetviews(ws, opts, idx, wb);
|
o[o.length] = write_ws_xml_sheetviews(ws, opts, idx, wb);
|
||||||
|
|
||||||
/* TODO: store in WB, process styles */
|
/* TODO: store in WB, undefined styles */
|
||||||
if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {
|
if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {
|
||||||
defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16',
|
defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16',
|
||||||
baseColWidth:opts.sheetFormat.baseColWidth||'10',
|
baseColWidth:opts.sheetFormat.baseColWidth||'10',
|
||||||
@ -15477,6 +15606,8 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
|
|
||||||
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
||||||
|
|
||||||
|
var cm, vm;
|
||||||
|
|
||||||
recordhopper(data, function ws_parse(val, R_n, RT) {
|
recordhopper(data, function ws_parse(val, R_n, RT) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
switch(RT) {
|
switch(RT) {
|
||||||
@ -15534,6 +15665,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
}
|
}
|
||||||
if(!af && val.length > 3) p.f = val[3];
|
if(!af && val.length > 3) p.f = val[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
@ -15541,12 +15673,17 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
||||||
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
||||||
}
|
}
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0001: /* 'BrtCellBlank' */
|
case 0x0001: /* 'BrtCellBlank' */
|
||||||
case 0x000C: /* 'BrtShortBlank' */
|
case 0x000C: /* 'BrtShortBlank' */
|
||||||
if(!opts.sheetStubs || pass) break;
|
if(!opts.sheetStubs || pass) break;
|
||||||
p = ({t:'z',v:undefined});
|
p = ({t:'z',v:void 0});
|
||||||
C = val[0].c == -1 ? C + 1 : val[0].c;
|
C = val[0].c == -1 ? C + 1 : val[0].c;
|
||||||
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
||||||
else s[encode_col(C) + rr] = p;
|
else s[encode_col(C) + rr] = p;
|
||||||
@ -15554,11 +15691,20 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
if(refguess.e.c < C) refguess.e.c = C;
|
if(refguess.e.c < C) refguess.e.c = C;
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x00B0: /* 'BrtMergeCell' */
|
case 0x00B0: /* 'BrtMergeCell' */
|
||||||
merges.push(val); break;
|
merges.push(val); break;
|
||||||
|
|
||||||
|
case 0x0031: { /* 'BrtCellMeta' */
|
||||||
|
cm = ((opts.xlmeta||{}).Types||[])[val-1];
|
||||||
|
} break;
|
||||||
|
|
||||||
case 0x01EE: /* 'BrtHLink' */
|
case 0x01EE: /* 'BrtHLink' */
|
||||||
var rel = rels['!id'][val.relId];
|
var rel = rels['!id'][val.relId];
|
||||||
if(rel) {
|
if(rel) {
|
||||||
@ -15646,7 +15792,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
case 0x041A: /* 'BrtCFVO14' */
|
case 0x041A: /* 'BrtCFVO14' */
|
||||||
case 0x0289: /* 'BrtCellIgnoreEC' */
|
case 0x0289: /* 'BrtCellIgnoreEC' */
|
||||||
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
||||||
case 0x0031: /* 'BrtCellMeta' */
|
|
||||||
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
||||||
case 0x025F: /* 'BrtCellWatch' */
|
case 0x025F: /* 'BrtCellWatch' */
|
||||||
case 0x0234: /* 'BrtColor' */
|
case 0x0234: /* 'BrtColor' */
|
||||||
@ -16851,6 +16996,11 @@ function parse_xlink(data, rel, name, opts) {
|
|||||||
return parse_xlink_xml((data), rel, name, opts);
|
return parse_xlink_xml((data), rel, name, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_xlmeta(data, name, opts) {
|
||||||
|
if(name.slice(-4)===".bin") return parse_xlmeta_bin((data), name, opts);
|
||||||
|
return parse_xlmeta_xml((data), name, opts);
|
||||||
|
}
|
||||||
|
|
||||||
function write_wb(wb, name, opts) {
|
function write_wb(wb, name, opts) {
|
||||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||||
}
|
}
|
||||||
@ -16880,6 +17030,10 @@ function write_cc(data, name:string, opts) {
|
|||||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function write_xlmeta(name) {
|
||||||
|
return (name.slice(-4)===".bin" ? write_xlmeta_bin : write_xlmeta_xml)();
|
||||||
|
}
|
||||||
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||||
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
||||||
function xlml_parsexmltag(tag, skip_root) {
|
function xlml_parsexmltag(tag, skip_root) {
|
||||||
@ -18294,7 +18448,7 @@ function parse_workbook(blob, options) {
|
|||||||
var last_Rn = '';
|
var last_Rn = '';
|
||||||
var file_depth = 0; /* TODO: make a real stack */
|
var file_depth = 0; /* TODO: make a real stack */
|
||||||
var BIFF2Fmt = 0, BIFF2FmtTable = [];
|
var BIFF2Fmt = 0, BIFF2FmtTable = [];
|
||||||
var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */
|
var FilterDatabases = []; /* TODO: sort out supbooks and undefined elsewhere */
|
||||||
var last_lbl;
|
var last_lbl;
|
||||||
|
|
||||||
/* explicit override for some broken writers */
|
/* explicit override for some broken writers */
|
||||||
@ -19136,7 +19290,7 @@ var XLSBRecordEnum = {
|
|||||||
0x002E: { n:"BrtBorder", f:parse_BrtBorder },
|
0x002E: { n:"BrtBorder", f:parse_BrtBorder },
|
||||||
0x002F: { n:"BrtXF", f:parse_BrtXF },
|
0x002F: { n:"BrtXF", f:parse_BrtXF },
|
||||||
0x0030: { n:"BrtStyle" },
|
0x0030: { n:"BrtStyle" },
|
||||||
0x0031: { n:"BrtCellMeta" },
|
0x0031: { n:"BrtCellMeta", f:parse_Int32LE },
|
||||||
0x0032: { n:"BrtValueMeta" },
|
0x0032: { n:"BrtValueMeta" },
|
||||||
0x0033: { n:"BrtMdb" },
|
0x0033: { n:"BrtMdb" },
|
||||||
0x0034: { n:"BrtBeginFmd" },
|
0x0034: { n:"BrtBeginFmd" },
|
||||||
@ -19362,7 +19516,7 @@ var XLSBRecordEnum = {
|
|||||||
0x014C: { n:"BrtBeginMetadata" },
|
0x014C: { n:"BrtBeginMetadata" },
|
||||||
0x014D: { n:"BrtEndMetadata" },
|
0x014D: { n:"BrtEndMetadata" },
|
||||||
0x014E: { n:"BrtBeginEsmdtinfo" },
|
0x014E: { n:"BrtBeginEsmdtinfo" },
|
||||||
0x014F: { n:"BrtMdtinfo" },
|
0x014F: { n:"BrtMdtinfo", f:parse_BrtMdtinfo },
|
||||||
0x0150: { n:"BrtEndEsmdtinfo" },
|
0x0150: { n:"BrtEndEsmdtinfo" },
|
||||||
0x0151: { n:"BrtBeginEsmdb" },
|
0x0151: { n:"BrtBeginEsmdb" },
|
||||||
0x0152: { n:"BrtEndEsmdb" },
|
0x0152: { n:"BrtEndEsmdb" },
|
||||||
@ -19883,7 +20037,7 @@ var XLSBRecordEnum = {
|
|||||||
0x0835: { n:"BrtEndTimelineStyleElements" },
|
0x0835: { n:"BrtEndTimelineStyleElements" },
|
||||||
0x0836: { n:"BrtDxf15" },
|
0x0836: { n:"BrtDxf15" },
|
||||||
0x0837: { n:"BrtBeginDxfs15" },
|
0x0837: { n:"BrtBeginDxfs15" },
|
||||||
0x0838: { n:"brtEndDxfs15" },
|
0x0838: { n:"BrtEndDxfs15" },
|
||||||
0x0839: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
0x0839: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
||||||
0x083A: { n:"BrtBeginItemUniqueNames" },
|
0x083A: { n:"BrtBeginItemUniqueNames" },
|
||||||
0x083B: { n:"BrtEndItemUniqueNames" },
|
0x083B: { n:"BrtEndItemUniqueNames" },
|
||||||
@ -19923,9 +20077,27 @@ var XLSBRecordEnum = {
|
|||||||
0x085D: { n:"BrtModelTimeGroupingCalcCol" },
|
0x085D: { n:"BrtModelTimeGroupingCalcCol" },
|
||||||
0x0C00: { n:"BrtUid" },
|
0x0C00: { n:"BrtUid" },
|
||||||
0x0C01: { n:"BrtRevisionPtr" },
|
0x0C01: { n:"BrtRevisionPtr" },
|
||||||
0x13e7: { n:"BrtBeginCalcFeatures" },
|
0x1000: { n:"BrtBeginDynamicArrayPr" },
|
||||||
0x13e8: { n:"BrtEndCalcFeatures" },
|
0x1001: { n:"BrtEndDynamicArrayPr" },
|
||||||
0x13e9: { n:"BrtCalcFeature" },
|
0x138A: { n:"BrtBeginRichValueBlock" },
|
||||||
|
0x138B: { n:"BrtEndRichValueBlock" },
|
||||||
|
0x13D9: { n:"BrtBeginRichFilters" },
|
||||||
|
0x13DA: { n:"BrtEndRichFilters" },
|
||||||
|
0x13DB: { n:"BrtRichFilter" },
|
||||||
|
0x13DC: { n:"BrtBeginRichFilterColumn" },
|
||||||
|
0x13DD: { n:"BrtEndRichFilterColumn" },
|
||||||
|
0x13DE: { n:"BrtBeginCustomRichFilters" },
|
||||||
|
0x13DF: { n:"BrtEndCustomRichFilters" },
|
||||||
|
0x13E0: { n:"BrtCustomRichFilter" },
|
||||||
|
0x13E1: { n:"BrtTop10RichFilter" },
|
||||||
|
0x13E2: { n:"BrtDynamicRichFilter" },
|
||||||
|
0x13E4: { n:"BrtBeginRichSortCondition" },
|
||||||
|
0x13E5: { n:"BrtEndRichSortCondition" },
|
||||||
|
0x13E6: { n:"BrtRichFilterDateGroupItem" },
|
||||||
|
0x13E7: { n:"BrtBeginCalcFeatures" },
|
||||||
|
0x13E8: { n:"BrtEndCalcFeatures" },
|
||||||
|
0x13E9: { n:"BrtCalcFeature" },
|
||||||
|
0x13EB: { n:"BrtExternalLinksPr" },
|
||||||
0xFFFF: { n:"" }
|
0xFFFF: { n:"" }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -20992,7 +21164,7 @@ function sheet_add_dom(ws, table, _opts) {
|
|||||||
}
|
}
|
||||||
if(o.z === undefined && z != null) o.z = z;
|
if(o.z === undefined && z != null) o.z = z;
|
||||||
/* The first link is used. Links are assumed to be fully specified.
|
/* The first link is used. Links are assumed to be fully specified.
|
||||||
* TODO: The right way to process relative links is to make a new <a> */
|
* TODO: The right way to undefined relative links is to make a new <a> */
|
||||||
var l = "", Aelts = elt.getElementsByTagName("A");
|
var l = "", Aelts = elt.getElementsByTagName("A");
|
||||||
if(Aelts && Aelts.length) for(var Aelti = 0; Aelti < Aelts.length; ++Aelti) if(Aelts[Aelti].hasAttribute("href")) {
|
if(Aelts && Aelts.length) for(var Aelti = 0; Aelti < Aelts.length; ++Aelti) if(Aelts[Aelti].hasAttribute("href")) {
|
||||||
l = Aelts[Aelti].getAttribute("href"); if(l.charAt(0) != "#") break;
|
l = Aelts[Aelti].getAttribute("href"); if(l.charAt(0) != "#") break;
|
||||||
@ -22778,9 +22950,16 @@ function parse_zip(zip, opts) {
|
|||||||
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
||||||
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
||||||
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
||||||
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile);
|
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile.replace(/_rels.*/, "s5s"));
|
||||||
|
|
||||||
|
if((dir.metadata || []).length >= 1) {
|
||||||
|
/* TODO: MDX and other types of metadata */
|
||||||
|
opts.xlmeta = parse_xlmeta(getzipdata(zip, strip_front_slash(dir.metadata[0])),dir.metadata[0],opts);
|
||||||
|
}
|
||||||
|
|
||||||
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
||||||
|
|
||||||
|
|
||||||
/* Numbers iOS hack */
|
/* Numbers iOS hack */
|
||||||
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
||||||
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
||||||
@ -23013,6 +23192,11 @@ f = "docProps/app.xml";
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta(f));
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -23021,7 +23205,7 @@ f = "docProps/app.xml";
|
|||||||
return zip;
|
return zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this version does not reference XLSB write functions */
|
||||||
function write_zip_xlsx(wb, opts) {
|
function write_zip_xlsx(wb, opts) {
|
||||||
_shapeid = 1024;
|
_shapeid = 1024;
|
||||||
if(wb && !wb.SSF) {
|
if(wb && !wb.SSF) {
|
||||||
@ -23142,6 +23326,11 @@ f = "docProps/app.xml";
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta_xml());
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -23195,6 +23384,7 @@ function read_plaintext_raw(data, o) {
|
|||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
|
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
|
||||||
|
o.type = "binary";
|
||||||
return read_plaintext(str, o);
|
return read_plaintext(str, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23313,14 +23503,15 @@ function write_zip_typeXLSX(wb, opts) {
|
|||||||
}
|
}
|
||||||
function write_zip_denouement(z, o) {
|
function write_zip_denouement(z, o) {
|
||||||
var oopts = {};
|
var oopts = {};
|
||||||
|
var ftype = has_buf ? "nodebuffer" : (typeof Uint8Array !== "undefined" ? "array" : "string");
|
||||||
if(o.compression) oopts.compression = 'DEFLATE';
|
if(o.compression) oopts.compression = 'DEFLATE';
|
||||||
if(o.password) oopts.type = has_buf ? "nodebuffer" : "string";
|
if(o.password) oopts.type = ftype;
|
||||||
else switch(o.type) {
|
else switch(o.type) {
|
||||||
case "base64": oopts.type = "base64"; break;
|
case "base64": oopts.type = "base64"; break;
|
||||||
case "binary": oopts.type = "string"; break;
|
case "binary": oopts.type = "string"; break;
|
||||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
||||||
case "buffer":
|
case "buffer":
|
||||||
case "file": oopts.type = has_buf ? "nodebuffer" : "string"; break;
|
case "file": oopts.type = ftype; break;
|
||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: {"nodebuffer": "buffer", "string": "binary"}[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: {"nodebuffer": "buffer", "string": "binary"}[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
||||||
@ -23838,7 +24029,7 @@ utils.cell_add_comment = function(cell, text, author) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* set array formula and flush related cells */
|
/* set array formula and flush related cells */
|
||||||
utils.sheet_set_array_formula = function(ws, range, formula) {
|
utils.sheet_set_array_formula = function(ws, range, formula, dynamic) {
|
||||||
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
||||||
var rngstr = typeof range == "string" ? range : encode_range(range);
|
var rngstr = typeof range == "string" ? range : encode_range(range);
|
||||||
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
||||||
@ -23846,7 +24037,10 @@ utils.sheet_set_array_formula = function(ws, range, formula) {
|
|||||||
cell.t = 'n';
|
cell.t = 'n';
|
||||||
cell.F = rngstr;
|
cell.F = rngstr;
|
||||||
delete cell.v;
|
delete cell.v;
|
||||||
if(R == rng.s.r && C == rng.s.c) cell.f = formula;
|
if(R == rng.s.r && C == rng.s.c) {
|
||||||
|
cell.f = formula;
|
||||||
|
if(dynamic) cell.D = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ws;
|
return ws;
|
||||||
};
|
};
|
||||||
|
30
dist/xlsx.full.min.js
generated
vendored
30
dist/xlsx.full.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.full.min.map
generated
vendored
2
dist/xlsx.full.min.map
generated
vendored
File diff suppressed because one or more lines are too long
16
dist/xlsx.mini.min.js
generated
vendored
16
dist/xlsx.mini.min.js
generated
vendored
File diff suppressed because one or more lines are too long
2
dist/xlsx.mini.min.map
generated
vendored
2
dist/xlsx.mini.min.map
generated
vendored
File diff suppressed because one or more lines are too long
@ -24,9 +24,5 @@ port calculations to web apps; automate common spreadsheet tasks, and much more!
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
<details><summary><b>Diagram Legend</b> (click to show)</summary>
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
@ -38,7 +38,6 @@ The complete single-file version is generated at `dist/xlsx.full.min.js`
|
|||||||
|
|
||||||
A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
||||||
- codepage library skipped (no support for XLS encodings)
|
- codepage library skipped (no support for XLS encodings)
|
||||||
- XLSX compression option not currently available
|
|
||||||
- no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003 / Numbers
|
- no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003 / Numbers
|
||||||
- node stream utils removed
|
- node stream utils removed
|
||||||
|
|
||||||
|
@ -48,6 +48,18 @@ and approaches for steps 1 and 5.
|
|||||||
|
|
||||||
Utility functions help with step 3.
|
Utility functions help with step 3.
|
||||||
|
|
||||||
|
["Acquiring and Extracting Data"](#acquiring-and-extracting-data) describes
|
||||||
|
solutions for common data import scenarios.
|
||||||
|
|
||||||
|
["Packaging and Releasing Data"](#packaging-and-releasing-data) describes
|
||||||
|
solutions for common data export scenarios.
|
||||||
|
|
||||||
|
["Processing Data"](#packaging-and-releasing-data) describes solutions for
|
||||||
|
common workbook processing and manipulation scenarios.
|
||||||
|
|
||||||
|
["Utility Functions"](#utility-functions) details utility functions for
|
||||||
|
translating JSON Arrays and other common JS structures into worksheet objects.
|
||||||
|
|
||||||
### The Zen of SheetJS
|
### The Zen of SheetJS
|
||||||
|
|
||||||
_Data processing should fit in any workflow_
|
_Data processing should fit in any workflow_
|
||||||
@ -56,15 +68,6 @@ The library does not impose a separate lifecycle. It fits nicely in websites
|
|||||||
and apps built using any framework. The plain JS data objects play nice with
|
and apps built using any framework. The plain JS data objects play nice with
|
||||||
Web Workers and future APIs.
|
Web Workers and future APIs.
|
||||||
|
|
||||||
["Acquiring and Extracting Data"](#acquiring-and-extracting-data) describes
|
|
||||||
solutions for common data import scenarios.
|
|
||||||
|
|
||||||
["Writing Workbooks"](#writing-workbooks) describes solutions for common data
|
|
||||||
export scenarios involving actual spreadsheet files.
|
|
||||||
|
|
||||||
["Utility Functions"](#utility-functions) details utility functions for
|
|
||||||
translating JSON Arrays and other common JS structures into worksheet objects.
|
|
||||||
|
|
||||||
_JavaScript is a powerful language for data processing_
|
_JavaScript is a powerful language for data processing_
|
||||||
|
|
||||||
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
||||||
|
@ -40,3 +40,9 @@ The [`demos` directory](demos/) includes sample projects for:
|
|||||||
|
|
||||||
Other examples are included in the [showcase](demos/showcase/).
|
Other examples are included in the [showcase](demos/showcase/).
|
||||||
|
|
||||||
|
<https://sheetjs.com/demos/modify.html> shows a complete example of reading,
|
||||||
|
modifying, and writing files.
|
||||||
|
|
||||||
|
<https://github.com/SheetJS/sheetjs/blob/HEAD/bin/xlsx.njs> is the command-line
|
||||||
|
tool included with node installations, reading spreadsheet files and exporting
|
||||||
|
the contents in various formats.
|
||||||
|
@ -440,3 +440,4 @@ const workbook = XLSX.read(data);
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
More detailed examples are covered in the [included demos](demos/)
|
More detailed examples are covered in the [included demos](demos/)
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
### Processing JSON and JS Data
|
### Processing JSON and JS Data
|
||||||
|
|
||||||
JSON and JS data tend to represent single worksheets. This section will use a
|
JSON and JS data tend to represent single worksheets. This section will use a
|
||||||
few utility functions to generate workbooks:
|
few utility functions to generate workbooks.
|
||||||
|
|
||||||
_Create a new Worksheet_
|
_Create a new Workbook_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var workbook = XLSX.utils.book_new();
|
var workbook = XLSX.utils.book_new();
|
||||||
@ -11,16 +11,9 @@ var workbook = XLSX.utils.book_new();
|
|||||||
|
|
||||||
The `book_new` utility function creates an empty workbook with no worksheets.
|
The `book_new` utility function creates an empty workbook with no worksheets.
|
||||||
|
|
||||||
|
Spreadsheet software generally require at least one worksheet and enforce the
|
||||||
_Append a Worksheet to a Workbook_
|
requirement in the user interface. This library enforces the requirement at
|
||||||
|
write time, throwing errors if an empty workbook is passed to write functions.
|
||||||
```js
|
|
||||||
XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name);
|
|
||||||
```
|
|
||||||
|
|
||||||
The `book_append_sheet` utility function appends a worksheet to the workbook.
|
|
||||||
The third argument specifies the desired worksheet name. Multiple worksheets can
|
|
||||||
be added to a workbook by calling the function multiple times.
|
|
||||||
|
|
||||||
|
|
||||||
**API**
|
**API**
|
||||||
@ -33,14 +26,14 @@ var worksheet = XLSX.utils.aoa_to_sheet(aoa, opts);
|
|||||||
|
|
||||||
The `aoa_to_sheet` utility function walks an "array of arrays" in row-major
|
The `aoa_to_sheet` utility function walks an "array of arrays" in row-major
|
||||||
order, generating a worksheet object. The following snippet generates a sheet
|
order, generating a worksheet object. The following snippet generates a sheet
|
||||||
with cell `A1` set to the string `A1`, cell `B1` set to `B2`, etc:
|
with cell `A1` set to the string `A1`, cell `B1` set to `B1`, etc:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var worksheet = XLSX.utils.aoa_to_sheet([
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
["A1", "B1", "C1"],
|
["A1", "B1", "C1"],
|
||||||
["A2", "B2", "C2"],
|
["A2", "B2", "C2"],
|
||||||
["A3", "B3", "C3"]
|
["A3", "B3", "C3"]
|
||||||
])
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
||||||
|
@ -1,38 +1,54 @@
|
|||||||
## Working with the Workbook
|
## Processing Data
|
||||||
|
|
||||||
The full object format is described later in this README.
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
||||||
|
representation of the core concepts of a workbook. The utility functions work
|
||||||
|
with the object representation and are intended to handle common use cases.
|
||||||
|
|
||||||
<details>
|
### Modifying Workbook Structure
|
||||||
<summary><b>Reading a specific cell </b> (click to show)</summary>
|
|
||||||
|
|
||||||
This example extracts the value stored in cell A1 from the first worksheet:
|
**API**
|
||||||
|
|
||||||
|
_Append a Worksheet to a Workbook_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var first_sheet_name = workbook.SheetNames[0];
|
XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name);
|
||||||
var address_of_cell = 'A1';
|
|
||||||
|
|
||||||
/* Get worksheet */
|
|
||||||
var worksheet = workbook.Sheets[first_sheet_name];
|
|
||||||
|
|
||||||
/* Find desired cell */
|
|
||||||
var desired_cell = worksheet[address_of_cell];
|
|
||||||
|
|
||||||
/* Get the value */
|
|
||||||
var desired_value = (desired_cell ? desired_cell.v : undefined);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
The `book_append_sheet` utility function appends a worksheet to the workbook.
|
||||||
|
The third argument specifies the desired worksheet name. Multiple worksheets can
|
||||||
|
be added to a workbook by calling the function multiple times.
|
||||||
|
|
||||||
|
_List the Worksheet names in tab order_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var wsnames = workbook.SheetNames;
|
||||||
|
```
|
||||||
|
|
||||||
|
The `SheetNames` property of the workbook object is a list of the worksheet
|
||||||
|
names in "tab order". API functions will look at this array.
|
||||||
|
|
||||||
|
_Replace a Worksheet in place_
|
||||||
|
|
||||||
|
```js
|
||||||
|
workbook.Sheets[sheet_name] = new_worksheet;
|
||||||
|
```
|
||||||
|
|
||||||
|
The `Sheets` property of the workbook object is an object whose keys are names
|
||||||
|
and whose values are worksheet objects. By reassigning to a property of the
|
||||||
|
`Sheets` object, the worksheet object can be changed without disrupting the
|
||||||
|
rest of the worksheet structure.
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Adding a new worksheet to a workbook</b> (click to show)</summary>
|
<summary><b>Add a new worksheet to a workbook</b> (click to show)</summary>
|
||||||
|
|
||||||
This example uses [`XLSX.utils.aoa_to_sheet`](#array-of-arrays-input) to make a
|
This example uses [`XLSX.utils.aoa_to_sheet`](#array-of-arrays-input).
|
||||||
sheet and `XLSX.utils.book_append_sheet` to append the sheet to the workbook:
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var ws_name = "SheetJS";
|
var ws_name = "SheetJS";
|
||||||
|
|
||||||
/* make worksheet */
|
/* Create worksheet */
|
||||||
var ws_data = [
|
var ws_data = [
|
||||||
[ "S", "h", "e", "e", "t", "J", "S" ],
|
[ "S", "h", "e", "e", "t", "J", "S" ],
|
||||||
[ 1 , 2 , 3 , 4 , 5 ]
|
[ 1 , 2 , 3 , 4 , 5 ]
|
||||||
@ -45,39 +61,58 @@ XLSX.utils.book_append_sheet(wb, ws, ws_name);
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
### Modifying Cell Values
|
||||||
<summary><b>Creating a new workbook from scratch</b> (click to show)</summary>
|
|
||||||
|
|
||||||
The workbook object contains a `SheetNames` array of names and a `Sheets` object
|
**API**
|
||||||
mapping sheet names to sheet objects. The `XLSX.utils.book_new` utility function
|
|
||||||
creates a new workbook object:
|
_Modify a single cell value in a worksheet_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/* create a new blank workbook */
|
XLSX.utils.sheet_add_aoa(worksheet, [[new_value]], { origin: address });
|
||||||
var wb = XLSX.utils.book_new();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The new workbook is blank and contains no worksheets. The write functions will
|
_Modify multiple cell values in a worksheet_
|
||||||
error if the workbook is empty.
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, aoa, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `sheet_add_aoa` utility function modifies cell values in a worksheet. The
|
||||||
|
first argument is the worksheet object. The second argument is an array of
|
||||||
|
arrays of values. The `origin` key of the third argument controls where cells
|
||||||
|
will be written. The following snippet sets `B3=1` and `E5="abc"`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, [
|
||||||
|
[1], // <-- Write 1 to cell B3
|
||||||
|
, // <-- Do nothing in row 4
|
||||||
|
[/*B5*/, /*C5*/, /*D5*/, "abc"] // <-- Write "abc" to cell E5
|
||||||
|
], { origin: "B3" });
|
||||||
|
```
|
||||||
|
|
||||||
|
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
||||||
|
optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Appending rows to a worksheet</b> (click to show)</summary>
|
||||||
|
|
||||||
|
The special origin value `-1` instructs `sheet_add_aoa` to start in column A of
|
||||||
|
the row after the last row in the range, appending the data:
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, [
|
||||||
|
["first row after data", 1],
|
||||||
|
["second row after data", 2]
|
||||||
|
], { origin: -1 });
|
||||||
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
### Parsing and Writing Examples
|
### Modifying Other Worksheet / Workbook / Cell Properties
|
||||||
|
|
||||||
- <https://sheetjs.com/demos/modify.html> read + modify + write files
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) section describes
|
||||||
|
the object structures in greater detail.
|
||||||
- <https://github.com/SheetJS/sheetjs/blob/HEAD/bin/xlsx.njs> node
|
|
||||||
|
|
||||||
The node version installs a command line tool `xlsx` which can read spreadsheet
|
|
||||||
files and output the contents in various formats. The source is available at
|
|
||||||
`xlsx.njs` in the bin directory.
|
|
||||||
|
|
||||||
Some helper functions in `XLSX.utils` generate different views of the sheets:
|
|
||||||
|
|
||||||
- `XLSX.utils.sheet_to_csv` generates CSV
|
|
||||||
- `XLSX.utils.sheet_to_txt` generates UTF16 Formatted Text
|
|
||||||
- `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
|
|
||||||
|
|
||||||
|
@ -255,3 +255,42 @@ The [`vuejs` demo](demos/vue) includes more React examples.
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### Generating Single-Worksheet Snapshots
|
||||||
|
|
||||||
|
The `sheet_to_*` functions accept a worksheet object.
|
||||||
|
|
||||||
|
**API**
|
||||||
|
|
||||||
|
_Generate a CSV from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var csv = XLSX.utils.sheet_to_csv(worksheet, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot is designed to replicate the "CSV UTF8 (`.csv`)" output type.
|
||||||
|
["Delimiter-Separated Output"](#delimiter-separated-output) describes the
|
||||||
|
function and the optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
_Generate "Text" from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var txt = XLSX.utils.sheet_to_txt(worksheet, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot is designed to replicate the "UTF16 Text (`.txt`)" output type.
|
||||||
|
["Delimiter-Separated Output"](#delimiter-separated-output) describes the
|
||||||
|
function and the optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
_Generate a list of formulae from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var fmla = XLSX.utils.sheet_to_formulae(worksheet);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot generates an array of entries representing the embedded formulae.
|
||||||
|
Array formulae are rendered in the form `range=formula` while plain cells are
|
||||||
|
rendered in the form `cell=formula or value`. String literals are prefixed with
|
||||||
|
an apostrophe `'`, consistent with Excel's formula bar display.
|
||||||
|
|
||||||
|
["Formulae Output"](#formulae-output) describes the function in more detail.
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ Cell objects are plain JS objects with keys and values following the convention:
|
|||||||
| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub |
|
| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub |
|
||||||
| `f` | cell formula encoded as an A1-style string (if applicable) |
|
| `f` | cell formula encoded as an A1-style string (if applicable) |
|
||||||
| `F` | range of enclosing array if formula is array formula (if applicable) |
|
| `F` | range of enclosing array if formula is array formula (if applicable) |
|
||||||
|
| `D` | if true, array formula is dynamic (if applicable) |
|
||||||
| `r` | rich text encoding (if applicable) |
|
| `r` | rich text encoding (if applicable) |
|
||||||
| `h` | HTML rendering of the rich text (if applicable) |
|
| `h` | HTML rendering of the rich text (if applicable) |
|
||||||
| `c` | comments associated with the cell |
|
| `c` | comments associated with the cell |
|
||||||
|
@ -6,79 +6,7 @@ Even though some formats store formulae with a leading equal sign, CSF formulae
|
|||||||
do not start with `=`.
|
do not start with `=`.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Representation of A1=1, A2=2, A3=A1+A2</b> (click to show)</summary>
|
<summary><b>Formulae File Format Support</b> (click to show)</summary>
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"!ref": "A1:A3",
|
|
||||||
A1: { t:'n', v:1 },
|
|
||||||
A2: { t:'n', v:2 },
|
|
||||||
A3: { t:'n', v:3, f:'A1+A2' }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
Shared formulae are decompressed and each cell has the formula corresponding to
|
|
||||||
its cell. Writers generally do not attempt to generate shared formulae.
|
|
||||||
|
|
||||||
Cells with formula entries but no value will be serialized in a way that Excel
|
|
||||||
and other spreadsheet tools will recognize. This library will not automatically
|
|
||||||
compute formula results! For example, to compute `BESSELJ` in a worksheet:
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><b>Formula without known value</b> (click to show)</summary>
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"!ref": "A1:A3",
|
|
||||||
A1: { t:'n', v:3.14159 },
|
|
||||||
A2: { t:'n', v:2 },
|
|
||||||
A3: { t:'n', f:'BESSELJ(A1,A2)' }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
**Array Formulae**
|
|
||||||
|
|
||||||
Array formulae are stored in the top-left cell of the array block. All cells
|
|
||||||
of an array formula have a `F` field corresponding to the range. A single-cell
|
|
||||||
formula can be distinguished from a plain formula by the presence of `F` field.
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><b>Array Formula examples</b> (click to show)</summary>
|
|
||||||
|
|
||||||
For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" };
|
|
||||||
```
|
|
||||||
|
|
||||||
For a multi-cell array formula, every cell has the same array range but only the
|
|
||||||
first cell specifies the formula. Consider `D1:D3=A1:A3*B1:B3`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" };
|
|
||||||
worksheet['D2'] = { t:'n', F:"D1:D3" };
|
|
||||||
worksheet['D3'] = { t:'n', F:"D1:D3" };
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
Utilities and writers are expected to check for the presence of a `F` field and
|
|
||||||
ignore any possible formula element `f` in cells other than the starting cell.
|
|
||||||
They are not expected to perform validation of the formulae!
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><b>Formula Output Utility Function</b> (click to show)</summary>
|
|
||||||
|
|
||||||
The `sheet_to_formulae` method generates one line per formula or array formula.
|
|
||||||
Array formulae are rendered in the form `range=formula` while plain cells are
|
|
||||||
rendered in the form `cell=formula or value`. Note that string literals are
|
|
||||||
prefixed with an apostrophe `'`, consistent with Excel's formula bar display.
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><b>Formulae File Format Details</b> (click to show)</summary>
|
|
||||||
|
|
||||||
| Storage Representation | Formats | Read | Write |
|
| Storage Representation | Formats | Read | Write |
|
||||||
|:-----------------------|:-------------------------|:-----:|:-----:|
|
|:-----------------------|:-------------------------|:-----:|:-----:|
|
||||||
@ -92,5 +20,271 @@ Since Excel prohibits named cells from colliding with names of A1 or RC style
|
|||||||
cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed
|
cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed
|
||||||
formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula
|
formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula
|
||||||
formulae can be converted with regular expressions.
|
formulae can be converted with regular expressions.
|
||||||
|
|
||||||
|
Shared formulae are decompressed and each cell has the formula corresponding to
|
||||||
|
its cell. Writers generally do not attempt to generate shared formulae.
|
||||||
|
</details>
|
||||||
|
|
||||||
|
**Single-Cell Formulae**
|
||||||
|
|
||||||
|
For simple formulae, the `f` key of the desired cell can be set to the actual
|
||||||
|
formula text. This worksheet represents `A1=1`, `A2=2`, and `A3=A1+A2`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = {
|
||||||
|
"!ref": "A1:A3",
|
||||||
|
A1: { t:'n', v:1 },
|
||||||
|
A2: { t:'n', v:2 },
|
||||||
|
A3: { t:'n', v:3, f:'A1+A2' }
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Utilities like `aoa_to_sheet` will accept cell objects in lieu of values:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
[ 1 ], // A1
|
||||||
|
[ 2 ], // A2
|
||||||
|
[ {t: "n", v: 3, f: "A1+A2"} ] // A3
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Cells with formula entries but no value will be serialized in a way that Excel
|
||||||
|
and other spreadsheet tools will recognize. This library will not automatically
|
||||||
|
compute formula results! For example, the following worksheet will include the
|
||||||
|
`BESSELJ` function but the result will not be available in JavaScript:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
[ 3.14159, 2 ], // Row "1"
|
||||||
|
[ { t:'n', f:'BESSELJ(A1,B1)' } ] // Row "2" will be calculated on file open
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the actual results are needed in JS, [SheetJS Pro](https://sheetjs.com/pro)
|
||||||
|
offers a formula calculator component for evaluating expressions, updating
|
||||||
|
values and dependent cells, and refreshing entire workbooks.
|
||||||
|
|
||||||
|
|
||||||
|
**Array Formulae**
|
||||||
|
|
||||||
|
_Assign an array formula_
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, range, formula);
|
||||||
|
```
|
||||||
|
|
||||||
|
Array formulae are stored in the top-left cell of the array block. All cells
|
||||||
|
of an array formula have a `F` field corresponding to the range. A single-cell
|
||||||
|
formula can be distinguished from a plain formula by the presence of `F` field.
|
||||||
|
|
||||||
|
For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "SUM(A1:A3*B1:B3)");
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" };
|
||||||
|
```
|
||||||
|
|
||||||
|
For a multi-cell array formula, every cell has the same array range but only the
|
||||||
|
first cell specifies the formula. Consider `D1:D3=A1:A3*B1:B3`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "D1:D3", "A1:A3*B1:B3");
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" };
|
||||||
|
worksheet['D2'] = { t:'n', F:"D1:D3" };
|
||||||
|
worksheet['D3'] = { t:'n', F:"D1:D3" };
|
||||||
|
```
|
||||||
|
|
||||||
|
Utilities and writers are expected to check for the presence of a `F` field and
|
||||||
|
ignore any possible formula element `f` in cells other than the starting cell.
|
||||||
|
They are not expected to perform validation of the formulae!
|
||||||
|
|
||||||
|
|
||||||
|
**Dynamic Array Formulae**
|
||||||
|
|
||||||
|
_Assign a dynamic array formula_
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, range, formula, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
Released in 2020, Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB
|
||||||
|
file formats. They are represented like normal array formulae but have special
|
||||||
|
cell metadata indicating that the formula should be allowed to adjust the range.
|
||||||
|
|
||||||
|
An array formula can be marked as dynamic by setting the cell's `D` property to
|
||||||
|
true. The `F` range is expected but can be the set to the current cell:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1);
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['C1'] = { t: "s", f: "_xlfn.UNIQUE(A1:A3)", F:"C1", D: 1 }; // dynamic
|
||||||
|
```
|
||||||
|
|
||||||
|
**Localization with Function Names**
|
||||||
|
|
||||||
|
SheetJS operates at the file level. Excel stores formula expressions using the
|
||||||
|
English (United States) function names. For non-English users, Excel uses a
|
||||||
|
localized set of function names.
|
||||||
|
|
||||||
|
For example, when the computer language and region is set to French (France),
|
||||||
|
Excel interprets `=SOMME(A1:C3)` as if `SOMME` is the `SUM` function. However,
|
||||||
|
in the actual file, Excel stores `SUM(A1:C3)`.
|
||||||
|
|
||||||
|
**Prefixed "Future Functions"**
|
||||||
|
|
||||||
|
Functions introduced in newer versions of Excel are prefixed with `_xlfn.` when
|
||||||
|
stored in files. When writing formula expressions using these functions, the
|
||||||
|
prefix is required for maximal compatibility:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Broadest compatibility
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1);
|
||||||
|
|
||||||
|
// Can cause errors in spreadsheet software
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "UNIQUE(A1:A3)", 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
When reading a file, the `xlfn` option preserves the prefixes.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b> Functions requiring `_xlfn.` prefix</b> (click to show)</summary>
|
||||||
|
|
||||||
|
This list is growing with each Excel release.
|
||||||
|
|
||||||
|
```
|
||||||
|
ACOT
|
||||||
|
ACOTH
|
||||||
|
AGGREGATE
|
||||||
|
ARABIC
|
||||||
|
BASE
|
||||||
|
BETA.DIST
|
||||||
|
BETA.INV
|
||||||
|
BINOM.DIST
|
||||||
|
BINOM.DIST.RANGE
|
||||||
|
BINOM.INV
|
||||||
|
BITAND
|
||||||
|
BITLSHIFT
|
||||||
|
BITOR
|
||||||
|
BITRSHIFT
|
||||||
|
BITXOR
|
||||||
|
BYCOL
|
||||||
|
BYROW
|
||||||
|
CEILING.MATH
|
||||||
|
CEILING.PRECISE
|
||||||
|
CHISQ.DIST
|
||||||
|
CHISQ.DIST.RT
|
||||||
|
CHISQ.INV
|
||||||
|
CHISQ.INV.RT
|
||||||
|
CHISQ.TEST
|
||||||
|
COMBINA
|
||||||
|
CONFIDENCE.NORM
|
||||||
|
CONFIDENCE.T
|
||||||
|
COT
|
||||||
|
COTH
|
||||||
|
COVARIANCE.P
|
||||||
|
COVARIANCE.S
|
||||||
|
CSC
|
||||||
|
CSCH
|
||||||
|
DAYS
|
||||||
|
DECIMAL
|
||||||
|
ERF.PRECISE
|
||||||
|
ERFC.PRECISE
|
||||||
|
EXPON.DIST
|
||||||
|
F.DIST
|
||||||
|
F.DIST.RT
|
||||||
|
F.INV
|
||||||
|
F.INV.RT
|
||||||
|
F.TEST
|
||||||
|
FIELDVALUE
|
||||||
|
FILTERXML
|
||||||
|
FLOOR.MATH
|
||||||
|
FLOOR.PRECISE
|
||||||
|
FORMULATEXT
|
||||||
|
GAMMA
|
||||||
|
GAMMA.DIST
|
||||||
|
GAMMA.INV
|
||||||
|
GAMMALN.PRECISE
|
||||||
|
GAUSS
|
||||||
|
HYPGEOM.DIST
|
||||||
|
IFNA
|
||||||
|
IMCOSH
|
||||||
|
IMCOT
|
||||||
|
IMCSC
|
||||||
|
IMCSCH
|
||||||
|
IMSEC
|
||||||
|
IMSECH
|
||||||
|
IMSINH
|
||||||
|
IMTAN
|
||||||
|
ISFORMULA
|
||||||
|
ISOMITTED
|
||||||
|
ISOWEEKNUM
|
||||||
|
LAMBDA
|
||||||
|
LET
|
||||||
|
LOGNORM.DIST
|
||||||
|
LOGNORM.INV
|
||||||
|
MAKEARRAY
|
||||||
|
MAP
|
||||||
|
MODE.MULT
|
||||||
|
MODE.SNGL
|
||||||
|
MUNIT
|
||||||
|
NEGBINOM.DIST
|
||||||
|
NORM.DIST
|
||||||
|
NORM.INV
|
||||||
|
NORM.S.DIST
|
||||||
|
NORM.S.INV
|
||||||
|
NUMBERVALUE
|
||||||
|
PDURATION
|
||||||
|
PERCENTILE.EXC
|
||||||
|
PERCENTILE.INC
|
||||||
|
PERCENTRANK.EXC
|
||||||
|
PERCENTRANK.INC
|
||||||
|
PERMUTATIONA
|
||||||
|
PHI
|
||||||
|
POISSON.DIST
|
||||||
|
QUARTILE.EXC
|
||||||
|
QUARTILE.INC
|
||||||
|
QUERYSTRING
|
||||||
|
RANDARRAY
|
||||||
|
RANK.AVG
|
||||||
|
RANK.EQ
|
||||||
|
REDUCE
|
||||||
|
RRI
|
||||||
|
SCAN
|
||||||
|
SEC
|
||||||
|
SECH
|
||||||
|
SEQUENCE
|
||||||
|
SHEET
|
||||||
|
SHEETS
|
||||||
|
SKEW.P
|
||||||
|
SORTBY
|
||||||
|
STDEV.P
|
||||||
|
STDEV.S
|
||||||
|
T.DIST
|
||||||
|
T.DIST.2T
|
||||||
|
T.DIST.RT
|
||||||
|
T.INV
|
||||||
|
T.INV.2T
|
||||||
|
T.TEST
|
||||||
|
UNICHAR
|
||||||
|
UNICODE
|
||||||
|
UNIQUE
|
||||||
|
VAR.P
|
||||||
|
VAR.S
|
||||||
|
WEBSERVICE
|
||||||
|
WEIBULL.DIST
|
||||||
|
XLOOKUP
|
||||||
|
XOR
|
||||||
|
Z.TEST
|
||||||
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
1
mini.lst
1
mini.lst
@ -28,6 +28,7 @@ bits/42_sstxml.js
|
|||||||
bits/46_stycommon.js
|
bits/46_stycommon.js
|
||||||
bits/47_styxml.js
|
bits/47_styxml.js
|
||||||
bits/49_theme.js
|
bits/49_theme.js
|
||||||
|
misc/51_xlsxmeta.js
|
||||||
bits/53_externlink.js
|
bits/53_externlink.js
|
||||||
bits/54_drawing.js
|
bits/54_drawing.js
|
||||||
bits/55_vml.js
|
bits/55_vml.js
|
||||||
|
@ -14,7 +14,7 @@ function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
|
|||||||
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
||||||
if(typeof Deno !== 'undefined') {
|
if(typeof Deno !== 'undefined') {
|
||||||
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
||||||
if(enc) switch(enc) {
|
if(enc && typeof payload == "string") switch(enc) {
|
||||||
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
||||||
case "binary": payload = s2ab(payload); break;
|
case "binary": payload = s2ab(payload); break;
|
||||||
/* TODO: binary equivalent */
|
/* TODO: binary equivalent */
|
||||||
|
63
misc/51_xlsxmeta.js
Normal file
63
misc/51_xlsxmeta.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
function parse_xlmeta_xml(data, name, opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
if (!data)
|
||||||
|
return out;
|
||||||
|
var pass = false;
|
||||||
|
data.replace(tagregex, function(x, idx) {
|
||||||
|
var y = parsexmltag(x);
|
||||||
|
switch (strip_ns(y[0])) {
|
||||||
|
case "<?xml":
|
||||||
|
break;
|
||||||
|
case "<metadata":
|
||||||
|
case "</metadata>":
|
||||||
|
break;
|
||||||
|
case "<metadataTypes":
|
||||||
|
case "</metadataTypes>":
|
||||||
|
break;
|
||||||
|
case "<metadataType":
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
case "<futureMetadata":
|
||||||
|
break;
|
||||||
|
case "</futureMetadata>":
|
||||||
|
break;
|
||||||
|
case "<bk>":
|
||||||
|
break;
|
||||||
|
case "</bk>":
|
||||||
|
break;
|
||||||
|
case "<rc":
|
||||||
|
break;
|
||||||
|
case "</rc>":
|
||||||
|
break;
|
||||||
|
case "<cellMetadata":
|
||||||
|
case "</cellMetadata>":
|
||||||
|
break;
|
||||||
|
case "<valueMetadata":
|
||||||
|
break;
|
||||||
|
case "</valueMetadata>":
|
||||||
|
break;
|
||||||
|
case "<extLst":
|
||||||
|
case "<extLst>":
|
||||||
|
case "</extLst>":
|
||||||
|
case "<extLst/>":
|
||||||
|
break;
|
||||||
|
case "<ext":
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case "</ext>":
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!pass && opts.WTF)
|
||||||
|
throw new Error("unrecognized " + y[0] + " in metadata");
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_xml() {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
|
||||||
|
return o.join("");
|
||||||
|
}
|
@ -24,10 +24,8 @@ port calculations to web apps; automate common spreadsheet tasks, and much more!
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
|
|
||||||
@ -42,14 +40,17 @@ port calculations to web apps; automate common spreadsheet tasks, and much more!
|
|||||||
* [Parsing Workbooks](#parsing-workbooks)
|
* [Parsing Workbooks](#parsing-workbooks)
|
||||||
* [Processing JSON and JS Data](#processing-json-and-js-data)
|
* [Processing JSON and JS Data](#processing-json-and-js-data)
|
||||||
* [Processing HTML Tables](#processing-html-tables)
|
* [Processing HTML Tables](#processing-html-tables)
|
||||||
- [Working with the Workbook](#working-with-the-workbook)
|
- [Processing Data](#processing-data)
|
||||||
* [Parsing and Writing Examples](#parsing-and-writing-examples)
|
* [Modifying Workbook Structure](#modifying-workbook-structure)
|
||||||
|
* [Modifying Cell Values](#modifying-cell-values)
|
||||||
|
* [Modifying Other Worksheet / Workbook / Cell Properties](#modifying-other-worksheet--workbook--cell-properties)
|
||||||
- [Packaging and Releasing Data](#packaging-and-releasing-data)
|
- [Packaging and Releasing Data](#packaging-and-releasing-data)
|
||||||
* [Writing Workbooks](#writing-workbooks)
|
* [Writing Workbooks](#writing-workbooks)
|
||||||
* [Writing Examples](#writing-examples)
|
* [Writing Examples](#writing-examples)
|
||||||
* [Streaming Write](#streaming-write)
|
* [Streaming Write](#streaming-write)
|
||||||
* [Generating JSON and JS Data](#generating-json-and-js-data)
|
* [Generating JSON and JS Data](#generating-json-and-js-data)
|
||||||
* [Generating HTML Tables](#generating-html-tables)
|
* [Generating HTML Tables](#generating-html-tables)
|
||||||
|
* [Generating Single-Worksheet Snapshots](#generating-single-worksheet-snapshots)
|
||||||
- [Interface](#interface)
|
- [Interface](#interface)
|
||||||
* [Parsing functions](#parsing-functions)
|
* [Parsing functions](#parsing-functions)
|
||||||
* [Writing functions](#writing-functions)
|
* [Writing functions](#writing-functions)
|
||||||
@ -140,10 +141,11 @@ For example, `unpkg` makes the latest version available at:
|
|||||||
|
|
||||||
The complete single-file version is generated at `dist/xlsx.full.min.js`
|
The complete single-file version is generated at `dist/xlsx.full.min.js`
|
||||||
|
|
||||||
|
`dist/xlsx.core.min.js` omits codepage library (no support for XLS encodings)
|
||||||
|
|
||||||
A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
A slimmer build is generated at `dist/xlsx.mini.min.js`. Compared to full build:
|
||||||
- codepage library skipped (no support for XLS encodings)
|
- codepage library skipped (no support for XLS encodings)
|
||||||
- XLSX compression option not currently available
|
- no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003 / Numbers
|
||||||
- no support for XLSB / XLS / Lotus 1-2-3 / SpreadsheetML 2003
|
|
||||||
- node stream utils removed
|
- node stream utils removed
|
||||||
|
|
||||||
|
|
||||||
@ -303,6 +305,18 @@ and approaches for steps 1 and 5.
|
|||||||
|
|
||||||
Utility functions help with step 3.
|
Utility functions help with step 3.
|
||||||
|
|
||||||
|
["Acquiring and Extracting Data"](#acquiring-and-extracting-data) describes
|
||||||
|
solutions for common data import scenarios.
|
||||||
|
|
||||||
|
["Packaging and Releasing Data"](#packaging-and-releasing-data) describes
|
||||||
|
solutions for common data export scenarios.
|
||||||
|
|
||||||
|
["Processing Data"](#packaging-and-releasing-data) describes solutions for
|
||||||
|
common workbook processing and manipulation scenarios.
|
||||||
|
|
||||||
|
["Utility Functions"](#utility-functions) details utility functions for
|
||||||
|
translating JSON Arrays and other common JS structures into worksheet objects.
|
||||||
|
|
||||||
### The Zen of SheetJS
|
### The Zen of SheetJS
|
||||||
|
|
||||||
_Data processing should fit in any workflow_
|
_Data processing should fit in any workflow_
|
||||||
@ -311,15 +325,6 @@ The library does not impose a separate lifecycle. It fits nicely in websites
|
|||||||
and apps built using any framework. The plain JS data objects play nice with
|
and apps built using any framework. The plain JS data objects play nice with
|
||||||
Web Workers and future APIs.
|
Web Workers and future APIs.
|
||||||
|
|
||||||
["Acquiring and Extracting Data"](#acquiring-and-extracting-data) describes
|
|
||||||
solutions for common data import scenarios.
|
|
||||||
|
|
||||||
["Writing Workbooks"](#writing-workbooks) describes solutions for common data
|
|
||||||
export scenarios involving actual spreadsheet files.
|
|
||||||
|
|
||||||
["Utility Functions"](#utility-functions) details utility functions for
|
|
||||||
translating JSON Arrays and other common JS structures into worksheet objects.
|
|
||||||
|
|
||||||
_JavaScript is a powerful language for data processing_
|
_JavaScript is a powerful language for data processing_
|
||||||
|
|
||||||
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
||||||
@ -559,6 +564,12 @@ The [`demos` directory](demos/) includes sample projects for:
|
|||||||
|
|
||||||
Other examples are included in the [showcase](demos/showcase/).
|
Other examples are included in the [showcase](demos/showcase/).
|
||||||
|
|
||||||
|
<https://sheetjs.com/demos/modify.html> shows a complete example of reading,
|
||||||
|
modifying, and writing files.
|
||||||
|
|
||||||
|
<https://github.com/SheetJS/sheetjs/blob/HEAD/bin/xlsx.njs> is the command-line
|
||||||
|
tool included with node installations, reading spreadsheet files and exporting
|
||||||
|
the contents in various formats.
|
||||||
## Acquiring and Extracting Data
|
## Acquiring and Extracting Data
|
||||||
|
|
||||||
### Parsing Workbooks
|
### Parsing Workbooks
|
||||||
@ -962,12 +973,13 @@ const workbook = XLSX.read(data);
|
|||||||
|
|
||||||
|
|
||||||
More detailed examples are covered in the [included demos](demos/)
|
More detailed examples are covered in the [included demos](demos/)
|
||||||
|
|
||||||
### Processing JSON and JS Data
|
### Processing JSON and JS Data
|
||||||
|
|
||||||
JSON and JS data tend to represent single worksheets. This section will use a
|
JSON and JS data tend to represent single worksheets. This section will use a
|
||||||
few utility functions to generate workbooks:
|
few utility functions to generate workbooks.
|
||||||
|
|
||||||
_Create a new Worksheet_
|
_Create a new Workbook_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var workbook = XLSX.utils.book_new();
|
var workbook = XLSX.utils.book_new();
|
||||||
@ -975,16 +987,9 @@ var workbook = XLSX.utils.book_new();
|
|||||||
|
|
||||||
The `book_new` utility function creates an empty workbook with no worksheets.
|
The `book_new` utility function creates an empty workbook with no worksheets.
|
||||||
|
|
||||||
|
Spreadsheet software generally require at least one worksheet and enforce the
|
||||||
_Append a Worksheet to a Workbook_
|
requirement in the user interface. This library enforces the requirement at
|
||||||
|
write time, throwing errors if an empty workbook is passed to write functions.
|
||||||
```js
|
|
||||||
XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name);
|
|
||||||
```
|
|
||||||
|
|
||||||
The `book_append_sheet` utility function appends a worksheet to the workbook.
|
|
||||||
The third argument specifies the desired worksheet name. Multiple worksheets can
|
|
||||||
be added to a workbook by calling the function multiple times.
|
|
||||||
|
|
||||||
|
|
||||||
**API**
|
**API**
|
||||||
@ -997,14 +1002,14 @@ var worksheet = XLSX.utils.aoa_to_sheet(aoa, opts);
|
|||||||
|
|
||||||
The `aoa_to_sheet` utility function walks an "array of arrays" in row-major
|
The `aoa_to_sheet` utility function walks an "array of arrays" in row-major
|
||||||
order, generating a worksheet object. The following snippet generates a sheet
|
order, generating a worksheet object. The following snippet generates a sheet
|
||||||
with cell `A1` set to the string `A1`, cell `B1` set to `B2`, etc:
|
with cell `A1` set to the string `A1`, cell `B1` set to `B1`, etc:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var worksheet = XLSX.utils.aoa_to_sheet([
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
["A1", "B1", "C1"],
|
["A1", "B1", "C1"],
|
||||||
["A2", "B2", "C2"],
|
["A2", "B2", "C2"],
|
||||||
["A3", "B3", "C3"]
|
["A3", "B3", "C3"]
|
||||||
])
|
]);
|
||||||
```
|
```
|
||||||
|
|
||||||
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
||||||
@ -1284,36 +1289,55 @@ const workbook = XLSX.utils.table_to_book(doc);
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Working with the Workbook
|
## Processing Data
|
||||||
|
|
||||||
The full object format is described later in this README.
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) is a simple object
|
||||||
|
representation of the core concepts of a workbook. The utility functions work
|
||||||
|
with the object representation and are intended to handle common use cases.
|
||||||
|
|
||||||
|
### Modifying Workbook Structure
|
||||||
|
|
||||||
This example extracts the value stored in cell A1 from the first worksheet:
|
**API**
|
||||||
|
|
||||||
|
_Append a Worksheet to a Workbook_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var first_sheet_name = workbook.SheetNames[0];
|
XLSX.utils.book_append_sheet(workbook, worksheet, sheet_name);
|
||||||
var address_of_cell = 'A1';
|
|
||||||
|
|
||||||
/* Get worksheet */
|
|
||||||
var worksheet = workbook.Sheets[first_sheet_name];
|
|
||||||
|
|
||||||
/* Find desired cell */
|
|
||||||
var desired_cell = worksheet[address_of_cell];
|
|
||||||
|
|
||||||
/* Get the value */
|
|
||||||
var desired_value = (desired_cell ? desired_cell.v : undefined);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The `book_append_sheet` utility function appends a worksheet to the workbook.
|
||||||
|
The third argument specifies the desired worksheet name. Multiple worksheets can
|
||||||
|
be added to a workbook by calling the function multiple times.
|
||||||
|
|
||||||
|
_List the Worksheet names in tab order_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var wsnames = workbook.SheetNames;
|
||||||
|
```
|
||||||
|
|
||||||
|
The `SheetNames` property of the workbook object is a list of the worksheet
|
||||||
|
names in "tab order". API functions will look at this array.
|
||||||
|
|
||||||
|
_Replace a Worksheet in place_
|
||||||
|
|
||||||
|
```js
|
||||||
|
workbook.Sheets[sheet_name] = new_worksheet;
|
||||||
|
```
|
||||||
|
|
||||||
|
The `Sheets` property of the workbook object is an object whose keys are names
|
||||||
|
and whose values are worksheet objects. By reassigning to a property of the
|
||||||
|
`Sheets` object, the worksheet object can be changed without disrupting the
|
||||||
|
rest of the worksheet structure.
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
|
||||||
This example uses [`XLSX.utils.aoa_to_sheet`](#array-of-arrays-input) to make a
|
This example uses [`XLSX.utils.aoa_to_sheet`](#array-of-arrays-input).
|
||||||
sheet and `XLSX.utils.book_append_sheet` to append the sheet to the workbook:
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var ws_name = "SheetJS";
|
var ws_name = "SheetJS";
|
||||||
|
|
||||||
/* make worksheet */
|
/* Create worksheet */
|
||||||
var ws_data = [
|
var ws_data = [
|
||||||
[ "S", "h", "e", "e", "t", "J", "S" ],
|
[ "S", "h", "e", "e", "t", "J", "S" ],
|
||||||
[ 1 , 2 , 3 , 4 , 5 ]
|
[ 1 , 2 , 3 , 4 , 5 ]
|
||||||
@ -1325,38 +1349,57 @@ XLSX.utils.book_append_sheet(wb, ws, ws_name);
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Modifying Cell Values
|
||||||
|
|
||||||
The workbook object contains a `SheetNames` array of names and a `Sheets` object
|
**API**
|
||||||
mapping sheet names to sheet objects. The `XLSX.utils.book_new` utility function
|
|
||||||
creates a new workbook object:
|
_Modify a single cell value in a worksheet_
|
||||||
|
|
||||||
```js
|
```js
|
||||||
/* create a new blank workbook */
|
XLSX.utils.sheet_add_aoa(worksheet, [[new_value]], { origin: address });
|
||||||
var wb = XLSX.utils.book_new();
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The new workbook is blank and contains no worksheets. The write functions will
|
_Modify multiple cell values in a worksheet_
|
||||||
error if the workbook is empty.
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, aoa, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `sheet_add_aoa` utility function modifies cell values in a worksheet. The
|
||||||
|
first argument is the worksheet object. The second argument is an array of
|
||||||
|
arrays of values. The `origin` key of the third argument controls where cells
|
||||||
|
will be written. The following snippet sets `B3=1` and `E5="abc"`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, [
|
||||||
|
[1], // <-- Write 1 to cell B3
|
||||||
|
, // <-- Do nothing in row 4
|
||||||
|
[/*B5*/, /*C5*/, /*D5*/, "abc"] // <-- Write "abc" to cell E5
|
||||||
|
], { origin: "B3" });
|
||||||
|
```
|
||||||
|
|
||||||
|
["Array of Arrays Input"](#array-of-arrays-input) describes the function and the
|
||||||
|
optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
**Examples**
|
||||||
|
|
||||||
|
|
||||||
|
The special origin value `-1` instructs `sheet_add_aoa` to start in column A of
|
||||||
|
the row after the last row in the range, appending the data:
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, [
|
||||||
|
["first row after data", 1],
|
||||||
|
["second row after data", 2]
|
||||||
|
], { origin: -1 });
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Parsing and Writing Examples
|
### Modifying Other Worksheet / Workbook / Cell Properties
|
||||||
|
|
||||||
- <https://sheetjs.com/demos/modify.html> read + modify + write files
|
The ["Common Spreadsheet Format"](#common-spreadsheet-format) section describes
|
||||||
|
the object structures in greater detail.
|
||||||
- <https://github.com/SheetJS/sheetjs/blob/HEAD/bin/xlsx.njs> node
|
|
||||||
|
|
||||||
The node version installs a command line tool `xlsx` which can read spreadsheet
|
|
||||||
files and output the contents in various formats. The source is available at
|
|
||||||
`xlsx.njs` in the bin directory.
|
|
||||||
|
|
||||||
Some helper functions in `XLSX.utils` generate different views of the sheets:
|
|
||||||
|
|
||||||
- `XLSX.utils.sheet_to_csv` generates CSV
|
|
||||||
- `XLSX.utils.sheet_to_txt` generates UTF16 Formatted Text
|
|
||||||
- `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
|
|
||||||
|
|
||||||
## Packaging and Releasing Data
|
## Packaging and Releasing Data
|
||||||
|
|
||||||
@ -1832,6 +1875,45 @@ const S5SComponent = {
|
|||||||
The [`vuejs` demo](demos/vue) includes more React examples.
|
The [`vuejs` demo](demos/vue) includes more React examples.
|
||||||
|
|
||||||
|
|
||||||
|
### Generating Single-Worksheet Snapshots
|
||||||
|
|
||||||
|
The `sheet_to_*` functions accept a worksheet object.
|
||||||
|
|
||||||
|
**API**
|
||||||
|
|
||||||
|
_Generate a CSV from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var csv = XLSX.utils.sheet_to_csv(worksheet, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot is designed to replicate the "CSV UTF8 (`.csv`)" output type.
|
||||||
|
["Delimiter-Separated Output"](#delimiter-separated-output) describes the
|
||||||
|
function and the optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
_Generate "Text" from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var txt = XLSX.utils.sheet_to_txt(worksheet, opts);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot is designed to replicate the "UTF16 Text (`.txt`)" output type.
|
||||||
|
["Delimiter-Separated Output"](#delimiter-separated-output) describes the
|
||||||
|
function and the optional `opts` argument in more detail.
|
||||||
|
|
||||||
|
_Generate a list of formulae from a single worksheet_
|
||||||
|
|
||||||
|
```js
|
||||||
|
var fmla = XLSX.utils.sheet_to_formulae(worksheet);
|
||||||
|
```
|
||||||
|
|
||||||
|
This snapshot generates an array of entries representing the embedded formulae.
|
||||||
|
Array formulae are rendered in the form `range=formula` while plain cells are
|
||||||
|
rendered in the form `cell=formula or value`. String literals are prefixed with
|
||||||
|
an apostrophe `'`, consistent with Excel's formula bar display.
|
||||||
|
|
||||||
|
["Formulae Output"](#formulae-output) describes the function in more detail.
|
||||||
|
|
||||||
## Interface
|
## Interface
|
||||||
|
|
||||||
`XLSX` is the exposed variable in the browser and the exported node variable
|
`XLSX` is the exposed variable in the browser and the exported node variable
|
||||||
@ -1934,6 +2016,7 @@ Cell objects are plain JS objects with keys and values following the convention:
|
|||||||
| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub |
|
| `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub |
|
||||||
| `f` | cell formula encoded as an A1-style string (if applicable) |
|
| `f` | cell formula encoded as an A1-style string (if applicable) |
|
||||||
| `F` | range of enclosing array if formula is array formula (if applicable) |
|
| `F` | range of enclosing array if formula is array formula (if applicable) |
|
||||||
|
| `D` | if true, array formula is dynamic (if applicable) |
|
||||||
| `r` | rich text encoding (if applicable) |
|
| `r` | rich text encoding (if applicable) |
|
||||||
| `h` | HTML rendering of the rich text (if applicable) |
|
| `h` | HTML rendering of the rich text (if applicable) |
|
||||||
| `c` | comments associated with the cell |
|
| `c` | comments associated with the cell |
|
||||||
@ -2261,66 +2344,6 @@ Even though some formats store formulae with a leading equal sign, CSF formulae
|
|||||||
do not start with `=`.
|
do not start with `=`.
|
||||||
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"!ref": "A1:A3",
|
|
||||||
A1: { t:'n', v:1 },
|
|
||||||
A2: { t:'n', v:2 },
|
|
||||||
A3: { t:'n', v:3, f:'A1+A2' }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Shared formulae are decompressed and each cell has the formula corresponding to
|
|
||||||
its cell. Writers generally do not attempt to generate shared formulae.
|
|
||||||
|
|
||||||
Cells with formula entries but no value will be serialized in a way that Excel
|
|
||||||
and other spreadsheet tools will recognize. This library will not automatically
|
|
||||||
compute formula results! For example, to compute `BESSELJ` in a worksheet:
|
|
||||||
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
"!ref": "A1:A3",
|
|
||||||
A1: { t:'n', v:3.14159 },
|
|
||||||
A2: { t:'n', v:2 },
|
|
||||||
A3: { t:'n', f:'BESSELJ(A1,A2)' }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Array Formulae**
|
|
||||||
|
|
||||||
Array formulae are stored in the top-left cell of the array block. All cells
|
|
||||||
of an array formula have a `F` field corresponding to the range. A single-cell
|
|
||||||
formula can be distinguished from a plain formula by the presence of `F` field.
|
|
||||||
|
|
||||||
|
|
||||||
For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" };
|
|
||||||
```
|
|
||||||
|
|
||||||
For a multi-cell array formula, every cell has the same array range but only the
|
|
||||||
first cell specifies the formula. Consider `D1:D3=A1:A3*B1:B3`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" };
|
|
||||||
worksheet['D2'] = { t:'n', F:"D1:D3" };
|
|
||||||
worksheet['D3'] = { t:'n', F:"D1:D3" };
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Utilities and writers are expected to check for the presence of a `F` field and
|
|
||||||
ignore any possible formula element `f` in cells other than the starting cell.
|
|
||||||
They are not expected to perform validation of the formulae!
|
|
||||||
|
|
||||||
|
|
||||||
The `sheet_to_formulae` method generates one line per formula or array formula.
|
|
||||||
Array formulae are rendered in the form `range=formula` while plain cells are
|
|
||||||
rendered in the form `cell=formula or value`. Note that string literals are
|
|
||||||
prefixed with an apostrophe `'`, consistent with Excel's formula bar display.
|
|
||||||
|
|
||||||
|
|
||||||
| Storage Representation | Formats | Read | Write |
|
| Storage Representation | Formats | Read | Write |
|
||||||
|:-----------------------|:-------------------------|:-----:|:-----:|
|
|:-----------------------|:-------------------------|:-----:|:-----:|
|
||||||
| A1-style strings | XLSX | ✔ | ✔ |
|
| A1-style strings | XLSX | ✔ | ✔ |
|
||||||
@ -2334,6 +2357,269 @@ cell references, a (not-so-simple) regex conversion is possible. BIFF Parsed
|
|||||||
formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula
|
formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula
|
||||||
formulae can be converted with regular expressions.
|
formulae can be converted with regular expressions.
|
||||||
|
|
||||||
|
Shared formulae are decompressed and each cell has the formula corresponding to
|
||||||
|
its cell. Writers generally do not attempt to generate shared formulae.
|
||||||
|
|
||||||
|
**Single-Cell Formulae**
|
||||||
|
|
||||||
|
For simple formulae, the `f` key of the desired cell can be set to the actual
|
||||||
|
formula text. This worksheet represents `A1=1`, `A2=2`, and `A3=A1+A2`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = {
|
||||||
|
"!ref": "A1:A3",
|
||||||
|
A1: { t:'n', v:1 },
|
||||||
|
A2: { t:'n', v:2 },
|
||||||
|
A3: { t:'n', v:3, f:'A1+A2' }
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Utilities like `aoa_to_sheet` will accept cell objects in lieu of values:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
[ 1 ], // A1
|
||||||
|
[ 2 ], // A2
|
||||||
|
[ {t: "n", v: 3, f: "A1+A2"} ] // A3
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Cells with formula entries but no value will be serialized in a way that Excel
|
||||||
|
and other spreadsheet tools will recognize. This library will not automatically
|
||||||
|
compute formula results! For example, the following worksheet will include the
|
||||||
|
`BESSELJ` function but the result will not be available in JavaScript:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var worksheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
[ 3.14159, 2 ], // Row "1"
|
||||||
|
[ { t:'n', f:'BESSELJ(A1,B1)' } ] // Row "2" will be calculated on file open
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the actual results are needed in JS, [SheetJS Pro](https://sheetjs.com/pro)
|
||||||
|
offers a formula calculator component for evaluating expressions, updating
|
||||||
|
values and dependent cells, and refreshing entire workbooks.
|
||||||
|
|
||||||
|
|
||||||
|
**Array Formulae**
|
||||||
|
|
||||||
|
_Assign an array formula_
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, range, formula);
|
||||||
|
```
|
||||||
|
|
||||||
|
Array formulae are stored in the top-left cell of the array block. All cells
|
||||||
|
of an array formula have a `F` field corresponding to the range. A single-cell
|
||||||
|
formula can be distinguished from a plain formula by the presence of `F` field.
|
||||||
|
|
||||||
|
For example, setting the cell `C1` to the array formula `{=SUM(A1:A3*B1:B3)}`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "SUM(A1:A3*B1:B3)");
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['C1'] = { t:'n', f: "SUM(A1:A3*B1:B3)", F:"C1:C1" };
|
||||||
|
```
|
||||||
|
|
||||||
|
For a multi-cell array formula, every cell has the same array range but only the
|
||||||
|
first cell specifies the formula. Consider `D1:D3=A1:A3*B1:B3`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "D1:D3", "A1:A3*B1:B3");
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['D1'] = { t:'n', F:"D1:D3", f:"A1:A3*B1:B3" };
|
||||||
|
worksheet['D2'] = { t:'n', F:"D1:D3" };
|
||||||
|
worksheet['D3'] = { t:'n', F:"D1:D3" };
|
||||||
|
```
|
||||||
|
|
||||||
|
Utilities and writers are expected to check for the presence of a `F` field and
|
||||||
|
ignore any possible formula element `f` in cells other than the starting cell.
|
||||||
|
They are not expected to perform validation of the formulae!
|
||||||
|
|
||||||
|
|
||||||
|
**Dynamic Array Formulae**
|
||||||
|
|
||||||
|
_Assign a dynamic array formula_
|
||||||
|
|
||||||
|
```js
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, range, formula, true);
|
||||||
|
```
|
||||||
|
|
||||||
|
Released in 2020, Dynamic Array Formulae are supported in the XLSX/XLSM and XLSB
|
||||||
|
file formats. They are represented like normal array formulae but have special
|
||||||
|
cell metadata indicating that the formula should be allowed to adjust the range.
|
||||||
|
|
||||||
|
An array formula can be marked as dynamic by setting the cell's `D` property to
|
||||||
|
true. The `F` range is expected but can be the set to the current cell:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// API function
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1);
|
||||||
|
|
||||||
|
// ... OR raw operations
|
||||||
|
worksheet['C1'] = { t: "s", f: "_xlfn.UNIQUE(A1:A3)", F:"C1", D: 1 }; // dynamic
|
||||||
|
```
|
||||||
|
|
||||||
|
**Localization with Function Names**
|
||||||
|
|
||||||
|
SheetJS operates at the file level. Excel stores formula expressions using the
|
||||||
|
English (United States) function names. For non-English users, Excel uses a
|
||||||
|
localized set of function names.
|
||||||
|
|
||||||
|
For example, when the computer language and region is set to French (France),
|
||||||
|
Excel interprets `=SOMME(A1:C3)` as if `SOMME` is the `SUM` function. However,
|
||||||
|
in the actual file, Excel stores `SUM(A1:C3)`.
|
||||||
|
|
||||||
|
**Prefixed "Future Functions"**
|
||||||
|
|
||||||
|
Functions introduced in newer versions of Excel are prefixed with `_xlfn.` when
|
||||||
|
stored in files. When writing formula expressions using these functions, the
|
||||||
|
prefix is required for maximal compatibility:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// Broadest compatibility
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "_xlfn.UNIQUE(A1:A3)", 1);
|
||||||
|
|
||||||
|
// Can cause errors in spreadsheet software
|
||||||
|
XLSX.utils.sheet_set_array_formula(worksheet, "C1", "UNIQUE(A1:A3)", 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
When reading a file, the `xlfn` option preserves the prefixes.
|
||||||
|
|
||||||
|
|
||||||
|
This list is growing with each Excel release.
|
||||||
|
|
||||||
|
```
|
||||||
|
ACOT
|
||||||
|
ACOTH
|
||||||
|
AGGREGATE
|
||||||
|
ARABIC
|
||||||
|
BASE
|
||||||
|
BETA.DIST
|
||||||
|
BETA.INV
|
||||||
|
BINOM.DIST
|
||||||
|
BINOM.DIST.RANGE
|
||||||
|
BINOM.INV
|
||||||
|
BITAND
|
||||||
|
BITLSHIFT
|
||||||
|
BITOR
|
||||||
|
BITRSHIFT
|
||||||
|
BITXOR
|
||||||
|
BYCOL
|
||||||
|
BYROW
|
||||||
|
CEILING.MATH
|
||||||
|
CEILING.PRECISE
|
||||||
|
CHISQ.DIST
|
||||||
|
CHISQ.DIST.RT
|
||||||
|
CHISQ.INV
|
||||||
|
CHISQ.INV.RT
|
||||||
|
CHISQ.TEST
|
||||||
|
COMBINA
|
||||||
|
CONFIDENCE.NORM
|
||||||
|
CONFIDENCE.T
|
||||||
|
COT
|
||||||
|
COTH
|
||||||
|
COVARIANCE.P
|
||||||
|
COVARIANCE.S
|
||||||
|
CSC
|
||||||
|
CSCH
|
||||||
|
DAYS
|
||||||
|
DECIMAL
|
||||||
|
ERF.PRECISE
|
||||||
|
ERFC.PRECISE
|
||||||
|
EXPON.DIST
|
||||||
|
F.DIST
|
||||||
|
F.DIST.RT
|
||||||
|
F.INV
|
||||||
|
F.INV.RT
|
||||||
|
F.TEST
|
||||||
|
FIELDVALUE
|
||||||
|
FILTERXML
|
||||||
|
FLOOR.MATH
|
||||||
|
FLOOR.PRECISE
|
||||||
|
FORMULATEXT
|
||||||
|
GAMMA
|
||||||
|
GAMMA.DIST
|
||||||
|
GAMMA.INV
|
||||||
|
GAMMALN.PRECISE
|
||||||
|
GAUSS
|
||||||
|
HYPGEOM.DIST
|
||||||
|
IFNA
|
||||||
|
IMCOSH
|
||||||
|
IMCOT
|
||||||
|
IMCSC
|
||||||
|
IMCSCH
|
||||||
|
IMSEC
|
||||||
|
IMSECH
|
||||||
|
IMSINH
|
||||||
|
IMTAN
|
||||||
|
ISFORMULA
|
||||||
|
ISOMITTED
|
||||||
|
ISOWEEKNUM
|
||||||
|
LAMBDA
|
||||||
|
LET
|
||||||
|
LOGNORM.DIST
|
||||||
|
LOGNORM.INV
|
||||||
|
MAKEARRAY
|
||||||
|
MAP
|
||||||
|
MODE.MULT
|
||||||
|
MODE.SNGL
|
||||||
|
MUNIT
|
||||||
|
NEGBINOM.DIST
|
||||||
|
NORM.DIST
|
||||||
|
NORM.INV
|
||||||
|
NORM.S.DIST
|
||||||
|
NORM.S.INV
|
||||||
|
NUMBERVALUE
|
||||||
|
PDURATION
|
||||||
|
PERCENTILE.EXC
|
||||||
|
PERCENTILE.INC
|
||||||
|
PERCENTRANK.EXC
|
||||||
|
PERCENTRANK.INC
|
||||||
|
PERMUTATIONA
|
||||||
|
PHI
|
||||||
|
POISSON.DIST
|
||||||
|
QUARTILE.EXC
|
||||||
|
QUARTILE.INC
|
||||||
|
QUERYSTRING
|
||||||
|
RANDARRAY
|
||||||
|
RANK.AVG
|
||||||
|
RANK.EQ
|
||||||
|
REDUCE
|
||||||
|
RRI
|
||||||
|
SCAN
|
||||||
|
SEC
|
||||||
|
SECH
|
||||||
|
SEQUENCE
|
||||||
|
SHEET
|
||||||
|
SHEETS
|
||||||
|
SKEW.P
|
||||||
|
SORTBY
|
||||||
|
STDEV.P
|
||||||
|
STDEV.S
|
||||||
|
T.DIST
|
||||||
|
T.DIST.2T
|
||||||
|
T.DIST.RT
|
||||||
|
T.INV
|
||||||
|
T.INV.2T
|
||||||
|
T.TEST
|
||||||
|
UNICHAR
|
||||||
|
UNICODE
|
||||||
|
UNIQUE
|
||||||
|
VAR.P
|
||||||
|
VAR.S
|
||||||
|
WEBSERVICE
|
||||||
|
WEIBULL.DIST
|
||||||
|
XLOOKUP
|
||||||
|
XOR
|
||||||
|
Z.TEST
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Row and Column Properties
|
#### Row and Column Properties
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,14 +10,17 @@
|
|||||||
* [Parsing Workbooks](README.md#parsing-workbooks)
|
* [Parsing Workbooks](README.md#parsing-workbooks)
|
||||||
* [Processing JSON and JS Data](README.md#processing-json-and-js-data)
|
* [Processing JSON and JS Data](README.md#processing-json-and-js-data)
|
||||||
* [Processing HTML Tables](README.md#processing-html-tables)
|
* [Processing HTML Tables](README.md#processing-html-tables)
|
||||||
- [Working with the Workbook](README.md#working-with-the-workbook)
|
- [Processing Data](README.md#processing-data)
|
||||||
* [Parsing and Writing Examples](README.md#parsing-and-writing-examples)
|
* [Modifying Workbook Structure](README.md#modifying-workbook-structure)
|
||||||
|
* [Modifying Cell Values](README.md#modifying-cell-values)
|
||||||
|
* [Modifying Other Worksheet / Workbook / Cell Properties](README.md#modifying-other-worksheet--workbook--cell-properties)
|
||||||
- [Packaging and Releasing Data](README.md#packaging-and-releasing-data)
|
- [Packaging and Releasing Data](README.md#packaging-and-releasing-data)
|
||||||
* [Writing Workbooks](README.md#writing-workbooks)
|
* [Writing Workbooks](README.md#writing-workbooks)
|
||||||
* [Writing Examples](README.md#writing-examples)
|
* [Writing Examples](README.md#writing-examples)
|
||||||
* [Streaming Write](README.md#streaming-write)
|
* [Streaming Write](README.md#streaming-write)
|
||||||
* [Generating JSON and JS Data](README.md#generating-json-and-js-data)
|
* [Generating JSON and JS Data](README.md#generating-json-and-js-data)
|
||||||
* [Generating HTML Tables](README.md#generating-html-tables)
|
* [Generating HTML Tables](README.md#generating-html-tables)
|
||||||
|
* [Generating Single-Worksheet Snapshots](README.md#generating-single-worksheet-snapshots)
|
||||||
- [Interface](README.md#interface)
|
- [Interface](README.md#interface)
|
||||||
* [Parsing functions](README.md#parsing-functions)
|
* [Parsing functions](README.md#parsing-functions)
|
||||||
* [Writing functions](README.md#writing-functions)
|
* [Writing functions](README.md#writing-functions)
|
||||||
|
@ -38,6 +38,7 @@ bits/47_styxml.js
|
|||||||
bits/48_stybin.js
|
bits/48_stybin.js
|
||||||
bits/49_theme.js
|
bits/49_theme.js
|
||||||
bits/50_styxls.js
|
bits/50_styxls.js
|
||||||
|
bits/51_xlmeta.js
|
||||||
bits/52_calcchain.js
|
bits/52_calcchain.js
|
||||||
bits/53_externlink.js
|
bits/53_externlink.js
|
||||||
bits/54_drawing.js
|
bits/54_drawing.js
|
||||||
|
151
modules/51_xlmeta.js
Normal file
151
modules/51_xlmeta.js
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
function parse_xlmeta_xml(data, name, opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
if (!data)
|
||||||
|
return out;
|
||||||
|
var pass = false;
|
||||||
|
data.replace(tagregex, function(x, idx) {
|
||||||
|
var y = parsexmltag(x);
|
||||||
|
switch (strip_ns(y[0])) {
|
||||||
|
case "<?xml":
|
||||||
|
break;
|
||||||
|
case "<metadata":
|
||||||
|
case "</metadata>":
|
||||||
|
break;
|
||||||
|
case "<metadataTypes":
|
||||||
|
case "</metadataTypes>":
|
||||||
|
break;
|
||||||
|
case "<metadataType":
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
case "<futureMetadata":
|
||||||
|
break;
|
||||||
|
case "</futureMetadata>":
|
||||||
|
break;
|
||||||
|
case "<bk>":
|
||||||
|
break;
|
||||||
|
case "</bk>":
|
||||||
|
break;
|
||||||
|
case "<rc":
|
||||||
|
break;
|
||||||
|
case "</rc>":
|
||||||
|
break;
|
||||||
|
case "<cellMetadata":
|
||||||
|
case "</cellMetadata>":
|
||||||
|
break;
|
||||||
|
case "<valueMetadata":
|
||||||
|
break;
|
||||||
|
case "</valueMetadata>":
|
||||||
|
break;
|
||||||
|
case "<extLst":
|
||||||
|
case "<extLst>":
|
||||||
|
case "</extLst>":
|
||||||
|
case "<extLst/>":
|
||||||
|
break;
|
||||||
|
case "<ext":
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case "</ext>":
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!pass && opts.WTF)
|
||||||
|
throw new Error("unrecognized " + y[0] + " in metadata");
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_xml() {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
|
||||||
|
return o.join("");
|
||||||
|
}
|
||||||
|
function parse_BrtMdtinfo(data, length) {
|
||||||
|
return {
|
||||||
|
flags: data.read_shift(4),
|
||||||
|
version: data.read_shift(4),
|
||||||
|
name: parse_XLWideString(data, length - 8)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function write_BrtMdtinfo(data) {
|
||||||
|
var o = new_buf(12 + 2 * data.name.length);
|
||||||
|
o.write_shift(4, data.flags);
|
||||||
|
o.write_shift(4, data.version);
|
||||||
|
write_XLWideString(data.name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtMdb(mdb) {
|
||||||
|
var o = new_buf(4 + 8 * mdb.length);
|
||||||
|
o.write_shift(4, mdb.length);
|
||||||
|
for (var i = 0; i < mdb.length; ++i) {
|
||||||
|
o.write_shift(4, mdb[i][0]);
|
||||||
|
o.write_shift(4, mdb[i][1]);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsfmd(cnt, name) {
|
||||||
|
var o = new_buf(8 + 2 * name.length);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
write_XLWideString(name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsmdb(cnt, cm) {
|
||||||
|
var o = new_buf(8);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
o.write_shift(4, cm ? 1 : 0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function parse_xlmeta_bin(data, name, _opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
var opts = _opts || {};
|
||||||
|
var state = [];
|
||||||
|
var pass = false;
|
||||||
|
recordhopper(data, function(val, R_n, RT) {
|
||||||
|
switch (RT) {
|
||||||
|
case 335:
|
||||||
|
out.Types.push({ name: val.name });
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.push(R_n);
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.pop();
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((R_n || "").indexOf("Begin") > 0) {
|
||||||
|
} else if ((R_n || "").indexOf("End") > 0) {
|
||||||
|
} else if (!pass || opts.WTF && state[state.length - 1] != "BrtFRTBegin")
|
||||||
|
throw new Error("Unexpected record " + RT + " " + R_n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_bin() {
|
||||||
|
var ba = buf_array();
|
||||||
|
write_record(ba, "BrtBeginMetadata");
|
||||||
|
write_record(ba, "BrtBeginEsmdtinfo", write_UInt32LE(1));
|
||||||
|
write_record(ba, "BrtMdtinfo", write_BrtMdtinfo({
|
||||||
|
name: "XLDAPR",
|
||||||
|
version: 12e4,
|
||||||
|
flags: 3496657072
|
||||||
|
}));
|
||||||
|
write_record(ba, "BrtEndEsmdtinfo");
|
||||||
|
write_record(ba, "BrtBeginEsfmd", write_BrtBeginEsfmd(1, "XLDAPR"));
|
||||||
|
write_record(ba, "BrtBeginFmd");
|
||||||
|
write_record(ba, "BrtFRTBegin", write_UInt32LE(514));
|
||||||
|
write_record(ba, "BrtBeginDynamicArrayPr", write_UInt32LE(0));
|
||||||
|
write_record(ba, "BrtEndDynamicArrayPr", writeuint16(1));
|
||||||
|
write_record(ba, "BrtFRTEnd");
|
||||||
|
write_record(ba, "BrtEndFmd");
|
||||||
|
write_record(ba, "BrtEndEsfmd");
|
||||||
|
write_record(ba, "BrtBeginEsmdb", write_BrtBeginEsmdb(1, true));
|
||||||
|
write_record(ba, "BrtMdb", write_BrtMdb([[1, 0]]));
|
||||||
|
write_record(ba, "BrtEndEsmdb");
|
||||||
|
write_record(ba, "BrtEndMetadata");
|
||||||
|
return ba.end();
|
||||||
|
}
|
88
modules/51_xlsbmeta.js
Normal file
88
modules/51_xlsbmeta.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
function parse_BrtMdtinfo(data, length) {
|
||||||
|
return {
|
||||||
|
flags: data.read_shift(4),
|
||||||
|
version: data.read_shift(4),
|
||||||
|
name: parse_XLWideString(data, length - 8)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function write_BrtMdtinfo(data) {
|
||||||
|
var o = new_buf(12 + 2 * data.name.length);
|
||||||
|
o.write_shift(4, data.flags);
|
||||||
|
o.write_shift(4, data.version);
|
||||||
|
write_XLWideString(data.name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtMdb(mdb) {
|
||||||
|
var o = new_buf(4 + 8 * mdb.length);
|
||||||
|
o.write_shift(4, mdb.length);
|
||||||
|
for (var i = 0; i < mdb.length; ++i) {
|
||||||
|
o.write_shift(4, mdb[i][0]);
|
||||||
|
o.write_shift(4, mdb[i][1]);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsfmd(cnt, name) {
|
||||||
|
var o = new_buf(8 + 2 * name.length);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
write_XLWideString(name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsmdb(cnt, cm) {
|
||||||
|
var o = new_buf(8);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
o.write_shift(4, cm ? 1 : 0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function parse_xlmeta_bin(data, name, _opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
var opts = _opts || {};
|
||||||
|
var state = [];
|
||||||
|
var pass = false;
|
||||||
|
recordhopper(data, function(val, R_n, RT) {
|
||||||
|
switch (RT) {
|
||||||
|
case 335:
|
||||||
|
out.Types.push({ name: val.name });
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.push(R_n);
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.pop();
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((R_n || "").indexOf("Begin") > 0) {
|
||||||
|
} else if ((R_n || "").indexOf("End") > 0) {
|
||||||
|
} else if (!pass || opts.WTF && state[state.length - 1] != "BrtFRTBegin")
|
||||||
|
throw new Error("Unexpected record " + RT + " " + R_n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_bin() {
|
||||||
|
var ba = buf_array();
|
||||||
|
write_record(ba, "BrtBeginMetadata");
|
||||||
|
write_record(ba, "BrtBeginEsmdtinfo", write_UInt32LE(1));
|
||||||
|
write_record(ba, "BrtMdtinfo", write_BrtMdtinfo({
|
||||||
|
name: "XLDAPR",
|
||||||
|
version: 12e4,
|
||||||
|
flags: 3496657072
|
||||||
|
}));
|
||||||
|
write_record(ba, "BrtEndEsmdtinfo");
|
||||||
|
write_record(ba, "BrtBeginEsfmd", write_BrtBeginEsfmd(1, "XLDAPR"));
|
||||||
|
write_record(ba, "BrtBeginFmd");
|
||||||
|
write_record(ba, "BrtFRTBegin", write_UInt32LE(514));
|
||||||
|
write_record(ba, "BrtBeginDynamicArrayPr", write_UInt32LE(0));
|
||||||
|
write_record(ba, "BrtEndDynamicArrayPr", writeuint16(1));
|
||||||
|
write_record(ba, "BrtFRTEnd");
|
||||||
|
write_record(ba, "BrtEndFmd");
|
||||||
|
write_record(ba, "BrtEndEsfmd");
|
||||||
|
write_record(ba, "BrtBeginEsmdb", write_BrtBeginEsmdb(1, true));
|
||||||
|
write_record(ba, "BrtMdb", write_BrtMdb([[1, 0]]));
|
||||||
|
write_record(ba, "BrtEndEsmdb");
|
||||||
|
write_record(ba, "BrtEndMetadata");
|
||||||
|
return ba.end();
|
||||||
|
}
|
120
modules/51_xlsbmeta.ts
Normal file
120
modules/51_xlsbmeta.ts
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/// <reference path="src/types.ts"/>
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.698 BrtMdtinfo */
|
||||||
|
interface BrtMdtinfo {
|
||||||
|
flags: number;
|
||||||
|
version: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
function parse_BrtMdtinfo(data: ReadableData, length: number): BrtMdtinfo {
|
||||||
|
return {
|
||||||
|
flags: data.read_shift(4),
|
||||||
|
version: data.read_shift(4),
|
||||||
|
name: parse_XLWideString(data, length - 8)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function write_BrtMdtinfo(data: BrtMdtinfo): RawData {
|
||||||
|
var o = new_buf(12 + 2 * data.name.length);
|
||||||
|
o.write_shift(4, data.flags);
|
||||||
|
o.write_shift(4, data.version);
|
||||||
|
write_XLWideString(data.name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.697 BrtMdb */
|
||||||
|
type Mdir = [number, number]; // "t", "v" in XLSX parlance
|
||||||
|
type BrtMdb = Mdir[];
|
||||||
|
function write_BrtMdb(mdb: BrtMdb): RawData {
|
||||||
|
var o = new_buf(4 + 8 * mdb.length);
|
||||||
|
o.write_shift(4, mdb.length);
|
||||||
|
for(var i = 0; i < mdb.length; ++i) {
|
||||||
|
o.write_shift(4, mdb[i][0]);
|
||||||
|
o.write_shift(4, mdb[i][1]);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.72 BrtBeginEsfmd */
|
||||||
|
function write_BrtBeginEsfmd(cnt: number, name: string): RawData {
|
||||||
|
var o = new_buf(8 + 2 * name.length);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
write_XLWideString(name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.4.73 BrtBeginEsmdb */
|
||||||
|
function write_BrtBeginEsmdb(cnt: number, cm: boolean): RawData {
|
||||||
|
var o = new_buf(8);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
o.write_shift(4, cm ? 1 : 0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [MS-XLSB] 2.1.7.34 Metadata */
|
||||||
|
function parse_xlmeta_bin(data, name: string, _opts?: ParseXLMetaOptions): XLMeta {
|
||||||
|
var out: XLMeta = { Types: [] };
|
||||||
|
var opts = _opts || {};
|
||||||
|
var state: string[] = [];
|
||||||
|
var pass = false;
|
||||||
|
|
||||||
|
recordhopper(data, (val, R_n, RT) => {
|
||||||
|
switch(RT) {
|
||||||
|
// case 0x014C: /* 'BrtBeginMetadata' */
|
||||||
|
// case 0x014D: /* 'BrtEndMetadata' */
|
||||||
|
// case 0x014E: /* 'BrtBeginEsmdtinfo' */
|
||||||
|
// case 0x0150: /* 'BrtEndEsmdtinfo' */
|
||||||
|
// case 0x0151: /* 'BrtBeginEsmdb' */
|
||||||
|
// case 0x0152: /* 'BrtEndEsmdb' */
|
||||||
|
// case 0x0153: /* 'BrtBeginEsfmd' */
|
||||||
|
// case 0x0154: /* 'BrtEndEsfmd' */
|
||||||
|
// case 0x0034: /* 'BrtBeginFmd' */
|
||||||
|
// case 0x0035: /* 'BrtEndFmd' */
|
||||||
|
// case 0x1000: /* 'BrtBeginDynamicArrayPr' */
|
||||||
|
// case 0x1001: /* 'BrtEndDynamicArrayPr' */
|
||||||
|
// case 0x138A: /* 'BrtBeginRichValueBlock' */
|
||||||
|
// case 0x138B: /* 'BrtEndRichValueBlock' */
|
||||||
|
|
||||||
|
case 0x014F: /* 'BrtMdtinfo' */
|
||||||
|
out.Types.push({name: (val as BrtMdtinfo).name});
|
||||||
|
break;
|
||||||
|
case 0x0033: /* 'BrtMdb' */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x0023: /* 'BrtFRTBegin' */
|
||||||
|
state.push(R_n); pass = true; break;
|
||||||
|
case 0x0024: /* 'BrtFRTEnd' */
|
||||||
|
state.pop(); pass = false; break;
|
||||||
|
default:
|
||||||
|
if((R_n||"").indexOf("Begin") > 0){/* empty */}
|
||||||
|
else if((R_n||"").indexOf("End") > 0){/* empty */}
|
||||||
|
else if(!pass || (opts.WTF && state[state.length-1] != "BrtFRTBegin")) throw new Error("Unexpected record " + RT + " " + R_n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_bin() {
|
||||||
|
var ba = buf_array();
|
||||||
|
write_record(ba, "BrtBeginMetadata");
|
||||||
|
write_record(ba, "BrtBeginEsmdtinfo", write_UInt32LE(1));
|
||||||
|
write_record(ba, "BrtMdtinfo", write_BrtMdtinfo({
|
||||||
|
name: "XLDAPR",
|
||||||
|
version: 120000,
|
||||||
|
flags: 0xD06AC0B0
|
||||||
|
}));
|
||||||
|
write_record(ba, "BrtEndEsmdtinfo");
|
||||||
|
/* [ESSTR] [ESMDX] */
|
||||||
|
write_record(ba, "BrtBeginEsfmd", write_BrtBeginEsfmd(1, "XLDAPR"));
|
||||||
|
write_record(ba, "BrtBeginFmd");
|
||||||
|
write_record(ba, "BrtFRTBegin", write_UInt32LE(0x0202));
|
||||||
|
write_record(ba, "BrtBeginDynamicArrayPr", write_UInt32LE(0));
|
||||||
|
write_record(ba, "BrtEndDynamicArrayPr", writeuint16(1));
|
||||||
|
write_record(ba, "BrtFRTEnd");
|
||||||
|
write_record(ba, "BrtEndFmd");
|
||||||
|
write_record(ba, "BrtEndEsfmd");
|
||||||
|
write_record(ba, "BrtBeginEsmdb", write_BrtBeginEsmdb(1, true));
|
||||||
|
write_record(ba, "BrtMdb", write_BrtMdb([[1, 0]]));
|
||||||
|
write_record(ba, "BrtEndEsmdb");
|
||||||
|
/* *FRT */
|
||||||
|
write_record(ba, "BrtEndMetadata");
|
||||||
|
return ba.end();
|
||||||
|
}
|
63
modules/51_xlsxmeta.js
Normal file
63
modules/51_xlsxmeta.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
function parse_xlmeta_xml(data, name, opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
if (!data)
|
||||||
|
return out;
|
||||||
|
var pass = false;
|
||||||
|
data.replace(tagregex, function(x, idx) {
|
||||||
|
var y = parsexmltag(x);
|
||||||
|
switch (strip_ns(y[0])) {
|
||||||
|
case "<?xml":
|
||||||
|
break;
|
||||||
|
case "<metadata":
|
||||||
|
case "</metadata>":
|
||||||
|
break;
|
||||||
|
case "<metadataTypes":
|
||||||
|
case "</metadataTypes>":
|
||||||
|
break;
|
||||||
|
case "<metadataType":
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
case "<futureMetadata":
|
||||||
|
break;
|
||||||
|
case "</futureMetadata>":
|
||||||
|
break;
|
||||||
|
case "<bk>":
|
||||||
|
break;
|
||||||
|
case "</bk>":
|
||||||
|
break;
|
||||||
|
case "<rc":
|
||||||
|
break;
|
||||||
|
case "</rc>":
|
||||||
|
break;
|
||||||
|
case "<cellMetadata":
|
||||||
|
case "</cellMetadata>":
|
||||||
|
break;
|
||||||
|
case "<valueMetadata":
|
||||||
|
break;
|
||||||
|
case "</valueMetadata>":
|
||||||
|
break;
|
||||||
|
case "<extLst":
|
||||||
|
case "<extLst>":
|
||||||
|
case "</extLst>":
|
||||||
|
case "<extLst/>":
|
||||||
|
break;
|
||||||
|
case "<ext":
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case "</ext>":
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!pass && opts.WTF)
|
||||||
|
throw new Error("unrecognized " + y[0] + " in metadata");
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_xml() {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
|
||||||
|
return o.join("");
|
||||||
|
}
|
85
modules/51_xlsxmeta.ts
Normal file
85
modules/51_xlsxmeta.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/// <reference path="src/types.ts"/>
|
||||||
|
|
||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
|
||||||
|
/* 12.3.10 Metadata Part */
|
||||||
|
function parse_xlmeta_xml(data: string, name: string, opts?: ParseXLMetaOptions): XLMeta {
|
||||||
|
var out: XLMeta = { Types: [] };
|
||||||
|
if(!data) return out;
|
||||||
|
var pass = false;
|
||||||
|
|
||||||
|
data.replace(tagregex, (x: string, idx: number) => {
|
||||||
|
var y: any = parsexmltag(x);
|
||||||
|
switch(strip_ns(y[0])) {
|
||||||
|
case '<?xml': break;
|
||||||
|
|
||||||
|
/* 18.9.8 */
|
||||||
|
case '<metadata': case '</metadata>': break;
|
||||||
|
|
||||||
|
/* 18.9.11 */
|
||||||
|
case '<metadataTypes': case '</metadataTypes>': break;
|
||||||
|
|
||||||
|
/* 18.9.10 */
|
||||||
|
case '<metadataType':
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* 18.9.4 */
|
||||||
|
case '<futureMetadata': break;
|
||||||
|
case '</futureMetadata>': break;
|
||||||
|
|
||||||
|
/* 18.9.1 */
|
||||||
|
case '<bk>': break;
|
||||||
|
case '</bk>': break;
|
||||||
|
|
||||||
|
/* 18.9.15 */
|
||||||
|
case '<rc': break;
|
||||||
|
case '</rc>': break;
|
||||||
|
|
||||||
|
/* 18.9.3 */
|
||||||
|
case '<cellMetadata':
|
||||||
|
case '</cellMetadata>': break;
|
||||||
|
|
||||||
|
/* 18.9.17 */
|
||||||
|
case '<valueMetadata': break;
|
||||||
|
case '</valueMetadata>': break;
|
||||||
|
|
||||||
|
/* 18.2.10 extLst CT_ExtensionList ? */
|
||||||
|
case '<extLst': case '<extLst>': case '</extLst>': case '<extLst/>': break;
|
||||||
|
|
||||||
|
/* 18.2.7 ext CT_Extension + */
|
||||||
|
case '<ext': pass=true; break; //TODO: check with versions of excel
|
||||||
|
case '</ext>': pass=false; break;
|
||||||
|
|
||||||
|
default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in metadata');
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
/* TODO: coordinate with cell writing, pass flags */
|
||||||
|
function write_xlmeta_xml(): string {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push(`\
|
||||||
|
<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">
|
||||||
|
<metadataTypes count="1">
|
||||||
|
<metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>
|
||||||
|
</metadataTypes>
|
||||||
|
<futureMetadata name="XLDAPR" count="1">
|
||||||
|
<bk>
|
||||||
|
<extLst>
|
||||||
|
<ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">
|
||||||
|
<xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>
|
||||||
|
</ext>
|
||||||
|
</extLst>
|
||||||
|
</bk>
|
||||||
|
</futureMetadata>
|
||||||
|
<cellMetadata count="1">
|
||||||
|
<bk>
|
||||||
|
<rc t="1" v="0"/>
|
||||||
|
</bk>
|
||||||
|
</cellMetadata>
|
||||||
|
</metadata>`);
|
||||||
|
|
||||||
|
return o.join("");
|
||||||
|
}
|
@ -2,10 +2,13 @@ LIBFILES=$(wildcard src/*.ts)
|
|||||||
TSFILES=$(wildcard *.ts)
|
TSFILES=$(wildcard *.ts)
|
||||||
ENTRIES=$(subst .ts,.js,$(TSFILES))
|
ENTRIES=$(subst .ts,.js,$(TSFILES))
|
||||||
|
|
||||||
BAREJS=04_base64.js 59_vba.js 64_ftab.js
|
BAREJS=04_base64.js 51_xlsxmeta.js 51_xlsbmeta.js 59_vba.js 64_ftab.js
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: $(ENTRIES)
|
all: $(ENTRIES) 51_xlmeta.js
|
||||||
|
|
||||||
|
51_xlmeta.js: 51_xlsxmeta.js 51_xlsbmeta.js
|
||||||
|
cat $^ > $@
|
||||||
|
|
||||||
$(BAREJS): %.js: %.ts $(LIBFILES)
|
$(BAREJS): %.js: %.ts $(LIBFILES)
|
||||||
npx esbuild $< --outfile=$@ --platform=browser --target=es5
|
npx esbuild $< --outfile=$@ --platform=browser --target=es5
|
||||||
|
44
modules/src/types.ts
Normal file
44
modules/src/types.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
declare type RawData = Uint8Array | number[];
|
||||||
|
declare function recordhopper(data: RawData, cb:(val: any, R_n: string, RT: number)=>void): void;
|
||||||
|
declare interface ReadableData {
|
||||||
|
l: number;
|
||||||
|
read_shift(t: 4): number;
|
||||||
|
read_shift(t: any): any;
|
||||||
|
}
|
||||||
|
declare type ParseFunc<T> = (data: ReadableData, length: number) => T;
|
||||||
|
declare var parse_XLWideString: ParseFunc<string>;
|
||||||
|
|
||||||
|
declare interface WritableData {
|
||||||
|
l: number;
|
||||||
|
write_shift(t: 4, val: number): void;
|
||||||
|
write_shift(t: number, val: string|number, f?: string): any;
|
||||||
|
}
|
||||||
|
declare type WritableRawData = WritableData & RawData;
|
||||||
|
interface BufArray {
|
||||||
|
end(): RawData;
|
||||||
|
next(sz: number): WritableData;
|
||||||
|
push(buf: RawData): void;
|
||||||
|
}
|
||||||
|
declare function buf_array(): BufArray;
|
||||||
|
declare function write_record(ba: BufArray, type: string, payload?: RawData, length?: number): void;
|
||||||
|
declare function new_buf(sz: number): RawData & WritableData & ReadableData;
|
||||||
|
|
||||||
|
declare var tagregex: RegExp;
|
||||||
|
declare var XML_HEADER: string;
|
||||||
|
declare var RELS: any;
|
||||||
|
declare function parsexmltag(tag: string, skip_root?: boolean, skip_LC?: boolean): object;
|
||||||
|
declare function strip_ns(x: string): string;
|
||||||
|
declare function write_UInt32LE(x: number, o?: WritableData): RawData;
|
||||||
|
declare function write_XLWideString(data: string, o?: WritableData): RawData;
|
||||||
|
declare function writeuint16(x: number): RawData;
|
||||||
|
|
||||||
|
|
||||||
|
interface ParseXLMetaOptions {
|
||||||
|
WTF?: number|boolean;
|
||||||
|
}
|
||||||
|
interface XLMDT {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
interface XLMeta {
|
||||||
|
Types: XLMDT[];
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xlsx",
|
"name": "xlsx",
|
||||||
"version": "0.18.2",
|
"version": "0.18.3",
|
||||||
"author": "sheetjs",
|
"author": "sheetjs",
|
||||||
"description": "SheetJS Spreadsheet data parser and writer",
|
"description": "SheetJS Spreadsheet data parser and writer",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit c8fe8a48a8cfc3c480b02f0a6df75cc2aff1932d
|
Subproject commit 8203afea252b2817ec0a67e18f3b7c9503d50b97
|
2
types/index.d.ts
vendored
2
types/index.d.ts
vendored
@ -833,7 +833,7 @@ export interface XLSX$Utils {
|
|||||||
cell_add_comment(cell: CellObject, text: string, author?: string): void;
|
cell_add_comment(cell: CellObject, text: string, author?: string): void;
|
||||||
|
|
||||||
/** Assign an Array Formula to a range */
|
/** Assign an Array Formula to a range */
|
||||||
sheet_set_array_formula(ws: WorkSheet, range: Range|string, formula: string): WorkSheet;
|
sheet_set_array_formula(ws: WorkSheet, range: Range|string, formula: string, dynamic?: boolean): WorkSheet;
|
||||||
|
|
||||||
/** Add an array of arrays of JS data to a worksheet */
|
/** Add an array of arrays of JS data to a worksheet */
|
||||||
sheet_add_aoa<T>(ws: WorkSheet, data: T[][], opts?: SheetAOAOpts): WorkSheet;
|
sheet_add_aoa<T>(ws: WorkSheet, data: T[][], opts?: SheetAOAOpts): WorkSheet;
|
||||||
|
311
xlsx.flow.js
311
xlsx.flow.js
@ -4,7 +4,7 @@
|
|||||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||||
var XLSX = {};
|
var XLSX = {};
|
||||||
function make_xlsx_lib(XLSX){
|
function make_xlsx_lib(XLSX){
|
||||||
XLSX.version = '0.18.2';
|
XLSX.version = '0.18.3';
|
||||||
var current_codepage = 1200, current_ansi = 1252;
|
var current_codepage = 1200, current_ansi = 1252;
|
||||||
/*:: declare var cptable:any; */
|
/*:: declare var cptable:any; */
|
||||||
/*global cptable:true, window */
|
/*global cptable:true, window */
|
||||||
@ -3189,7 +3189,7 @@ function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
|
|||||||
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
||||||
if(typeof Deno !== 'undefined') {
|
if(typeof Deno !== 'undefined') {
|
||||||
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
||||||
if(enc) switch(enc) {
|
if(enc && typeof payload == "string") switch(enc) {
|
||||||
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
||||||
case "binary": payload = s2ab(payload); break;
|
case "binary": payload = s2ab(payload); break;
|
||||||
/* TODO: binary equivalent */
|
/* TODO: binary equivalent */
|
||||||
@ -4144,44 +4144,6 @@ function encode_range_xls(r, opts)/*:string*/ {
|
|||||||
}
|
}
|
||||||
return encode_cell_xls(r.s, opts.biff) + ":" + encode_cell_xls(r.e, opts.biff);
|
return encode_cell_xls(r.s, opts.biff) + ":" + encode_cell_xls(r.e, opts.biff);
|
||||||
}
|
}
|
||||||
var OFFCRYPTO = {};
|
|
||||||
|
|
||||||
var make_offcrypto = function(O, _crypto) {
|
|
||||||
var crypto;
|
|
||||||
if(typeof _crypto !== 'undefined') crypto = _crypto;
|
|
||||||
else if(typeof require !== 'undefined') {
|
|
||||||
try { crypto = require('crypto'); }
|
|
||||||
catch(e) { crypto = null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
O.rc4 = function(key, data) {
|
|
||||||
var S = new Array(256);
|
|
||||||
var c = 0, i = 0, j = 0, t = 0;
|
|
||||||
for(i = 0; i != 256; ++i) S[i] = i;
|
|
||||||
for(i = 0; i != 256; ++i) {
|
|
||||||
j = (j + S[i] + (key[i%key.length]).charCodeAt(0))&255;
|
|
||||||
t = S[i]; S[i] = S[j]; S[j] = t;
|
|
||||||
}
|
|
||||||
// $FlowIgnore
|
|
||||||
i = j = 0; var out = new_raw_buf(data.length);
|
|
||||||
for(c = 0; c != data.length; ++c) {
|
|
||||||
i = (i + 1)&255;
|
|
||||||
j = (j + S[i])%256;
|
|
||||||
t = S[i]; S[i] = S[j]; S[j] = t;
|
|
||||||
out[c] = (data[c] ^ S[(S[i]+S[j])&255]);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
O.md5 = function(hex) {
|
|
||||||
if(!crypto) throw new Error("Unsupported crypto");
|
|
||||||
return crypto.createHash('md5').update(hex).digest('hex');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/*:: declare var crypto:any; */
|
|
||||||
/*global crypto:true */
|
|
||||||
make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined);
|
|
||||||
|
|
||||||
function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; }
|
function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; }
|
||||||
function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); }
|
function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); }
|
||||||
function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
|
function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
|
||||||
@ -4351,6 +4313,9 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
|
|||||||
}
|
}
|
||||||
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
|
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
|
||||||
|
|
||||||
|
function parse_Int32LE(data) {
|
||||||
|
return data.read_shift(4, 'i');
|
||||||
|
}
|
||||||
function write_UInt32LE(x/*:number*/, o) {
|
function write_UInt32LE(x/*:number*/, o) {
|
||||||
if (!o) o = new_buf(4);
|
if (!o) o = new_buf(4);
|
||||||
o.write_shift(4, x);
|
o.write_shift(4, x);
|
||||||
@ -5016,8 +4981,8 @@ var ct2type/*{[string]:string}*/ = ({
|
|||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
||||||
|
|
||||||
/* Metadata */
|
/* Metadata */
|
||||||
"application/vnd.ms-excel.sheetMetadata": "TODO",
|
"application/vnd.ms-excel.sheetMetadata": "metadata",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "TODO",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "metadata",
|
||||||
|
|
||||||
/* PivotCache */
|
/* PivotCache */
|
||||||
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
||||||
@ -5134,6 +5099,10 @@ var CT_LIST = (function(){
|
|||||||
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
||||||
xlsb: "application/vnd.ms-excel.macrosheet"
|
xlsb: "application/vnd.ms-excel.macrosheet"
|
||||||
},
|
},
|
||||||
|
metadata: { /* Metadata (Stock/Geography and Dynamic Array) */
|
||||||
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
|
||||||
|
xlsb: "application/vnd.ms-excel.sheetMetadata"
|
||||||
|
},
|
||||||
styles: { /* Styles */
|
styles: { /* Styles */
|
||||||
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
||||||
xlsb: "application/vnd.ms-excel.styles"
|
xlsb: "application/vnd.ms-excel.styles"
|
||||||
@ -5153,7 +5122,7 @@ function new_ct()/*:any*/ {
|
|||||||
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
||||||
rels:[], strs:[], comments:[], links:[],
|
rels:[], strs:[], comments:[], links:[],
|
||||||
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
||||||
calcchains:[], vba: [], drawings: [],
|
calcchains:[], vba: [], drawings: [], metadata: [],
|
||||||
TODO:[], xmlns: "" }/*:any*/);
|
TODO:[], xmlns: "" }/*:any*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5252,6 +5221,7 @@ function write_ct(ct, opts)/*:string*/ {
|
|||||||
f3('vba');
|
f3('vba');
|
||||||
f3('comments');
|
f3('comments');
|
||||||
f3('drawings');
|
f3('drawings');
|
||||||
|
f2('metadata');
|
||||||
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
||||||
return o.join("");
|
return o.join("");
|
||||||
}
|
}
|
||||||
@ -5318,7 +5288,9 @@ var RELS_EXTERN = [RELS.HLINK, RELS.XPATH, RELS.XMISS];
|
|||||||
function add_rels(rels, rId/*:number*/, f, type, relobj, targetmode/*:?string*/)/*:number*/ {
|
function add_rels(rels, rId/*:number*/, f, type, relobj, targetmode/*:?string*/)/*:number*/ {
|
||||||
if(!relobj) relobj = {};
|
if(!relobj) relobj = {};
|
||||||
if(!rels['!id']) rels['!id'] = {};
|
if(!rels['!id']) rels['!id'] = {};
|
||||||
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
if(!rels['!idx']) rels['!idx'] = 1;
|
||||||
|
if(rId < 0) for(rId = rels['!idx']; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
||||||
|
rels['!idx'] = rId + 1;
|
||||||
relobj.Id = 'rId' + rId;
|
relobj.Id = 'rId' + rId;
|
||||||
relobj.Type = type;
|
relobj.Type = type;
|
||||||
relobj.Target = f;
|
relobj.Target = f;
|
||||||
@ -11310,6 +11282,157 @@ function update_xfext(xf, xfext) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
function parse_xlmeta_xml(data, name, opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
if (!data)
|
||||||
|
return out;
|
||||||
|
var pass = false;
|
||||||
|
data.replace(tagregex, function(x, idx) {
|
||||||
|
var y = parsexmltag(x);
|
||||||
|
switch (strip_ns(y[0])) {
|
||||||
|
case "<?xml":
|
||||||
|
break;
|
||||||
|
case "<metadata":
|
||||||
|
case "</metadata>":
|
||||||
|
break;
|
||||||
|
case "<metadataTypes":
|
||||||
|
case "</metadataTypes>":
|
||||||
|
break;
|
||||||
|
case "<metadataType":
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
case "<futureMetadata":
|
||||||
|
break;
|
||||||
|
case "</futureMetadata>":
|
||||||
|
break;
|
||||||
|
case "<bk>":
|
||||||
|
break;
|
||||||
|
case "</bk>":
|
||||||
|
break;
|
||||||
|
case "<rc":
|
||||||
|
break;
|
||||||
|
case "</rc>":
|
||||||
|
break;
|
||||||
|
case "<cellMetadata":
|
||||||
|
case "</cellMetadata>":
|
||||||
|
break;
|
||||||
|
case "<valueMetadata":
|
||||||
|
break;
|
||||||
|
case "</valueMetadata>":
|
||||||
|
break;
|
||||||
|
case "<extLst":
|
||||||
|
case "<extLst>":
|
||||||
|
case "</extLst>":
|
||||||
|
case "<extLst/>":
|
||||||
|
break;
|
||||||
|
case "<ext":
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case "</ext>":
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!pass && opts.WTF)
|
||||||
|
throw new Error("unrecognized " + y[0] + " in metadata");
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_xml() {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
|
||||||
|
return o.join("");
|
||||||
|
}
|
||||||
|
function parse_BrtMdtinfo(data, length) {
|
||||||
|
return {
|
||||||
|
flags: data.read_shift(4),
|
||||||
|
version: data.read_shift(4),
|
||||||
|
name: parse_XLWideString(data, length - 8)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function write_BrtMdtinfo(data) {
|
||||||
|
var o = new_buf(12 + 2 * data.name.length);
|
||||||
|
o.write_shift(4, data.flags);
|
||||||
|
o.write_shift(4, data.version);
|
||||||
|
write_XLWideString(data.name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtMdb(mdb) {
|
||||||
|
var o = new_buf(4 + 8 * mdb.length);
|
||||||
|
o.write_shift(4, mdb.length);
|
||||||
|
for (var i = 0; i < mdb.length; ++i) {
|
||||||
|
o.write_shift(4, mdb[i][0]);
|
||||||
|
o.write_shift(4, mdb[i][1]);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsfmd(cnt, name) {
|
||||||
|
var o = new_buf(8 + 2 * name.length);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
write_XLWideString(name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsmdb(cnt, cm) {
|
||||||
|
var o = new_buf(8);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
o.write_shift(4, cm ? 1 : 0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function parse_xlmeta_bin(data, name, _opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
var opts = _opts || {};
|
||||||
|
var state = [];
|
||||||
|
var pass = false;
|
||||||
|
recordhopper(data, function(val, R_n, RT) {
|
||||||
|
switch (RT) {
|
||||||
|
case 335:
|
||||||
|
out.Types.push({ name: val.name });
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.push(R_n);
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.pop();
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((R_n || "").indexOf("Begin") > 0) {
|
||||||
|
} else if ((R_n || "").indexOf("End") > 0) {
|
||||||
|
} else if (!pass || opts.WTF && state[state.length - 1] != "BrtFRTBegin")
|
||||||
|
throw new Error("Unexpected record " + RT + " " + R_n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_bin() {
|
||||||
|
var ba = buf_array();
|
||||||
|
write_record(ba, "BrtBeginMetadata");
|
||||||
|
write_record(ba, "BrtBeginEsmdtinfo", write_UInt32LE(1));
|
||||||
|
write_record(ba, "BrtMdtinfo", write_BrtMdtinfo({
|
||||||
|
name: "XLDAPR",
|
||||||
|
version: 12e4,
|
||||||
|
flags: 3496657072
|
||||||
|
}));
|
||||||
|
write_record(ba, "BrtEndEsmdtinfo");
|
||||||
|
write_record(ba, "BrtBeginEsfmd", write_BrtBeginEsfmd(1, "XLDAPR"));
|
||||||
|
write_record(ba, "BrtBeginFmd");
|
||||||
|
write_record(ba, "BrtFRTBegin", write_UInt32LE(514));
|
||||||
|
write_record(ba, "BrtBeginDynamicArrayPr", write_UInt32LE(0));
|
||||||
|
write_record(ba, "BrtEndDynamicArrayPr", writeuint16(1));
|
||||||
|
write_record(ba, "BrtFRTEnd");
|
||||||
|
write_record(ba, "BrtEndFmd");
|
||||||
|
write_record(ba, "BrtEndEsfmd");
|
||||||
|
write_record(ba, "BrtBeginEsmdb", write_BrtBeginEsmdb(1, true));
|
||||||
|
write_record(ba, "BrtMdb", write_BrtMdb([[1, 0]]));
|
||||||
|
write_record(ba, "BrtEndEsmdb");
|
||||||
|
write_record(ba, "BrtEndMetadata");
|
||||||
|
return ba.end();
|
||||||
|
}
|
||||||
/* 18.6 Calculation Chain */
|
/* 18.6 Calculation Chain */
|
||||||
function parse_cc_xml(data/*::, name, opts*/)/*:Array<any>*/ {
|
function parse_cc_xml(data/*::, name, opts*/)/*:Array<any>*/ {
|
||||||
var d = [];
|
var d = [];
|
||||||
@ -12636,7 +12759,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
|||||||
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
||||||
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
||||||
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
||||||
if(name && name.slice(0,6) == "_xlfn.") name = name.slice(6);
|
if(name && name.slice(0,6) == "_xlfn." && !opts.xlfn) name = name.slice(6);
|
||||||
stack.push(name);
|
stack.push(name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -14534,6 +14657,7 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string
|
|||||||
}
|
}
|
||||||
if(cell.l) ws['!links'].push([ref, cell.l]);
|
if(cell.l) ws['!links'].push([ref, cell.l]);
|
||||||
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
||||||
|
if(cell.D) o.cm = 1;
|
||||||
return writextag('c', v, o);
|
return writextag('c', v, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14710,6 +14834,10 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||||||
}
|
}
|
||||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
safe_format(p, fmtid, fillid, opts, themes, styles);
|
||||||
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
||||||
|
if(tag.cm && opts.xlmeta) {
|
||||||
|
var cm = (opts.xlmeta.Types||[])[+tag.cm-1];
|
||||||
|
if(cm && cm.name == 'XLDAPR') p.D = true;
|
||||||
|
}
|
||||||
if(dense) {
|
if(dense) {
|
||||||
var _r = decode_cell(tag.r);
|
var _r = decode_cell(tag.r);
|
||||||
if(!s[_r.r]) s[_r.r] = [];
|
if(!s[_r.r]) s[_r.r] = [];
|
||||||
@ -15424,6 +15552,8 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
|
|
||||||
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
||||||
|
|
||||||
|
var cm, vm;
|
||||||
|
|
||||||
recordhopper(data, function ws_parse(val, R_n, RT) {
|
recordhopper(data, function ws_parse(val, R_n, RT) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
switch(RT) {
|
switch(RT) {
|
||||||
@ -15481,6 +15611,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
}
|
}
|
||||||
if(!af && val.length > 3) p.f = val[3];
|
if(!af && val.length > 3) p.f = val[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
@ -15488,12 +15619,17 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
||||||
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
||||||
}
|
}
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0001: /* 'BrtCellBlank' */
|
case 0x0001: /* 'BrtCellBlank' */
|
||||||
case 0x000C: /* 'BrtShortBlank' */
|
case 0x000C: /* 'BrtShortBlank' */
|
||||||
if(!opts.sheetStubs || pass) break;
|
if(!opts.sheetStubs || pass) break;
|
||||||
p = ({t:'z',v:undefined}/*:any*/);
|
p = ({t:'z',v:void 0}/*:any*/);
|
||||||
C = val[0].c == -1 ? C + 1 : val[0].c;
|
C = val[0].c == -1 ? C + 1 : val[0].c;
|
||||||
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
||||||
else s[encode_col(C) + rr] = p;
|
else s[encode_col(C) + rr] = p;
|
||||||
@ -15501,11 +15637,20 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
if(refguess.e.c < C) refguess.e.c = C;
|
if(refguess.e.c < C) refguess.e.c = C;
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x00B0: /* 'BrtMergeCell' */
|
case 0x00B0: /* 'BrtMergeCell' */
|
||||||
merges.push(val); break;
|
merges.push(val); break;
|
||||||
|
|
||||||
|
case 0x0031: { /* 'BrtCellMeta' */
|
||||||
|
cm = ((opts.xlmeta||{}).Types||[])[val-1];
|
||||||
|
} break;
|
||||||
|
|
||||||
case 0x01EE: /* 'BrtHLink' */
|
case 0x01EE: /* 'BrtHLink' */
|
||||||
var rel = rels['!id'][val.relId];
|
var rel = rels['!id'][val.relId];
|
||||||
if(rel) {
|
if(rel) {
|
||||||
@ -15593,7 +15738,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
case 0x041A: /* 'BrtCFVO14' */
|
case 0x041A: /* 'BrtCFVO14' */
|
||||||
case 0x0289: /* 'BrtCellIgnoreEC' */
|
case 0x0289: /* 'BrtCellIgnoreEC' */
|
||||||
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
||||||
case 0x0031: /* 'BrtCellMeta' */
|
|
||||||
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
||||||
case 0x025F: /* 'BrtCellWatch' */
|
case 0x025F: /* 'BrtCellWatch' */
|
||||||
case 0x0234: /* 'BrtColor' */
|
case 0x0234: /* 'BrtColor' */
|
||||||
@ -16800,6 +16944,11 @@ function parse_xlink(data, rel, name/*:string*/, opts) {
|
|||||||
return parse_xlink_xml((data/*:any*/), rel, name, opts);
|
return parse_xlink_xml((data/*:any*/), rel, name, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_xlmeta(data, name/*:string*/, opts) {
|
||||||
|
if(name.slice(-4)===".bin") return parse_xlmeta_bin((data/*:any*/), name, opts);
|
||||||
|
return parse_xlmeta_xml((data/*:any*/), name, opts);
|
||||||
|
}
|
||||||
|
|
||||||
function write_wb(wb, name/*:string*/, opts) {
|
function write_wb(wb, name/*:string*/, opts) {
|
||||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||||
}
|
}
|
||||||
@ -16829,6 +16978,10 @@ function write_cc(data, name:string, opts) {
|
|||||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function write_xlmeta(name/*:string*/) {
|
||||||
|
return (name.slice(-4)===".bin" ? write_xlmeta_bin : write_xlmeta_xml)();
|
||||||
|
}
|
||||||
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||||
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
||||||
function xlml_parsexmltag(tag/*:string*/, skip_root/*:?boolean*/) {
|
function xlml_parsexmltag(tag/*:string*/, skip_root/*:?boolean*/) {
|
||||||
@ -19097,7 +19250,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parse_BrtBorder },
|
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parse_BrtBorder },
|
||||||
/*::[*/0x002F/*::]*/: { n:"BrtXF", f:parse_BrtXF },
|
/*::[*/0x002F/*::]*/: { n:"BrtXF", f:parse_BrtXF },
|
||||||
/*::[*/0x0030/*::]*/: { n:"BrtStyle" },
|
/*::[*/0x0030/*::]*/: { n:"BrtStyle" },
|
||||||
/*::[*/0x0031/*::]*/: { n:"BrtCellMeta" },
|
/*::[*/0x0031/*::]*/: { n:"BrtCellMeta", f:parse_Int32LE },
|
||||||
/*::[*/0x0032/*::]*/: { n:"BrtValueMeta" },
|
/*::[*/0x0032/*::]*/: { n:"BrtValueMeta" },
|
||||||
/*::[*/0x0033/*::]*/: { n:"BrtMdb" },
|
/*::[*/0x0033/*::]*/: { n:"BrtMdb" },
|
||||||
/*::[*/0x0034/*::]*/: { n:"BrtBeginFmd" },
|
/*::[*/0x0034/*::]*/: { n:"BrtBeginFmd" },
|
||||||
@ -19323,7 +19476,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x014C/*::]*/: { n:"BrtBeginMetadata" },
|
/*::[*/0x014C/*::]*/: { n:"BrtBeginMetadata" },
|
||||||
/*::[*/0x014D/*::]*/: { n:"BrtEndMetadata" },
|
/*::[*/0x014D/*::]*/: { n:"BrtEndMetadata" },
|
||||||
/*::[*/0x014E/*::]*/: { n:"BrtBeginEsmdtinfo" },
|
/*::[*/0x014E/*::]*/: { n:"BrtBeginEsmdtinfo" },
|
||||||
/*::[*/0x014F/*::]*/: { n:"BrtMdtinfo" },
|
/*::[*/0x014F/*::]*/: { n:"BrtMdtinfo", f:parse_BrtMdtinfo },
|
||||||
/*::[*/0x0150/*::]*/: { n:"BrtEndEsmdtinfo" },
|
/*::[*/0x0150/*::]*/: { n:"BrtEndEsmdtinfo" },
|
||||||
/*::[*/0x0151/*::]*/: { n:"BrtBeginEsmdb" },
|
/*::[*/0x0151/*::]*/: { n:"BrtBeginEsmdb" },
|
||||||
/*::[*/0x0152/*::]*/: { n:"BrtEndEsmdb" },
|
/*::[*/0x0152/*::]*/: { n:"BrtEndEsmdb" },
|
||||||
@ -19844,7 +19997,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x0835/*::]*/: { n:"BrtEndTimelineStyleElements" },
|
/*::[*/0x0835/*::]*/: { n:"BrtEndTimelineStyleElements" },
|
||||||
/*::[*/0x0836/*::]*/: { n:"BrtDxf15" },
|
/*::[*/0x0836/*::]*/: { n:"BrtDxf15" },
|
||||||
/*::[*/0x0837/*::]*/: { n:"BrtBeginDxfs15" },
|
/*::[*/0x0837/*::]*/: { n:"BrtBeginDxfs15" },
|
||||||
/*::[*/0x0838/*::]*/: { n:"brtEndDxfs15" },
|
/*::[*/0x0838/*::]*/: { n:"BrtEndDxfs15" },
|
||||||
/*::[*/0x0839/*::]*/: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
/*::[*/0x0839/*::]*/: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
||||||
/*::[*/0x083A/*::]*/: { n:"BrtBeginItemUniqueNames" },
|
/*::[*/0x083A/*::]*/: { n:"BrtBeginItemUniqueNames" },
|
||||||
/*::[*/0x083B/*::]*/: { n:"BrtEndItemUniqueNames" },
|
/*::[*/0x083B/*::]*/: { n:"BrtEndItemUniqueNames" },
|
||||||
@ -19884,9 +20037,27 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x085D/*::]*/: { n:"BrtModelTimeGroupingCalcCol" },
|
/*::[*/0x085D/*::]*/: { n:"BrtModelTimeGroupingCalcCol" },
|
||||||
/*::[*/0x0C00/*::]*/: { n:"BrtUid" },
|
/*::[*/0x0C00/*::]*/: { n:"BrtUid" },
|
||||||
/*::[*/0x0C01/*::]*/: { n:"BrtRevisionPtr" },
|
/*::[*/0x0C01/*::]*/: { n:"BrtRevisionPtr" },
|
||||||
/*::[*/0x13e7/*::]*/: { n:"BrtBeginCalcFeatures" },
|
/*::[*/0x1000/*::]*/: { n:"BrtBeginDynamicArrayPr" },
|
||||||
/*::[*/0x13e8/*::]*/: { n:"BrtEndCalcFeatures" },
|
/*::[*/0x1001/*::]*/: { n:"BrtEndDynamicArrayPr" },
|
||||||
/*::[*/0x13e9/*::]*/: { n:"BrtCalcFeature" },
|
/*::[*/0x138A/*::]*/: { n:"BrtBeginRichValueBlock" },
|
||||||
|
/*::[*/0x138B/*::]*/: { n:"BrtEndRichValueBlock" },
|
||||||
|
/*::[*/0x13D9/*::]*/: { n:"BrtBeginRichFilters" },
|
||||||
|
/*::[*/0x13DA/*::]*/: { n:"BrtEndRichFilters" },
|
||||||
|
/*::[*/0x13DB/*::]*/: { n:"BrtRichFilter" },
|
||||||
|
/*::[*/0x13DC/*::]*/: { n:"BrtBeginRichFilterColumn" },
|
||||||
|
/*::[*/0x13DD/*::]*/: { n:"BrtEndRichFilterColumn" },
|
||||||
|
/*::[*/0x13DE/*::]*/: { n:"BrtBeginCustomRichFilters" },
|
||||||
|
/*::[*/0x13DF/*::]*/: { n:"BrtEndCustomRichFilters" },
|
||||||
|
/*::[*/0x13E0/*::]*/: { n:"BrtCustomRichFilter" },
|
||||||
|
/*::[*/0x13E1/*::]*/: { n:"BrtTop10RichFilter" },
|
||||||
|
/*::[*/0x13E2/*::]*/: { n:"BrtDynamicRichFilter" },
|
||||||
|
/*::[*/0x13E4/*::]*/: { n:"BrtBeginRichSortCondition" },
|
||||||
|
/*::[*/0x13E5/*::]*/: { n:"BrtEndRichSortCondition" },
|
||||||
|
/*::[*/0x13E6/*::]*/: { n:"BrtRichFilterDateGroupItem" },
|
||||||
|
/*::[*/0x13E7/*::]*/: { n:"BrtBeginCalcFeatures" },
|
||||||
|
/*::[*/0x13E8/*::]*/: { n:"BrtEndCalcFeatures" },
|
||||||
|
/*::[*/0x13E9/*::]*/: { n:"BrtCalcFeature" },
|
||||||
|
/*::[*/0x13EB/*::]*/: { n:"BrtExternalLinksPr" },
|
||||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22740,9 +22911,16 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
|||||||
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
||||||
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
||||||
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
||||||
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile);
|
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile.replace(/_rels.*/, "s5s"));
|
||||||
|
|
||||||
|
if((dir.metadata || []).length >= 1) {
|
||||||
|
/* TODO: MDX and other types of metadata */
|
||||||
|
opts.xlmeta = parse_xlmeta(getzipdata(zip, strip_front_slash(dir.metadata[0])),dir.metadata[0],opts);
|
||||||
|
}
|
||||||
|
|
||||||
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
||||||
|
|
||||||
|
|
||||||
/* Numbers iOS hack */
|
/* Numbers iOS hack */
|
||||||
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
||||||
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
||||||
@ -22978,6 +23156,11 @@ function write_zip_xlsxb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta(f));
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -22986,7 +23169,7 @@ function write_zip_xlsxb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
return zip;
|
return zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this version does not reference XLSB write functions */
|
||||||
function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||||
_shapeid = 1024;
|
_shapeid = 1024;
|
||||||
if(wb && !wb.SSF) {
|
if(wb && !wb.SSF) {
|
||||||
@ -23108,6 +23291,11 @@ function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta_xml());
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -23161,6 +23349,7 @@ function read_plaintext_raw(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
|
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
|
||||||
|
o.type = "binary";
|
||||||
return read_plaintext(str, o);
|
return read_plaintext(str, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23280,14 +23469,15 @@ function write_zip_typeXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
|
|||||||
}
|
}
|
||||||
function write_zip_denouement(z/*:any*/, o/*:?WriteOpts*/)/*:any*/ {
|
function write_zip_denouement(z/*:any*/, o/*:?WriteOpts*/)/*:any*/ {
|
||||||
var oopts = {};
|
var oopts = {};
|
||||||
|
var ftype = has_buf ? "nodebuffer" : (typeof Uint8Array !== "undefined" ? "array" : "string");
|
||||||
if(o.compression) oopts.compression = 'DEFLATE';
|
if(o.compression) oopts.compression = 'DEFLATE';
|
||||||
if(o.password) oopts.type = has_buf ? "nodebuffer" : "string";
|
if(o.password) oopts.type = ftype;
|
||||||
else switch(o.type) {
|
else switch(o.type) {
|
||||||
case "base64": oopts.type = "base64"; break;
|
case "base64": oopts.type = "base64"; break;
|
||||||
case "binary": oopts.type = "string"; break;
|
case "binary": oopts.type = "string"; break;
|
||||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
||||||
case "buffer":
|
case "buffer":
|
||||||
case "file": oopts.type = has_buf ? "nodebuffer" : "string"; break;
|
case "file": oopts.type = ftype; break;
|
||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
||||||
@ -23811,7 +24001,7 @@ utils.cell_add_comment = function(cell/*:Cell*/, text/*:string*/, author/*:?stri
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* set array formula and flush related cells */
|
/* set array formula and flush related cells */
|
||||||
utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:string*/) {
|
utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:string*/, dynamic/*:boolean*/) {
|
||||||
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
||||||
var rngstr = typeof range == "string" ? range : encode_range(range);
|
var rngstr = typeof range == "string" ? range : encode_range(range);
|
||||||
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
||||||
@ -23819,7 +24009,10 @@ utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:stri
|
|||||||
cell.t = 'n';
|
cell.t = 'n';
|
||||||
cell.F = rngstr;
|
cell.F = rngstr;
|
||||||
delete cell.v;
|
delete cell.v;
|
||||||
if(R == rng.s.r && C == rng.s.c) cell.f = formula;
|
if(R == rng.s.r && C == rng.s.c) {
|
||||||
|
cell.f = formula;
|
||||||
|
if(dynamic) cell.D = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ws;
|
return ws;
|
||||||
};
|
};
|
||||||
|
310
xlsx.js
generated
310
xlsx.js
generated
@ -4,7 +4,7 @@
|
|||||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||||
var XLSX = {};
|
var XLSX = {};
|
||||||
function make_xlsx_lib(XLSX){
|
function make_xlsx_lib(XLSX){
|
||||||
XLSX.version = '0.18.2';
|
XLSX.version = '0.18.3';
|
||||||
var current_codepage = 1200, current_ansi = 1252;
|
var current_codepage = 1200, current_ansi = 1252;
|
||||||
/*global cptable:true, window */
|
/*global cptable:true, window */
|
||||||
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
if(typeof module !== "undefined" && typeof require !== 'undefined') {
|
||||||
@ -3114,7 +3114,7 @@ function write_dl(fname, payload, enc) {
|
|||||||
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
||||||
if(typeof Deno !== 'undefined') {
|
if(typeof Deno !== 'undefined') {
|
||||||
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
||||||
if(enc) switch(enc) {
|
if(enc && typeof payload == "string") switch(enc) {
|
||||||
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
||||||
case "binary": payload = s2ab(payload); break;
|
case "binary": payload = s2ab(payload); break;
|
||||||
/* TODO: binary equivalent */
|
/* TODO: binary equivalent */
|
||||||
@ -4057,43 +4057,6 @@ function encode_range_xls(r, opts) {
|
|||||||
}
|
}
|
||||||
return encode_cell_xls(r.s, opts.biff) + ":" + encode_cell_xls(r.e, opts.biff);
|
return encode_cell_xls(r.s, opts.biff) + ":" + encode_cell_xls(r.e, opts.biff);
|
||||||
}
|
}
|
||||||
var OFFCRYPTO = {};
|
|
||||||
|
|
||||||
var make_offcrypto = function(O, _crypto) {
|
|
||||||
var crypto;
|
|
||||||
if(typeof _crypto !== 'undefined') crypto = _crypto;
|
|
||||||
else if(typeof require !== 'undefined') {
|
|
||||||
try { crypto = require('crypto'); }
|
|
||||||
catch(e) { crypto = null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
O.rc4 = function(key, data) {
|
|
||||||
var S = new Array(256);
|
|
||||||
var c = 0, i = 0, j = 0, t = 0;
|
|
||||||
for(i = 0; i != 256; ++i) S[i] = i;
|
|
||||||
for(i = 0; i != 256; ++i) {
|
|
||||||
j = (j + S[i] + (key[i%key.length]).charCodeAt(0))&255;
|
|
||||||
t = S[i]; S[i] = S[j]; S[j] = t;
|
|
||||||
}
|
|
||||||
// $FlowIgnore
|
|
||||||
i = j = 0; var out = new_raw_buf(data.length);
|
|
||||||
for(c = 0; c != data.length; ++c) {
|
|
||||||
i = (i + 1)&255;
|
|
||||||
j = (j + S[i])%256;
|
|
||||||
t = S[i]; S[i] = S[j]; S[j] = t;
|
|
||||||
out[c] = (data[c] ^ S[(S[i]+S[j])&255]);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
O.md5 = function(hex) {
|
|
||||||
if(!crypto) throw new Error("Unsupported crypto");
|
|
||||||
return crypto.createHash('md5').update(hex).digest('hex');
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/*global crypto:true */
|
|
||||||
make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined);
|
|
||||||
|
|
||||||
function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; }
|
function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; }
|
||||||
function encode_row(row) { return "" + (row + 1); }
|
function encode_row(row) { return "" + (row + 1); }
|
||||||
function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
|
function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
|
||||||
@ -4258,6 +4221,9 @@ function sheet_add_aoa(_ws, data, opts) {
|
|||||||
}
|
}
|
||||||
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
|
function aoa_to_sheet(data, opts) { return sheet_add_aoa(null, data, opts); }
|
||||||
|
|
||||||
|
function parse_Int32LE(data) {
|
||||||
|
return data.read_shift(4, 'i');
|
||||||
|
}
|
||||||
function write_UInt32LE(x, o) {
|
function write_UInt32LE(x, o) {
|
||||||
if (!o) o = new_buf(4);
|
if (!o) o = new_buf(4);
|
||||||
o.write_shift(4, x);
|
o.write_shift(4, x);
|
||||||
@ -4923,8 +4889,8 @@ var ct2type/*{[string]:string}*/ = ({
|
|||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
||||||
|
|
||||||
/* Metadata */
|
/* Metadata */
|
||||||
"application/vnd.ms-excel.sheetMetadata": "TODO",
|
"application/vnd.ms-excel.sheetMetadata": "metadata",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "TODO",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "metadata",
|
||||||
|
|
||||||
/* PivotCache */
|
/* PivotCache */
|
||||||
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
||||||
@ -5041,6 +5007,10 @@ var CT_LIST = (function(){
|
|||||||
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
||||||
xlsb: "application/vnd.ms-excel.macrosheet"
|
xlsb: "application/vnd.ms-excel.macrosheet"
|
||||||
},
|
},
|
||||||
|
metadata: { /* Metadata (Stock/Geography and Dynamic Array) */
|
||||||
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
|
||||||
|
xlsb: "application/vnd.ms-excel.sheetMetadata"
|
||||||
|
},
|
||||||
styles: { /* Styles */
|
styles: { /* Styles */
|
||||||
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
||||||
xlsb: "application/vnd.ms-excel.styles"
|
xlsb: "application/vnd.ms-excel.styles"
|
||||||
@ -5060,7 +5030,7 @@ function new_ct() {
|
|||||||
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
||||||
rels:[], strs:[], comments:[], links:[],
|
rels:[], strs:[], comments:[], links:[],
|
||||||
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
||||||
calcchains:[], vba: [], drawings: [],
|
calcchains:[], vba: [], drawings: [], metadata: [],
|
||||||
TODO:[], xmlns: "" });
|
TODO:[], xmlns: "" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5159,6 +5129,7 @@ function write_ct(ct, opts) {
|
|||||||
f3('vba');
|
f3('vba');
|
||||||
f3('comments');
|
f3('comments');
|
||||||
f3('drawings');
|
f3('drawings');
|
||||||
|
f2('metadata');
|
||||||
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
||||||
return o.join("");
|
return o.join("");
|
||||||
}
|
}
|
||||||
@ -5225,7 +5196,9 @@ var RELS_EXTERN = [RELS.HLINK, RELS.XPATH, RELS.XMISS];
|
|||||||
function add_rels(rels, rId, f, type, relobj, targetmode) {
|
function add_rels(rels, rId, f, type, relobj, targetmode) {
|
||||||
if(!relobj) relobj = {};
|
if(!relobj) relobj = {};
|
||||||
if(!rels['!id']) rels['!id'] = {};
|
if(!rels['!id']) rels['!id'] = {};
|
||||||
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
if(!rels['!idx']) rels['!idx'] = 1;
|
||||||
|
if(rId < 0) for(rId = rels['!idx']; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
||||||
|
rels['!idx'] = rId + 1;
|
||||||
relobj.Id = 'rId' + rId;
|
relobj.Id = 'rId' + rId;
|
||||||
relobj.Type = type;
|
relobj.Type = type;
|
||||||
relobj.Target = f;
|
relobj.Target = f;
|
||||||
@ -11209,6 +11182,157 @@ function update_xfext(xf, xfext) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
function parse_xlmeta_xml(data, name, opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
if (!data)
|
||||||
|
return out;
|
||||||
|
var pass = false;
|
||||||
|
data.replace(tagregex, function(x, idx) {
|
||||||
|
var y = parsexmltag(x);
|
||||||
|
switch (strip_ns(y[0])) {
|
||||||
|
case "<?xml":
|
||||||
|
break;
|
||||||
|
case "<metadata":
|
||||||
|
case "</metadata>":
|
||||||
|
break;
|
||||||
|
case "<metadataTypes":
|
||||||
|
case "</metadataTypes>":
|
||||||
|
break;
|
||||||
|
case "<metadataType":
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
case "<futureMetadata":
|
||||||
|
break;
|
||||||
|
case "</futureMetadata>":
|
||||||
|
break;
|
||||||
|
case "<bk>":
|
||||||
|
break;
|
||||||
|
case "</bk>":
|
||||||
|
break;
|
||||||
|
case "<rc":
|
||||||
|
break;
|
||||||
|
case "</rc>":
|
||||||
|
break;
|
||||||
|
case "<cellMetadata":
|
||||||
|
case "</cellMetadata>":
|
||||||
|
break;
|
||||||
|
case "<valueMetadata":
|
||||||
|
break;
|
||||||
|
case "</valueMetadata>":
|
||||||
|
break;
|
||||||
|
case "<extLst":
|
||||||
|
case "<extLst>":
|
||||||
|
case "</extLst>":
|
||||||
|
case "<extLst/>":
|
||||||
|
break;
|
||||||
|
case "<ext":
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case "</ext>":
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!pass && opts.WTF)
|
||||||
|
throw new Error("unrecognized " + y[0] + " in metadata");
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_xml() {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
|
||||||
|
return o.join("");
|
||||||
|
}
|
||||||
|
function parse_BrtMdtinfo(data, length) {
|
||||||
|
return {
|
||||||
|
flags: data.read_shift(4),
|
||||||
|
version: data.read_shift(4),
|
||||||
|
name: parse_XLWideString(data, length - 8)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function write_BrtMdtinfo(data) {
|
||||||
|
var o = new_buf(12 + 2 * data.name.length);
|
||||||
|
o.write_shift(4, data.flags);
|
||||||
|
o.write_shift(4, data.version);
|
||||||
|
write_XLWideString(data.name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtMdb(mdb) {
|
||||||
|
var o = new_buf(4 + 8 * mdb.length);
|
||||||
|
o.write_shift(4, mdb.length);
|
||||||
|
for (var i = 0; i < mdb.length; ++i) {
|
||||||
|
o.write_shift(4, mdb[i][0]);
|
||||||
|
o.write_shift(4, mdb[i][1]);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsfmd(cnt, name) {
|
||||||
|
var o = new_buf(8 + 2 * name.length);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
write_XLWideString(name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsmdb(cnt, cm) {
|
||||||
|
var o = new_buf(8);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
o.write_shift(4, cm ? 1 : 0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function parse_xlmeta_bin(data, name, _opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
var opts = _opts || {};
|
||||||
|
var state = [];
|
||||||
|
var pass = false;
|
||||||
|
recordhopper(data, function(val, R_n, RT) {
|
||||||
|
switch (RT) {
|
||||||
|
case 335:
|
||||||
|
out.Types.push({ name: val.name });
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.push(R_n);
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.pop();
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((R_n || "").indexOf("Begin") > 0) {
|
||||||
|
} else if ((R_n || "").indexOf("End") > 0) {
|
||||||
|
} else if (!pass || opts.WTF && state[state.length - 1] != "BrtFRTBegin")
|
||||||
|
throw new Error("Unexpected record " + RT + " " + R_n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_bin() {
|
||||||
|
var ba = buf_array();
|
||||||
|
write_record(ba, "BrtBeginMetadata");
|
||||||
|
write_record(ba, "BrtBeginEsmdtinfo", write_UInt32LE(1));
|
||||||
|
write_record(ba, "BrtMdtinfo", write_BrtMdtinfo({
|
||||||
|
name: "XLDAPR",
|
||||||
|
version: 12e4,
|
||||||
|
flags: 3496657072
|
||||||
|
}));
|
||||||
|
write_record(ba, "BrtEndEsmdtinfo");
|
||||||
|
write_record(ba, "BrtBeginEsfmd", write_BrtBeginEsfmd(1, "XLDAPR"));
|
||||||
|
write_record(ba, "BrtBeginFmd");
|
||||||
|
write_record(ba, "BrtFRTBegin", write_UInt32LE(514));
|
||||||
|
write_record(ba, "BrtBeginDynamicArrayPr", write_UInt32LE(0));
|
||||||
|
write_record(ba, "BrtEndDynamicArrayPr", writeuint16(1));
|
||||||
|
write_record(ba, "BrtFRTEnd");
|
||||||
|
write_record(ba, "BrtEndFmd");
|
||||||
|
write_record(ba, "BrtEndEsfmd");
|
||||||
|
write_record(ba, "BrtBeginEsmdb", write_BrtBeginEsmdb(1, true));
|
||||||
|
write_record(ba, "BrtMdb", write_BrtMdb([[1, 0]]));
|
||||||
|
write_record(ba, "BrtEndEsmdb");
|
||||||
|
write_record(ba, "BrtEndMetadata");
|
||||||
|
return ba.end();
|
||||||
|
}
|
||||||
/* 18.6 Calculation Chain */
|
/* 18.6 Calculation Chain */
|
||||||
function parse_cc_xml(data) {
|
function parse_cc_xml(data) {
|
||||||
var d = [];
|
var d = [];
|
||||||
@ -12534,7 +12658,7 @@ ixti = f[1][1]; r = f[1][2];
|
|||||||
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
||||||
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
||||||
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
||||||
if(name && name.slice(0,6) == "_xlfn.") name = name.slice(6);
|
if(name && name.slice(0,6) == "_xlfn." && !opts.xlfn) name = name.slice(6);
|
||||||
stack.push(name);
|
stack.push(name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -14432,6 +14556,7 @@ function write_ws_xml_cell(cell, ref, ws, opts) {
|
|||||||
}
|
}
|
||||||
if(cell.l) ws['!links'].push([ref, cell.l]);
|
if(cell.l) ws['!links'].push([ref, cell.l]);
|
||||||
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
||||||
|
if(cell.D) o.cm = 1;
|
||||||
return writextag('c', v, o);
|
return writextag('c', v, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14608,6 +14733,10 @@ return function parse_ws_xml_data(sdata, s, opts, guess, themes, styles) {
|
|||||||
}
|
}
|
||||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
safe_format(p, fmtid, fillid, opts, themes, styles);
|
||||||
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
||||||
|
if(tag.cm && opts.xlmeta) {
|
||||||
|
var cm = (opts.xlmeta.Types||[])[+tag.cm-1];
|
||||||
|
if(cm && cm.name == 'XLDAPR') p.D = true;
|
||||||
|
}
|
||||||
if(dense) {
|
if(dense) {
|
||||||
var _r = decode_cell(tag.r);
|
var _r = decode_cell(tag.r);
|
||||||
if(!s[_r.r]) s[_r.r] = [];
|
if(!s[_r.r]) s[_r.r] = [];
|
||||||
@ -15321,6 +15450,8 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
|
|
||||||
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
||||||
|
|
||||||
|
var cm, vm;
|
||||||
|
|
||||||
recordhopper(data, function ws_parse(val, R_n, RT) {
|
recordhopper(data, function ws_parse(val, R_n, RT) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
switch(RT) {
|
switch(RT) {
|
||||||
@ -15378,6 +15509,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
}
|
}
|
||||||
if(!af && val.length > 3) p.f = val[3];
|
if(!af && val.length > 3) p.f = val[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
@ -15385,12 +15517,17 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
||||||
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
||||||
}
|
}
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0001: /* 'BrtCellBlank' */
|
case 0x0001: /* 'BrtCellBlank' */
|
||||||
case 0x000C: /* 'BrtShortBlank' */
|
case 0x000C: /* 'BrtShortBlank' */
|
||||||
if(!opts.sheetStubs || pass) break;
|
if(!opts.sheetStubs || pass) break;
|
||||||
p = ({t:'z',v:undefined});
|
p = ({t:'z',v:void 0});
|
||||||
C = val[0].c == -1 ? C + 1 : val[0].c;
|
C = val[0].c == -1 ? C + 1 : val[0].c;
|
||||||
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
||||||
else s[encode_col(C) + rr] = p;
|
else s[encode_col(C) + rr] = p;
|
||||||
@ -15398,11 +15535,20 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
if(refguess.e.c < C) refguess.e.c = C;
|
if(refguess.e.c < C) refguess.e.c = C;
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x00B0: /* 'BrtMergeCell' */
|
case 0x00B0: /* 'BrtMergeCell' */
|
||||||
merges.push(val); break;
|
merges.push(val); break;
|
||||||
|
|
||||||
|
case 0x0031: { /* 'BrtCellMeta' */
|
||||||
|
cm = ((opts.xlmeta||{}).Types||[])[val-1];
|
||||||
|
} break;
|
||||||
|
|
||||||
case 0x01EE: /* 'BrtHLink' */
|
case 0x01EE: /* 'BrtHLink' */
|
||||||
var rel = rels['!id'][val.relId];
|
var rel = rels['!id'][val.relId];
|
||||||
if(rel) {
|
if(rel) {
|
||||||
@ -15490,7 +15636,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
|
|||||||
case 0x041A: /* 'BrtCFVO14' */
|
case 0x041A: /* 'BrtCFVO14' */
|
||||||
case 0x0289: /* 'BrtCellIgnoreEC' */
|
case 0x0289: /* 'BrtCellIgnoreEC' */
|
||||||
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
||||||
case 0x0031: /* 'BrtCellMeta' */
|
|
||||||
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
||||||
case 0x025F: /* 'BrtCellWatch' */
|
case 0x025F: /* 'BrtCellWatch' */
|
||||||
case 0x0234: /* 'BrtColor' */
|
case 0x0234: /* 'BrtColor' */
|
||||||
@ -16695,6 +16840,11 @@ function parse_xlink(data, rel, name, opts) {
|
|||||||
return parse_xlink_xml((data), rel, name, opts);
|
return parse_xlink_xml((data), rel, name, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_xlmeta(data, name, opts) {
|
||||||
|
if(name.slice(-4)===".bin") return parse_xlmeta_bin((data), name, opts);
|
||||||
|
return parse_xlmeta_xml((data), name, opts);
|
||||||
|
}
|
||||||
|
|
||||||
function write_wb(wb, name, opts) {
|
function write_wb(wb, name, opts) {
|
||||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||||
}
|
}
|
||||||
@ -16724,6 +16874,10 @@ function write_cc(data, name:string, opts) {
|
|||||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function write_xlmeta(name) {
|
||||||
|
return (name.slice(-4)===".bin" ? write_xlmeta_bin : write_xlmeta_xml)();
|
||||||
|
}
|
||||||
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||||
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
||||||
function xlml_parsexmltag(tag, skip_root) {
|
function xlml_parsexmltag(tag, skip_root) {
|
||||||
@ -18980,7 +19134,7 @@ var XLSBRecordEnum = {
|
|||||||
0x002E: { n:"BrtBorder", f:parse_BrtBorder },
|
0x002E: { n:"BrtBorder", f:parse_BrtBorder },
|
||||||
0x002F: { n:"BrtXF", f:parse_BrtXF },
|
0x002F: { n:"BrtXF", f:parse_BrtXF },
|
||||||
0x0030: { n:"BrtStyle" },
|
0x0030: { n:"BrtStyle" },
|
||||||
0x0031: { n:"BrtCellMeta" },
|
0x0031: { n:"BrtCellMeta", f:parse_Int32LE },
|
||||||
0x0032: { n:"BrtValueMeta" },
|
0x0032: { n:"BrtValueMeta" },
|
||||||
0x0033: { n:"BrtMdb" },
|
0x0033: { n:"BrtMdb" },
|
||||||
0x0034: { n:"BrtBeginFmd" },
|
0x0034: { n:"BrtBeginFmd" },
|
||||||
@ -19206,7 +19360,7 @@ var XLSBRecordEnum = {
|
|||||||
0x014C: { n:"BrtBeginMetadata" },
|
0x014C: { n:"BrtBeginMetadata" },
|
||||||
0x014D: { n:"BrtEndMetadata" },
|
0x014D: { n:"BrtEndMetadata" },
|
||||||
0x014E: { n:"BrtBeginEsmdtinfo" },
|
0x014E: { n:"BrtBeginEsmdtinfo" },
|
||||||
0x014F: { n:"BrtMdtinfo" },
|
0x014F: { n:"BrtMdtinfo", f:parse_BrtMdtinfo },
|
||||||
0x0150: { n:"BrtEndEsmdtinfo" },
|
0x0150: { n:"BrtEndEsmdtinfo" },
|
||||||
0x0151: { n:"BrtBeginEsmdb" },
|
0x0151: { n:"BrtBeginEsmdb" },
|
||||||
0x0152: { n:"BrtEndEsmdb" },
|
0x0152: { n:"BrtEndEsmdb" },
|
||||||
@ -19727,7 +19881,7 @@ var XLSBRecordEnum = {
|
|||||||
0x0835: { n:"BrtEndTimelineStyleElements" },
|
0x0835: { n:"BrtEndTimelineStyleElements" },
|
||||||
0x0836: { n:"BrtDxf15" },
|
0x0836: { n:"BrtDxf15" },
|
||||||
0x0837: { n:"BrtBeginDxfs15" },
|
0x0837: { n:"BrtBeginDxfs15" },
|
||||||
0x0838: { n:"brtEndDxfs15" },
|
0x0838: { n:"BrtEndDxfs15" },
|
||||||
0x0839: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
0x0839: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
||||||
0x083A: { n:"BrtBeginItemUniqueNames" },
|
0x083A: { n:"BrtBeginItemUniqueNames" },
|
||||||
0x083B: { n:"BrtEndItemUniqueNames" },
|
0x083B: { n:"BrtEndItemUniqueNames" },
|
||||||
@ -19767,9 +19921,27 @@ var XLSBRecordEnum = {
|
|||||||
0x085D: { n:"BrtModelTimeGroupingCalcCol" },
|
0x085D: { n:"BrtModelTimeGroupingCalcCol" },
|
||||||
0x0C00: { n:"BrtUid" },
|
0x0C00: { n:"BrtUid" },
|
||||||
0x0C01: { n:"BrtRevisionPtr" },
|
0x0C01: { n:"BrtRevisionPtr" },
|
||||||
0x13e7: { n:"BrtBeginCalcFeatures" },
|
0x1000: { n:"BrtBeginDynamicArrayPr" },
|
||||||
0x13e8: { n:"BrtEndCalcFeatures" },
|
0x1001: { n:"BrtEndDynamicArrayPr" },
|
||||||
0x13e9: { n:"BrtCalcFeature" },
|
0x138A: { n:"BrtBeginRichValueBlock" },
|
||||||
|
0x138B: { n:"BrtEndRichValueBlock" },
|
||||||
|
0x13D9: { n:"BrtBeginRichFilters" },
|
||||||
|
0x13DA: { n:"BrtEndRichFilters" },
|
||||||
|
0x13DB: { n:"BrtRichFilter" },
|
||||||
|
0x13DC: { n:"BrtBeginRichFilterColumn" },
|
||||||
|
0x13DD: { n:"BrtEndRichFilterColumn" },
|
||||||
|
0x13DE: { n:"BrtBeginCustomRichFilters" },
|
||||||
|
0x13DF: { n:"BrtEndCustomRichFilters" },
|
||||||
|
0x13E0: { n:"BrtCustomRichFilter" },
|
||||||
|
0x13E1: { n:"BrtTop10RichFilter" },
|
||||||
|
0x13E2: { n:"BrtDynamicRichFilter" },
|
||||||
|
0x13E4: { n:"BrtBeginRichSortCondition" },
|
||||||
|
0x13E5: { n:"BrtEndRichSortCondition" },
|
||||||
|
0x13E6: { n:"BrtRichFilterDateGroupItem" },
|
||||||
|
0x13E7: { n:"BrtBeginCalcFeatures" },
|
||||||
|
0x13E8: { n:"BrtEndCalcFeatures" },
|
||||||
|
0x13E9: { n:"BrtCalcFeature" },
|
||||||
|
0x13EB: { n:"BrtExternalLinksPr" },
|
||||||
0xFFFF: { n:"" }
|
0xFFFF: { n:"" }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22622,9 +22794,16 @@ function parse_zip(zip, opts) {
|
|||||||
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
||||||
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
||||||
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
||||||
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile);
|
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile.replace(/_rels.*/, "s5s"));
|
||||||
|
|
||||||
|
if((dir.metadata || []).length >= 1) {
|
||||||
|
/* TODO: MDX and other types of metadata */
|
||||||
|
opts.xlmeta = parse_xlmeta(getzipdata(zip, strip_front_slash(dir.metadata[0])),dir.metadata[0],opts);
|
||||||
|
}
|
||||||
|
|
||||||
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
||||||
|
|
||||||
|
|
||||||
/* Numbers iOS hack */
|
/* Numbers iOS hack */
|
||||||
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
||||||
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
||||||
@ -22857,6 +23036,11 @@ f = "docProps/app.xml";
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta(f));
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -22865,7 +23049,7 @@ f = "docProps/app.xml";
|
|||||||
return zip;
|
return zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this version does not reference XLSB write functions */
|
||||||
function write_zip_xlsx(wb, opts) {
|
function write_zip_xlsx(wb, opts) {
|
||||||
_shapeid = 1024;
|
_shapeid = 1024;
|
||||||
if(wb && !wb.SSF) {
|
if(wb && !wb.SSF) {
|
||||||
@ -22986,6 +23170,11 @@ f = "docProps/app.xml";
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta_xml());
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -23039,6 +23228,7 @@ function read_plaintext_raw(data, o) {
|
|||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
|
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
|
||||||
|
o.type = "binary";
|
||||||
return read_plaintext(str, o);
|
return read_plaintext(str, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23157,14 +23347,15 @@ function write_zip_typeXLSX(wb, opts) {
|
|||||||
}
|
}
|
||||||
function write_zip_denouement(z, o) {
|
function write_zip_denouement(z, o) {
|
||||||
var oopts = {};
|
var oopts = {};
|
||||||
|
var ftype = has_buf ? "nodebuffer" : (typeof Uint8Array !== "undefined" ? "array" : "string");
|
||||||
if(o.compression) oopts.compression = 'DEFLATE';
|
if(o.compression) oopts.compression = 'DEFLATE';
|
||||||
if(o.password) oopts.type = has_buf ? "nodebuffer" : "string";
|
if(o.password) oopts.type = ftype;
|
||||||
else switch(o.type) {
|
else switch(o.type) {
|
||||||
case "base64": oopts.type = "base64"; break;
|
case "base64": oopts.type = "base64"; break;
|
||||||
case "binary": oopts.type = "string"; break;
|
case "binary": oopts.type = "string"; break;
|
||||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
||||||
case "buffer":
|
case "buffer":
|
||||||
case "file": oopts.type = has_buf ? "nodebuffer" : "string"; break;
|
case "file": oopts.type = ftype; break;
|
||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: {"nodebuffer": "buffer", "string": "binary"}[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: {"nodebuffer": "buffer", "string": "binary"}[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
||||||
@ -23682,7 +23873,7 @@ utils.cell_add_comment = function(cell, text, author) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* set array formula and flush related cells */
|
/* set array formula and flush related cells */
|
||||||
utils.sheet_set_array_formula = function(ws, range, formula) {
|
utils.sheet_set_array_formula = function(ws, range, formula, dynamic) {
|
||||||
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
||||||
var rngstr = typeof range == "string" ? range : encode_range(range);
|
var rngstr = typeof range == "string" ? range : encode_range(range);
|
||||||
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
||||||
@ -23690,7 +23881,10 @@ utils.sheet_set_array_formula = function(ws, range, formula) {
|
|||||||
cell.t = 'n';
|
cell.t = 'n';
|
||||||
cell.F = rngstr;
|
cell.F = rngstr;
|
||||||
delete cell.v;
|
delete cell.v;
|
||||||
if(R == rng.s.r && C == rng.s.c) cell.f = formula;
|
if(R == rng.s.r && C == rng.s.c) {
|
||||||
|
cell.f = formula;
|
||||||
|
if(dynamic) cell.D = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ws;
|
return ws;
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
989
xlsx.mini.js
989
xlsx.mini.js
File diff suppressed because it is too large
Load Diff
273
xlsx.mjs
generated
273
xlsx.mjs
generated
@ -3,7 +3,7 @@
|
|||||||
/*exported XLSX */
|
/*exported XLSX */
|
||||||
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
/*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false */
|
||||||
var XLSX = {};
|
var XLSX = {};
|
||||||
XLSX.version = '0.18.2';
|
XLSX.version = '0.18.3';
|
||||||
var current_codepage = 1200, current_ansi = 1252;
|
var current_codepage = 1200, current_ansi = 1252;
|
||||||
|
|
||||||
var VALID_ANSI = [ 874, 932, 936, 949, 950, 10000 ];
|
var VALID_ANSI = [ 874, 932, 936, 949, 950, 10000 ];
|
||||||
@ -3186,7 +3186,7 @@ function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
|
|||||||
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
|
||||||
if(typeof Deno !== 'undefined') {
|
if(typeof Deno !== 'undefined') {
|
||||||
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
/* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
|
||||||
if(enc) switch(enc) {
|
if(enc && typeof payload == "string") switch(enc) {
|
||||||
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
case "utf8": payload = new TextEncoder(enc).encode(payload); break;
|
||||||
case "binary": payload = s2ab(payload); break;
|
case "binary": payload = s2ab(payload); break;
|
||||||
/* TODO: binary equivalent */
|
/* TODO: binary equivalent */
|
||||||
@ -4310,6 +4310,9 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
|
|||||||
}
|
}
|
||||||
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
|
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
|
||||||
|
|
||||||
|
function parse_Int32LE(data) {
|
||||||
|
return data.read_shift(4, 'i');
|
||||||
|
}
|
||||||
function write_UInt32LE(x/*:number*/, o) {
|
function write_UInt32LE(x/*:number*/, o) {
|
||||||
if (!o) o = new_buf(4);
|
if (!o) o = new_buf(4);
|
||||||
o.write_shift(4, x);
|
o.write_shift(4, x);
|
||||||
@ -4975,8 +4978,8 @@ var ct2type/*{[string]:string}*/ = ({
|
|||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
|
||||||
|
|
||||||
/* Metadata */
|
/* Metadata */
|
||||||
"application/vnd.ms-excel.sheetMetadata": "TODO",
|
"application/vnd.ms-excel.sheetMetadata": "metadata",
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "TODO",
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "metadata",
|
||||||
|
|
||||||
/* PivotCache */
|
/* PivotCache */
|
||||||
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
"application/vnd.ms-excel.pivotCacheDefinition": "TODO",
|
||||||
@ -5093,6 +5096,10 @@ var CT_LIST = (function(){
|
|||||||
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
xlsx: "application/vnd.ms-excel.macrosheet+xml",
|
||||||
xlsb: "application/vnd.ms-excel.macrosheet"
|
xlsb: "application/vnd.ms-excel.macrosheet"
|
||||||
},
|
},
|
||||||
|
metadata: { /* Metadata (Stock/Geography and Dynamic Array) */
|
||||||
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
|
||||||
|
xlsb: "application/vnd.ms-excel.sheetMetadata"
|
||||||
|
},
|
||||||
styles: { /* Styles */
|
styles: { /* Styles */
|
||||||
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
|
||||||
xlsb: "application/vnd.ms-excel.styles"
|
xlsb: "application/vnd.ms-excel.styles"
|
||||||
@ -5112,7 +5119,7 @@ function new_ct()/*:any*/ {
|
|||||||
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
|
||||||
rels:[], strs:[], comments:[], links:[],
|
rels:[], strs:[], comments:[], links:[],
|
||||||
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
|
||||||
calcchains:[], vba: [], drawings: [],
|
calcchains:[], vba: [], drawings: [], metadata: [],
|
||||||
TODO:[], xmlns: "" }/*:any*/);
|
TODO:[], xmlns: "" }/*:any*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5211,6 +5218,7 @@ function write_ct(ct, opts)/*:string*/ {
|
|||||||
f3('vba');
|
f3('vba');
|
||||||
f3('comments');
|
f3('comments');
|
||||||
f3('drawings');
|
f3('drawings');
|
||||||
|
f2('metadata');
|
||||||
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
|
||||||
return o.join("");
|
return o.join("");
|
||||||
}
|
}
|
||||||
@ -5277,7 +5285,9 @@ var RELS_EXTERN = [RELS.HLINK, RELS.XPATH, RELS.XMISS];
|
|||||||
function add_rels(rels, rId/*:number*/, f, type, relobj, targetmode/*:?string*/)/*:number*/ {
|
function add_rels(rels, rId/*:number*/, f, type, relobj, targetmode/*:?string*/)/*:number*/ {
|
||||||
if(!relobj) relobj = {};
|
if(!relobj) relobj = {};
|
||||||
if(!rels['!id']) rels['!id'] = {};
|
if(!rels['!id']) rels['!id'] = {};
|
||||||
if(rId < 0) for(rId = 1; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
if(!rels['!idx']) rels['!idx'] = 1;
|
||||||
|
if(rId < 0) for(rId = rels['!idx']; rels['!id']['rId' + rId]; ++rId){/* empty */}
|
||||||
|
rels['!idx'] = rId + 1;
|
||||||
relobj.Id = 'rId' + rId;
|
relobj.Id = 'rId' + rId;
|
||||||
relobj.Type = type;
|
relobj.Type = type;
|
||||||
relobj.Target = f;
|
relobj.Target = f;
|
||||||
@ -11269,6 +11279,157 @@ function update_xfext(xf, xfext) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RELS.XLMETA = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata";
|
||||||
|
function parse_xlmeta_xml(data, name, opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
if (!data)
|
||||||
|
return out;
|
||||||
|
var pass = false;
|
||||||
|
data.replace(tagregex, function(x, idx) {
|
||||||
|
var y = parsexmltag(x);
|
||||||
|
switch (strip_ns(y[0])) {
|
||||||
|
case "<?xml":
|
||||||
|
break;
|
||||||
|
case "<metadata":
|
||||||
|
case "</metadata>":
|
||||||
|
break;
|
||||||
|
case "<metadataTypes":
|
||||||
|
case "</metadataTypes>":
|
||||||
|
break;
|
||||||
|
case "<metadataType":
|
||||||
|
out.Types.push({ name: y.name });
|
||||||
|
break;
|
||||||
|
case "<futureMetadata":
|
||||||
|
break;
|
||||||
|
case "</futureMetadata>":
|
||||||
|
break;
|
||||||
|
case "<bk>":
|
||||||
|
break;
|
||||||
|
case "</bk>":
|
||||||
|
break;
|
||||||
|
case "<rc":
|
||||||
|
break;
|
||||||
|
case "</rc>":
|
||||||
|
break;
|
||||||
|
case "<cellMetadata":
|
||||||
|
case "</cellMetadata>":
|
||||||
|
break;
|
||||||
|
case "<valueMetadata":
|
||||||
|
break;
|
||||||
|
case "</valueMetadata>":
|
||||||
|
break;
|
||||||
|
case "<extLst":
|
||||||
|
case "<extLst>":
|
||||||
|
case "</extLst>":
|
||||||
|
case "<extLst/>":
|
||||||
|
break;
|
||||||
|
case "<ext":
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case "</ext>":
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!pass && opts.WTF)
|
||||||
|
throw new Error("unrecognized " + y[0] + " in metadata");
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_xml() {
|
||||||
|
var o = [XML_HEADER];
|
||||||
|
o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
|
||||||
|
return o.join("");
|
||||||
|
}
|
||||||
|
function parse_BrtMdtinfo(data, length) {
|
||||||
|
return {
|
||||||
|
flags: data.read_shift(4),
|
||||||
|
version: data.read_shift(4),
|
||||||
|
name: parse_XLWideString(data, length - 8)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function write_BrtMdtinfo(data) {
|
||||||
|
var o = new_buf(12 + 2 * data.name.length);
|
||||||
|
o.write_shift(4, data.flags);
|
||||||
|
o.write_shift(4, data.version);
|
||||||
|
write_XLWideString(data.name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtMdb(mdb) {
|
||||||
|
var o = new_buf(4 + 8 * mdb.length);
|
||||||
|
o.write_shift(4, mdb.length);
|
||||||
|
for (var i = 0; i < mdb.length; ++i) {
|
||||||
|
o.write_shift(4, mdb[i][0]);
|
||||||
|
o.write_shift(4, mdb[i][1]);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsfmd(cnt, name) {
|
||||||
|
var o = new_buf(8 + 2 * name.length);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
write_XLWideString(name, o);
|
||||||
|
return o.slice(0, o.l);
|
||||||
|
}
|
||||||
|
function write_BrtBeginEsmdb(cnt, cm) {
|
||||||
|
var o = new_buf(8);
|
||||||
|
o.write_shift(4, cnt);
|
||||||
|
o.write_shift(4, cm ? 1 : 0);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
function parse_xlmeta_bin(data, name, _opts) {
|
||||||
|
var out = { Types: [] };
|
||||||
|
var opts = _opts || {};
|
||||||
|
var state = [];
|
||||||
|
var pass = false;
|
||||||
|
recordhopper(data, function(val, R_n, RT) {
|
||||||
|
switch (RT) {
|
||||||
|
case 335:
|
||||||
|
out.Types.push({ name: val.name });
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.push(R_n);
|
||||||
|
pass = true;
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.pop();
|
||||||
|
pass = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((R_n || "").indexOf("Begin") > 0) {
|
||||||
|
} else if ((R_n || "").indexOf("End") > 0) {
|
||||||
|
} else if (!pass || opts.WTF && state[state.length - 1] != "BrtFRTBegin")
|
||||||
|
throw new Error("Unexpected record " + RT + " " + R_n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
function write_xlmeta_bin() {
|
||||||
|
var ba = buf_array();
|
||||||
|
write_record(ba, "BrtBeginMetadata");
|
||||||
|
write_record(ba, "BrtBeginEsmdtinfo", write_UInt32LE(1));
|
||||||
|
write_record(ba, "BrtMdtinfo", write_BrtMdtinfo({
|
||||||
|
name: "XLDAPR",
|
||||||
|
version: 12e4,
|
||||||
|
flags: 3496657072
|
||||||
|
}));
|
||||||
|
write_record(ba, "BrtEndEsmdtinfo");
|
||||||
|
write_record(ba, "BrtBeginEsfmd", write_BrtBeginEsfmd(1, "XLDAPR"));
|
||||||
|
write_record(ba, "BrtBeginFmd");
|
||||||
|
write_record(ba, "BrtFRTBegin", write_UInt32LE(514));
|
||||||
|
write_record(ba, "BrtBeginDynamicArrayPr", write_UInt32LE(0));
|
||||||
|
write_record(ba, "BrtEndDynamicArrayPr", writeuint16(1));
|
||||||
|
write_record(ba, "BrtFRTEnd");
|
||||||
|
write_record(ba, "BrtEndFmd");
|
||||||
|
write_record(ba, "BrtEndEsfmd");
|
||||||
|
write_record(ba, "BrtBeginEsmdb", write_BrtBeginEsmdb(1, true));
|
||||||
|
write_record(ba, "BrtMdb", write_BrtMdb([[1, 0]]));
|
||||||
|
write_record(ba, "BrtEndEsmdb");
|
||||||
|
write_record(ba, "BrtEndMetadata");
|
||||||
|
return ba.end();
|
||||||
|
}
|
||||||
/* 18.6 Calculation Chain */
|
/* 18.6 Calculation Chain */
|
||||||
function parse_cc_xml(data/*::, name, opts*/)/*:Array<any>*/ {
|
function parse_cc_xml(data/*::, name, opts*/)/*:Array<any>*/ {
|
||||||
var d = [];
|
var d = [];
|
||||||
@ -12595,7 +12756,7 @@ function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks,
|
|||||||
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
|
||||||
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
|
||||||
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
/* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
|
||||||
if(name && name.slice(0,6) == "_xlfn.") name = name.slice(6);
|
if(name && name.slice(0,6) == "_xlfn." && !opts.xlfn) name = name.slice(6);
|
||||||
stack.push(name);
|
stack.push(name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -14493,6 +14654,7 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string
|
|||||||
}
|
}
|
||||||
if(cell.l) ws['!links'].push([ref, cell.l]);
|
if(cell.l) ws['!links'].push([ref, cell.l]);
|
||||||
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
if(cell.c) ws['!comments'].push([ref, cell.c]);
|
||||||
|
if(cell.D) o.cm = 1;
|
||||||
return writextag('c', v, o);
|
return writextag('c', v, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14669,6 +14831,10 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
|
|||||||
}
|
}
|
||||||
safe_format(p, fmtid, fillid, opts, themes, styles);
|
safe_format(p, fmtid, fillid, opts, themes, styles);
|
||||||
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
if(opts.cellDates && do_format && p.t == 'n' && SSF.is_date(SSF._table[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
|
||||||
|
if(tag.cm && opts.xlmeta) {
|
||||||
|
var cm = (opts.xlmeta.Types||[])[+tag.cm-1];
|
||||||
|
if(cm && cm.name == 'XLDAPR') p.D = true;
|
||||||
|
}
|
||||||
if(dense) {
|
if(dense) {
|
||||||
var _r = decode_cell(tag.r);
|
var _r = decode_cell(tag.r);
|
||||||
if(!s[_r.r]) s[_r.r] = [];
|
if(!s[_r.r]) s[_r.r] = [];
|
||||||
@ -15383,6 +15549,8 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
|
|
||||||
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
|
||||||
|
|
||||||
|
var cm, vm;
|
||||||
|
|
||||||
recordhopper(data, function ws_parse(val, R_n, RT) {
|
recordhopper(data, function ws_parse(val, R_n, RT) {
|
||||||
if(end) return;
|
if(end) return;
|
||||||
switch(RT) {
|
switch(RT) {
|
||||||
@ -15440,6 +15608,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
}
|
}
|
||||||
if(!af && val.length > 3) p.f = val[3];
|
if(!af && val.length > 3) p.f = val[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
if(refguess.s.r > row.r) refguess.s.r = row.r;
|
||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
@ -15447,12 +15616,17 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
if(opts.cellDates && cf && p.t == 'n' && SSF.is_date(SSF._table[cf.numFmtId])) {
|
||||||
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
var _d = SSF.parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
|
||||||
}
|
}
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0001: /* 'BrtCellBlank' */
|
case 0x0001: /* 'BrtCellBlank' */
|
||||||
case 0x000C: /* 'BrtShortBlank' */
|
case 0x000C: /* 'BrtShortBlank' */
|
||||||
if(!opts.sheetStubs || pass) break;
|
if(!opts.sheetStubs || pass) break;
|
||||||
p = ({t:'z',v:undefined}/*:any*/);
|
p = ({t:'z',v:void 0}/*:any*/);
|
||||||
C = val[0].c == -1 ? C + 1 : val[0].c;
|
C = val[0].c == -1 ? C + 1 : val[0].c;
|
||||||
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
|
||||||
else s[encode_col(C) + rr] = p;
|
else s[encode_col(C) + rr] = p;
|
||||||
@ -15460,11 +15634,20 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
if(refguess.s.c > C) refguess.s.c = C;
|
if(refguess.s.c > C) refguess.s.c = C;
|
||||||
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
if(refguess.e.r < row.r) refguess.e.r = row.r;
|
||||||
if(refguess.e.c < C) refguess.e.c = C;
|
if(refguess.e.c < C) refguess.e.c = C;
|
||||||
|
if(cm) {
|
||||||
|
if(cm.name == 'XLDAPR') p.D = true;
|
||||||
|
cm = void 0;
|
||||||
|
}
|
||||||
|
if(vm) vm = void 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x00B0: /* 'BrtMergeCell' */
|
case 0x00B0: /* 'BrtMergeCell' */
|
||||||
merges.push(val); break;
|
merges.push(val); break;
|
||||||
|
|
||||||
|
case 0x0031: { /* 'BrtCellMeta' */
|
||||||
|
cm = ((opts.xlmeta||{}).Types||[])[val-1];
|
||||||
|
} break;
|
||||||
|
|
||||||
case 0x01EE: /* 'BrtHLink' */
|
case 0x01EE: /* 'BrtHLink' */
|
||||||
var rel = rels['!id'][val.relId];
|
var rel = rels['!id'][val.relId];
|
||||||
if(rel) {
|
if(rel) {
|
||||||
@ -15552,7 +15735,6 @@ function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/
|
|||||||
case 0x041A: /* 'BrtCFVO14' */
|
case 0x041A: /* 'BrtCFVO14' */
|
||||||
case 0x0289: /* 'BrtCellIgnoreEC' */
|
case 0x0289: /* 'BrtCellIgnoreEC' */
|
||||||
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
case 0x0451: /* 'BrtCellIgnoreEC14' */
|
||||||
case 0x0031: /* 'BrtCellMeta' */
|
|
||||||
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
case 0x024D: /* 'BrtCellSmartTagProperty' */
|
||||||
case 0x025F: /* 'BrtCellWatch' */
|
case 0x025F: /* 'BrtCellWatch' */
|
||||||
case 0x0234: /* 'BrtColor' */
|
case 0x0234: /* 'BrtColor' */
|
||||||
@ -16759,6 +16941,11 @@ function parse_xlink(data, rel, name/*:string*/, opts) {
|
|||||||
return parse_xlink_xml((data/*:any*/), rel, name, opts);
|
return parse_xlink_xml((data/*:any*/), rel, name, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parse_xlmeta(data, name/*:string*/, opts) {
|
||||||
|
if(name.slice(-4)===".bin") return parse_xlmeta_bin((data/*:any*/), name, opts);
|
||||||
|
return parse_xlmeta_xml((data/*:any*/), name, opts);
|
||||||
|
}
|
||||||
|
|
||||||
function write_wb(wb, name/*:string*/, opts) {
|
function write_wb(wb, name/*:string*/, opts) {
|
||||||
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
|
||||||
}
|
}
|
||||||
@ -16788,6 +16975,10 @@ function write_cc(data, name:string, opts) {
|
|||||||
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function write_xlmeta(name/*:string*/) {
|
||||||
|
return (name.slice(-4)===".bin" ? write_xlmeta_bin : write_xlmeta_xml)();
|
||||||
|
}
|
||||||
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
|
||||||
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
|
||||||
function xlml_parsexmltag(tag/*:string*/, skip_root/*:?boolean*/) {
|
function xlml_parsexmltag(tag/*:string*/, skip_root/*:?boolean*/) {
|
||||||
@ -19056,7 +19247,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parse_BrtBorder },
|
/*::[*/0x002E/*::]*/: { n:"BrtBorder", f:parse_BrtBorder },
|
||||||
/*::[*/0x002F/*::]*/: { n:"BrtXF", f:parse_BrtXF },
|
/*::[*/0x002F/*::]*/: { n:"BrtXF", f:parse_BrtXF },
|
||||||
/*::[*/0x0030/*::]*/: { n:"BrtStyle" },
|
/*::[*/0x0030/*::]*/: { n:"BrtStyle" },
|
||||||
/*::[*/0x0031/*::]*/: { n:"BrtCellMeta" },
|
/*::[*/0x0031/*::]*/: { n:"BrtCellMeta", f:parse_Int32LE },
|
||||||
/*::[*/0x0032/*::]*/: { n:"BrtValueMeta" },
|
/*::[*/0x0032/*::]*/: { n:"BrtValueMeta" },
|
||||||
/*::[*/0x0033/*::]*/: { n:"BrtMdb" },
|
/*::[*/0x0033/*::]*/: { n:"BrtMdb" },
|
||||||
/*::[*/0x0034/*::]*/: { n:"BrtBeginFmd" },
|
/*::[*/0x0034/*::]*/: { n:"BrtBeginFmd" },
|
||||||
@ -19282,7 +19473,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x014C/*::]*/: { n:"BrtBeginMetadata" },
|
/*::[*/0x014C/*::]*/: { n:"BrtBeginMetadata" },
|
||||||
/*::[*/0x014D/*::]*/: { n:"BrtEndMetadata" },
|
/*::[*/0x014D/*::]*/: { n:"BrtEndMetadata" },
|
||||||
/*::[*/0x014E/*::]*/: { n:"BrtBeginEsmdtinfo" },
|
/*::[*/0x014E/*::]*/: { n:"BrtBeginEsmdtinfo" },
|
||||||
/*::[*/0x014F/*::]*/: { n:"BrtMdtinfo" },
|
/*::[*/0x014F/*::]*/: { n:"BrtMdtinfo", f:parse_BrtMdtinfo },
|
||||||
/*::[*/0x0150/*::]*/: { n:"BrtEndEsmdtinfo" },
|
/*::[*/0x0150/*::]*/: { n:"BrtEndEsmdtinfo" },
|
||||||
/*::[*/0x0151/*::]*/: { n:"BrtBeginEsmdb" },
|
/*::[*/0x0151/*::]*/: { n:"BrtBeginEsmdb" },
|
||||||
/*::[*/0x0152/*::]*/: { n:"BrtEndEsmdb" },
|
/*::[*/0x0152/*::]*/: { n:"BrtEndEsmdb" },
|
||||||
@ -19803,7 +19994,7 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x0835/*::]*/: { n:"BrtEndTimelineStyleElements" },
|
/*::[*/0x0835/*::]*/: { n:"BrtEndTimelineStyleElements" },
|
||||||
/*::[*/0x0836/*::]*/: { n:"BrtDxf15" },
|
/*::[*/0x0836/*::]*/: { n:"BrtDxf15" },
|
||||||
/*::[*/0x0837/*::]*/: { n:"BrtBeginDxfs15" },
|
/*::[*/0x0837/*::]*/: { n:"BrtBeginDxfs15" },
|
||||||
/*::[*/0x0838/*::]*/: { n:"brtEndDxfs15" },
|
/*::[*/0x0838/*::]*/: { n:"BrtEndDxfs15" },
|
||||||
/*::[*/0x0839/*::]*/: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
/*::[*/0x0839/*::]*/: { n:"BrtSlicerCacheHideItemsWithNoData" },
|
||||||
/*::[*/0x083A/*::]*/: { n:"BrtBeginItemUniqueNames" },
|
/*::[*/0x083A/*::]*/: { n:"BrtBeginItemUniqueNames" },
|
||||||
/*::[*/0x083B/*::]*/: { n:"BrtEndItemUniqueNames" },
|
/*::[*/0x083B/*::]*/: { n:"BrtEndItemUniqueNames" },
|
||||||
@ -19843,9 +20034,27 @@ var XLSBRecordEnum = {
|
|||||||
/*::[*/0x085D/*::]*/: { n:"BrtModelTimeGroupingCalcCol" },
|
/*::[*/0x085D/*::]*/: { n:"BrtModelTimeGroupingCalcCol" },
|
||||||
/*::[*/0x0C00/*::]*/: { n:"BrtUid" },
|
/*::[*/0x0C00/*::]*/: { n:"BrtUid" },
|
||||||
/*::[*/0x0C01/*::]*/: { n:"BrtRevisionPtr" },
|
/*::[*/0x0C01/*::]*/: { n:"BrtRevisionPtr" },
|
||||||
/*::[*/0x13e7/*::]*/: { n:"BrtBeginCalcFeatures" },
|
/*::[*/0x1000/*::]*/: { n:"BrtBeginDynamicArrayPr" },
|
||||||
/*::[*/0x13e8/*::]*/: { n:"BrtEndCalcFeatures" },
|
/*::[*/0x1001/*::]*/: { n:"BrtEndDynamicArrayPr" },
|
||||||
/*::[*/0x13e9/*::]*/: { n:"BrtCalcFeature" },
|
/*::[*/0x138A/*::]*/: { n:"BrtBeginRichValueBlock" },
|
||||||
|
/*::[*/0x138B/*::]*/: { n:"BrtEndRichValueBlock" },
|
||||||
|
/*::[*/0x13D9/*::]*/: { n:"BrtBeginRichFilters" },
|
||||||
|
/*::[*/0x13DA/*::]*/: { n:"BrtEndRichFilters" },
|
||||||
|
/*::[*/0x13DB/*::]*/: { n:"BrtRichFilter" },
|
||||||
|
/*::[*/0x13DC/*::]*/: { n:"BrtBeginRichFilterColumn" },
|
||||||
|
/*::[*/0x13DD/*::]*/: { n:"BrtEndRichFilterColumn" },
|
||||||
|
/*::[*/0x13DE/*::]*/: { n:"BrtBeginCustomRichFilters" },
|
||||||
|
/*::[*/0x13DF/*::]*/: { n:"BrtEndCustomRichFilters" },
|
||||||
|
/*::[*/0x13E0/*::]*/: { n:"BrtCustomRichFilter" },
|
||||||
|
/*::[*/0x13E1/*::]*/: { n:"BrtTop10RichFilter" },
|
||||||
|
/*::[*/0x13E2/*::]*/: { n:"BrtDynamicRichFilter" },
|
||||||
|
/*::[*/0x13E4/*::]*/: { n:"BrtBeginRichSortCondition" },
|
||||||
|
/*::[*/0x13E5/*::]*/: { n:"BrtEndRichSortCondition" },
|
||||||
|
/*::[*/0x13E6/*::]*/: { n:"BrtRichFilterDateGroupItem" },
|
||||||
|
/*::[*/0x13E7/*::]*/: { n:"BrtBeginCalcFeatures" },
|
||||||
|
/*::[*/0x13E8/*::]*/: { n:"BrtEndCalcFeatures" },
|
||||||
|
/*::[*/0x13E9/*::]*/: { n:"BrtCalcFeature" },
|
||||||
|
/*::[*/0x13EB/*::]*/: { n:"BrtExternalLinksPr" },
|
||||||
/*::[*/0xFFFF/*::]*/: { n:"" }
|
/*::[*/0xFFFF/*::]*/: { n:"" }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22699,9 +22908,16 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
|
|||||||
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
var wbrelsi = dir.workbooks[0].lastIndexOf("/");
|
||||||
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
|
||||||
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
|
||||||
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile);
|
var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile.replace(/_rels.*/, "s5s"));
|
||||||
|
|
||||||
|
if((dir.metadata || []).length >= 1) {
|
||||||
|
/* TODO: MDX and other types of metadata */
|
||||||
|
opts.xlmeta = parse_xlmeta(getzipdata(zip, strip_front_slash(dir.metadata[0])),dir.metadata[0],opts);
|
||||||
|
}
|
||||||
|
|
||||||
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
|
||||||
|
|
||||||
|
|
||||||
/* Numbers iOS hack */
|
/* Numbers iOS hack */
|
||||||
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
|
||||||
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
wsloop: for(i = 0; i != props.Worksheets; ++i) {
|
||||||
@ -22937,6 +23153,11 @@ function write_zip_xlsxb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta(f));
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -22945,7 +23166,7 @@ function write_zip_xlsxb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
return zip;
|
return zip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* this version does not reference XLSB write functions */
|
||||||
function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
||||||
_shapeid = 1024;
|
_shapeid = 1024;
|
||||||
if(wb && !wb.SSF) {
|
if(wb && !wb.SSF) {
|
||||||
@ -23067,6 +23288,11 @@ function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
|
|||||||
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = "xl/metadata." + wbext;
|
||||||
|
zip_add_file(zip, f, write_xlmeta_xml());
|
||||||
|
ct.metadata.push(f);
|
||||||
|
add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
|
||||||
|
|
||||||
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
|
||||||
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
|
||||||
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
|
||||||
@ -23120,6 +23346,7 @@ function read_plaintext_raw(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ {
|
|||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
|
if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
|
||||||
|
o.type = "binary";
|
||||||
return read_plaintext(str, o);
|
return read_plaintext(str, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23239,14 +23466,15 @@ function write_zip_typeXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
|
|||||||
}
|
}
|
||||||
function write_zip_denouement(z/*:any*/, o/*:?WriteOpts*/)/*:any*/ {
|
function write_zip_denouement(z/*:any*/, o/*:?WriteOpts*/)/*:any*/ {
|
||||||
var oopts = {};
|
var oopts = {};
|
||||||
|
var ftype = has_buf ? "nodebuffer" : (typeof Uint8Array !== "undefined" ? "array" : "string");
|
||||||
if(o.compression) oopts.compression = 'DEFLATE';
|
if(o.compression) oopts.compression = 'DEFLATE';
|
||||||
if(o.password) oopts.type = has_buf ? "nodebuffer" : "string";
|
if(o.password) oopts.type = ftype;
|
||||||
else switch(o.type) {
|
else switch(o.type) {
|
||||||
case "base64": oopts.type = "base64"; break;
|
case "base64": oopts.type = "base64"; break;
|
||||||
case "binary": oopts.type = "string"; break;
|
case "binary": oopts.type = "string"; break;
|
||||||
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
|
||||||
case "buffer":
|
case "buffer":
|
||||||
case "file": oopts.type = has_buf ? "nodebuffer" : "string"; break;
|
case "file": oopts.type = ftype; break;
|
||||||
default: throw new Error("Unrecognized type " + o.type);
|
default: throw new Error("Unrecognized type " + o.type);
|
||||||
}
|
}
|
||||||
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
|
||||||
@ -23770,7 +23998,7 @@ utils.cell_add_comment = function(cell/*:Cell*/, text/*:string*/, author/*:?stri
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* set array formula and flush related cells */
|
/* set array formula and flush related cells */
|
||||||
utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:string*/) {
|
utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:string*/, dynamic/*:boolean*/) {
|
||||||
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
var rng = typeof range != "string" ? range : safe_decode_range(range);
|
||||||
var rngstr = typeof range == "string" ? range : encode_range(range);
|
var rngstr = typeof range == "string" ? range : encode_range(range);
|
||||||
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
|
||||||
@ -23778,7 +24006,10 @@ utils.sheet_set_array_formula = function(ws/*:Worksheet*/, range, formula/*:stri
|
|||||||
cell.t = 'n';
|
cell.t = 'n';
|
||||||
cell.F = rngstr;
|
cell.F = rngstr;
|
||||||
delete cell.v;
|
delete cell.v;
|
||||||
if(R == rng.s.r && C == rng.s.c) cell.f = formula;
|
if(R == rng.s.r && C == rng.s.c) {
|
||||||
|
cell.f = formula;
|
||||||
|
if(dynamic) cell.D = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ws;
|
return ws;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user