diff --git a/docz/docs/07-csf/01-general.md b/docz/docs/07-csf/01-general.md index 24400af..36d690c 100644 --- a/docz/docs/07-csf/01-general.md +++ b/docz/docs/07-csf/01-general.md @@ -33,17 +33,21 @@ Cell objects are plain JS objects with keys and values following the convention: | Key | Description | | --- | ---------------------------------------------------------------------- | -| `v` | raw value (see [Data Types](#data-types) section for more info) | -| `w` | formatted text (if applicable) | +| | **Core Cell Properties** ([More Info](#data-types)) | +| `v` | raw value (number, string, Date object, boolean) | | `t` | type: `b` Boolean, `e` Error, `n` Number, `d` Date, `s` Text, `z` Stub | +| | **Number Formats** ([More Info](./features#number-formats)) | +| `z` | number format string associated with the cell (if requested) | +| `w` | formatted text (if applicable) | +| | **Formulae** ([More Info](./features/formulae)) | | `f` | cell formula encoded as an A1-style string (if applicable) | | `F` | range of enclosing array if formula is array formula (if applicable) | | `D` | if true, array formula is dynamic (if applicable) | +| | **Other Cell Properties** ([More Info](./features)) | +| `l` | cell hyperlink and tooltip ([More Info](./features/hyperlinks)) | +| `c` | cell comments ([More Info](./features#cell-comments)) | | `r` | rich text encoding (if applicable) | | `h` | HTML rendering of the rich text (if applicable) | -| `c` | comments associated with the cell | -| `z` | number format string associated with the cell (if requested) | -| `l` | cell hyperlink object (`.Target` holds link, `.Tooltip` is tooltip) | | `s` | the style/theme of the cell (if applicable) | Built-in export utilities (such as the CSV exporter) will use the `w` text if it diff --git a/docz/docs/07-csf/07-features/01-formulae.md b/docz/docs/07-csf/07-features/01-formulae.md new file mode 100644 index 0000000..c0ddfef --- /dev/null +++ b/docz/docs/07-csf/07-features/01-formulae.md @@ -0,0 +1,527 @@ +--- +sidebar_position: 1 +--- + +# Formulae + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +
Formulae File Format Support (click to show) + +The parser will translate from the storage representation to A1-style strings, +while the writer will translate from A1-style strings to the file format. + +| Formats | Parse | Write | Array | Dynamic | Storage Representation | +|:------------------|:-----:|:-----:|:-----:|:-------:|:-----------------------| +| XLSX / XLSM | ✔ | ✔ | ✔ | ✔ | A1-style strings | +| XLSB | ✔ | | ✔ | ✔ | BIFF parsed tokens | +| XLS | ✔ | | ✔ | | BIFF parsed tokens | +| XLML | ✔ | ✔ | ✔ | | RC-style strings | +| SYLK | ✔ | ✔ | | | A1 / RC-style strings | +| CSV / TXT | ✔ | ✔ | | | A1-style strings | +| ODS / FODS / UOS | ✔ | ✔ | | | OpenFormula strings | +| WK\* | ✔ | | | | Lotus parsed tokens | +| WQ\* / WB\* / QPW | | | | | Quattro Pro tokens | +| NUMBERS | | | | | Numbers parsed tokens | + +
+ +SheetJS supports reading and writing formulae for a number of file formats. When +supported, formulae will always be exported. + +By default, formulae are not always imported. To ensure formula parsing, the +option `cellFormula: true` should be passed to the parser. + + + + +Typically file data will be available as an `ArrayBuffer`, either downloaded +with `fetch` / `XMLHttpRequest` or user-submitted with a File Input element. +`cellFormula: true` should be added to the second options argument: + +```js +/* using read in the browser, `cellFormula` is in the second argument */ +const ab = await (await fetch("test.xlsx")).arrayBuffer(); +const workbook = XLSX.read(ab, { cellFormula: true }); +// ------------------------------^^^^^^^^^^^^^^^^^ +``` + + + + +Typically file data will be available as a `Buffer` from a network request / API +or stored in the filesystem. `cellFormula: true` should be added to the second +options argument to `read` or `readFile`: + +**`XLSX.read`** + +```js +/* using read in NodeJS, `cellFormula` is in the second argument */ +const ab = await (await fetch("test.xlsx")).arrayBuffer(); +const workbook = XLSX.read(ab, { cellFormula: true }); +// ------------------------------^^^^^^^^^^^^^^^^^ +``` + +**`XLSX.readFile`** + +```js +/* using readFile in NodeJS, add `cellFormula` to the second argument */ +const workbook = XLSX.readFile("test.xlsx", { cellFormula: true }); +// -------------------------------------------^^^^^^^^^^^^^^^^^ +``` + + + + +Typically file data will be available as a `Uint8Array` / `ArrayBuffer` from an +API or stored in the filesystem. `cellFormula: true` should be added to the +second options argument to `read` or `readFile`: + +**`XLSX.read`** + +```js +/* using read in Deno, `cellFormula` is in the second argument */ +const ab = await (await fetch("test.xlsx")).arrayBuffer(); +const workbook = XLSX.read(ab, { cellFormula: true }); +// ------------------------------^^^^^^^^^^^^^^^^^ +``` + +**`XLSX.readFile`** + +```js +/* using readFile in Deno, add `cellFormula` to the second argument */ +const workbook = XLSX.readFile("test.xlsx", { cellFormula: true }); +// -------------------------------------------^^^^^^^^^^^^^^^^^ +``` + + + + +## A1-Style Formulae + +The A1-style formula string is stored in the `f` field of the cell object. +Spreadsheet software typically represent formulae with a leading `=` sign, but +SheetJS formulae omit the `=`. + +
What is A1-style? (click to show) + +A1-style is the default in Excel. + +Columns are specified with letters, counting from `A` to `Z`, then `AA` to `ZZ`, +then `AAA`. Some sample values, along with SheetJS column indices, are listed: + +| Ordinal | A1 Name | SheetJS | +|:--------|:--------|--------:| +| First | `A` | `0` | +| Second | `B` | `1` | +| 26th | `Z` | `25` | +| 27th | `AA` | `26` | +| 702st | `ZZ` | `701` | +| 703rd | `AAA` | `702` | +| 16384th | `XFD` | `16383` | + +Rows are specified with numbers, starting from `1` for the first row. SheetJS +APIs that take row indices start from `0` (ECMAScript convention). + +A cell address is the concatenation of column text and row number. For example, +the cell in the third column and fourth row is "C4". + +A cell range is represented as the top-left cell of the range, followed by `:`, +followed by the bottom-right cell of the range. For example, the range `"C2:D4"` +includes 6 cells marked with ▒ in the table below: + + + + + + + + +
ABCDE
1
2
3
4
5
+ +A column range is represented by the left-most column, followed by `:`, followed +by the right-most column. For example, the range `C:D` represents the third and +fourth columns. + +A row range is represented by the top-most row, followed by `:`, followed by the +bottom-most column. For example, `2:4` represents the second/third/fourth rows. + +
+ +For example, consider [this test file](pathname:///files/concat.xlsx): + +![D1=CONCAT("Sheet", "JS")](pathname:///files/concat.png) + +```jsx live +/* The live editor requires this function wrapper */ +function ConcatFormula(props) { + const [text, setText] = React.useState([]); + + /* Fetch and display formula */ + React.useEffect(async() => { + /* Fetch file */ + const ab = await (await fetch("/files/concat.xlsx")).arrayBuffer(); + + /* Parse file */ + const wb = XLSX.read(ab, {cellFormula: true}); + const ws = wb.Sheets[wb.SheetNames[0]]; + + /* Look at cell D1 */ + const addr = "D1"; + const { t, v, f } = ws[addr]; + setText(`\ +CELL ADDRESS: ${addr}\n\ +CELL FORMULA: ${f}\n\ +VALUE (TYPE): "${v}" ("${t}")\n\ +`); + }, []); + + return (
{text}
); +} +``` + + +## 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", // Worksheet range A1:A3 + A1: { t: "n", v: 1 }, // A1 is a number (1) + A2: { t: "n", v: 2 }, // A2 is a number (2) + A3: { t: "n", v: 3, f: "A1+A2" } // A3 =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 +]); +``` + +
Live Example (click to show) + +```jsx live +/* The live editor requires this function wrapper */ +function ExportSimpleFormula(props) { + + /* Callback invoked when the button is clicked */ + const xport = React.useCallback(() => { + /* Create worksheet with A1=1, A2=2, A3=A1+A2 */ + var ws = XLSX.utils.aoa_to_sheet([ + [ 1 ], // A1 + [ 2 ], // A2 + [ {t: "n", v: 3, f: "A1+A2"} ] // A3 + ]); + + /* Export to file (start a download) */ + var wb = XLSX.utils.book_new(); + XLSX.utils.book_append_sheet(wb, ws, "Sheet1"); + XLSX.writeFile(wb, "SheetJSFormula1.xlsx"); + }); + + return (<> + + ); +} +``` + +
+ +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. + +The following snippet sets 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 `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 + +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 Spanish, Excel +interprets `=CONTAR(A1:C3)` as if `CONTAR` is the `COUNT` function. However, +in the actual file, Excel stores `COUNT(A1:C3)`. + +[JSON Translation table](https://oss.sheetjs.com/notes/fmla/table.json). + +
Interactive Translator (click to show) + +```jsx live +/* The live editor requires this function wrapper */ +function Translator(props) { + const [locales, setLocales] = React.useState([]); + const [data, setData] = React.useState({}); + const [names, setNames] = React.useState([]); + const [name, setName] = React.useState("Enter a function name"); + /* Fetch and display formula */ + React.useEffect(async() => { + /* Fetch data */ + const json = await (await fetch("https://oss.sheetjs.com/notes/fmla/table.json")).json(); + setLocales(Object.keys(json)); + setData(json); + setNames(json.en); + setName(json.es[0]) + }, []); + + const update_name = React.useCallback(() => { + const nameelt = document.getElementById("fmla"); + const idx = nameelt.options[nameelt.selectedIndex].value; + const toelt = document.getElementById("tolocale"); + const tovalue = toelt.options[toelt.selectedIndex].value; + setName(data[tovalue][idx]); + }); + + const update_from = React.useCallback(() => { + const fromelt = document.getElementById("fromlocale"); + const fromvalue = fromelt.options[fromelt.selectedIndex].value; + setNames(data[fromvalue]); + }); + + return (<> + Name:
+ From: + To:
+ Translation:
{name}
+ ); +} +``` + +
+ +## 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. + +
+ Functions requiring `_xlfn.` prefix (click to show) + +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 +``` + +
diff --git a/docz/docs/07-csf/07-features/02-hyperlinks.md b/docz/docs/07-csf/07-features/02-hyperlinks.md new file mode 100644 index 0000000..265d4be --- /dev/null +++ b/docz/docs/07-csf/07-features/02-hyperlinks.md @@ -0,0 +1,100 @@ +# Hyperlinks + +
+ Format Support (click to show) + +**Cell Hyperlinks**: XLSX/M, XLSB, BIFF8 XLS, XLML, ODS, HTML + +**Tooltips**: XLSX/M, XLSB, BIFF8 XLS, XLML + +
+ +Hyperlinks are stored in the `l` key of cell objects. The `Target` field of the +hyperlink object is the target of the link, including the URI fragment. Tooltips +are stored in the `Tooltip` field and are displayed when hovering over the text. + +For example, the following snippet creates a link from cell `A3` to + with the tip `"Find us @ SheetJS.com!"`: + +```js +ws["A1"].l = { Target: "https://sheetjs.com", Tooltip: "Find us @ SheetJS.com!" }; +``` + +Note that Excel does not automatically style hyperlinks. They will be displayed +using default style. SheetJS Pro Basic +extends this export with support for hyperlink styling. + +## Remote Links + +HTTP / HTTPS links can be used directly: + +```js +ws["A2"].l = { Target: "https://docs.sheetjs.com/#hyperlinks" }; +ws["A3"].l = { Target: "http://localhost:7262/yes_localhost_works" }; +``` + +Excel also supports `mailto` email links with subject line: + +```js +ws["A4"].l = { Target: "mailto:ignored@dev.null" }; +ws["A5"].l = { Target: "mailto:ignored@dev.null?subject=Test Subject" }; +``` + +## Local Links + +Links to absolute paths should use the `file://` URI scheme: + +```js +ws["B1"].l = { Target: "file:///SheetJS/t.xlsx" }; /* Link to /SheetJS/t.xlsx */ +ws["B2"].l = { Target: "file:///c:/SheetJS.xlsx" }; /* Link to c:\SheetJS.xlsx */ +``` + +Links to relative paths can be specified without a scheme: + +```js +ws["B3"].l = { Target: "SheetJS.xlsb" }; /* Link to SheetJS.xlsb */ +ws["B4"].l = { Target: "../SheetJS.xlsm" }; /* Link to ../SheetJS.xlsm */ +``` + +Relative Paths have undefined behavior in the SpreadsheetML 2003 format. Excel +2019 will treat a `..\` parent mark as two levels up. + +## Internal Links + +Links where the target is a cell or range or defined name in the same workbook +("Internal Links") are marked with a leading hash character: + +```js +ws["C1"].l = { Target: "#E2" }; /* Link to cell E2 */ +ws["C2"].l = { Target: "#Sheet2!E2" }; /* Link to cell E2 in sheet Sheet2 */ +ws["C3"].l = { Target: "#SomeDefinedName" }; /* Link to Defined Name */ +``` + +## HTML + +The HTML DOM parser will process `` links in the table: + +```jsx live +/* The live editor requires this function wrapper */ +function ExportHyperlink(props) { + + /* Callback invoked when the button is clicked */ + const xport = React.useCallback(() => { + /* Create worksheet from HTML DOM TABLE */ + const table = document.getElementById("TableLink"); + const wb = XLSX.utils.table_to_book(table); + + /* Export to file (start a download) */ + XLSX.writeFile(wb, "SheetJSHyperlink1.xlsx"); + }); + + return (<> + + + ); +} +``` diff --git a/docz/docs/07-csf/07-features/_category_.json b/docz/docs/07-csf/07-features/_category_.json new file mode 100644 index 0000000..698a3b3 --- /dev/null +++ b/docz/docs/07-csf/07-features/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Spreadsheet Features", + "position": 7 +} diff --git a/docz/docs/07-csf/07-features.md b/docz/docs/07-csf/07-features/index.md similarity index 59% rename from docz/docs/07-csf/07-features.md rename to docz/docs/07-csf/07-features/index.md index 82ca1b6..2f5a613 100644 --- a/docz/docs/07-csf/07-features.md +++ b/docz/docs/07-csf/07-features/index.md @@ -1,7 +1,3 @@ ---- -sidebar_position: 7 ---- - # Spreadsheet Features Even for basic features like date storage, the official Excel formats store the @@ -9,296 +5,6 @@ same content in different ways. The parsers are expected to convert from the underlying file format representation to the Common Spreadsheet Format. Writers are expected to convert from CSF back to the underlying file format. -## Formulae - -The A1-style formula string is stored in the `f` field. Even though different -file formats store the formulae in different ways, the formats are translated. -Even though some formats store formulae with a leading equal sign, CSF formulae -do not start with `=`. - -
- Formulae File Format Support (click to show) - -| Storage Representation | Formats | Read | Write | -|:-----------------------|:-------------------------|:-----:|:-----:| -| A1-style strings | XLSX | ✔ | ✔ | -| RC-style strings | XLML and plain text | ✔ | ✔ | -| BIFF Parsed formulae | XLSB and all XLS formats | ✔ | | -| OpenFormula formulae | ODS/FODS/UOS | ✔ | ✔ | -| Lotus Parsed formulae | All Lotus WK_ formats | ✔ | | - -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 -formulae and Lotus Parsed formulae have to be explicitly unwound. OpenFormula -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 Arrays - -_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 - -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. - -
- Functions requiring `_xlfn.` prefix (click to show) - -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
@@ -327,12 +33,12 @@ type ColInfo = { /* column width is specified in one of the following ways: */ wpx?: number; // width in screen pixels - width?: number; // width in Excel's "Max Digit Width", width*256 is integral + width?: number; // width in Excel "Max Digit Width", width*256 is integral wch?: number; // width in characters /* other fields for preserving features from files */ level?: number; // 0-indexed outline / group level - MDW?: number; // Excel's "Max Digit Width" unit, always integral + MDW?: number; // Excel "Max Digit Width" unit, always integral }; ``` @@ -447,6 +153,7 @@ var wb = { } } ``` +
The rules are slightly different from how Excel displays custom number formats. @@ -500,80 +207,18 @@ is not always the case over the Internet. To get around this ambiguity, parse functions accept the `dateNF` option to override the interpretation of that specific format string. -## Hyperlinks + +## Cell Comments
Format Support (click to show) -**Cell Hyperlinks**: XLSX/M, XLSB, BIFF8 XLS, XLML, ODS +**Simple Notes/Comments**: XLSX/M, XLSB, BIFF8 XLS (read only), XLML, ODS (read only) -**Tooltips**: XLSX/M, XLSB, BIFF8 XLS, XLML +**Threaded Comments**: XLSX/M, XLSB (read only)
-Hyperlinks are stored in the `l` key of cell objects. The `Target` field of the -hyperlink object is the target of the link, including the URI fragment. Tooltips -are stored in the `Tooltip` field and are displayed when you move your mouse -over the text. - -For example, the following snippet creates a link from cell `A3` to - with the tip `"Find us @ SheetJS.com!"`: - -```js -ws['A1'].l = { Target:"https://sheetjs.com", Tooltip:"Find us @ SheetJS.com!" }; -``` - -Note that Excel does not automatically style hyperlinks -- they will generally -be displayed as normal text. - -_Remote Links_ - -HTTP / HTTPS links can be used directly: - -```js -ws['A2'].l = { Target:"https://docs.sheetjs.com/#hyperlinks" }; -ws['A3'].l = { Target:"http://localhost:7262/yes_localhost_works" }; -``` - -Excel also supports `mailto` email links with subject line: - -```js -ws['A4'].l = { Target:"mailto:ignored@dev.null" }; -ws['A5'].l = { Target:"mailto:ignored@dev.null?subject=Test Subject" }; -``` - -_Local Links_ - -Links to absolute paths should use the `file://` URI scheme: - -```js -ws['B1'].l = { Target:"file:///SheetJS/t.xlsx" }; /* Link to /SheetJS/t.xlsx */ -ws['B2'].l = { Target:"file:///c:/SheetJS.xlsx" }; /* Link to c:\SheetJS.xlsx */ -``` - -Links to relative paths can be specified without a scheme: - -```js -ws['B3'].l = { Target:"SheetJS.xlsb" }; /* Link to SheetJS.xlsb */ -ws['B4'].l = { Target:"../SheetJS.xlsm" }; /* Link to ../SheetJS.xlsm */ -``` - -Relative Paths have undefined behavior in the SpreadsheetML 2003 format. Excel -2019 will treat a `..\` parent mark as two levels up. - -_Internal Links_ - -Links where the target is a cell or range or defined name in the same workbook -("Internal Links") are marked with a leading hash character: - -```js -ws['C1'].l = { Target:"#E2" }; /* Link to cell E2 */ -ws['C2'].l = { Target:"#Sheet2!E2" }; /* Link to cell E2 in sheet Sheet2 */ -ws['C3'].l = { Target:"#SomeDefinedName" }; /* Link to Defined Name */ -``` - -## Cell Comments - Cell comments are objects stored in the `c` array of cell objects. The actual contents of the comment are split into blocks based on the comment author. The `a` field of each comment object is the author of the comment and the `t` field @@ -713,6 +358,13 @@ function Visibility(props) { ## VBA and Macros +
+ Format Support (click to show) + +**VBA Modules**: XLSM, XLSB, BIFF8 XLS + +
+ VBA Macros are stored in a special data blob that is exposed in the `vbaraw` property of the workbook object when the `bookVBA` option is `true`. They are supported in `XLSM`, `XLSB`, and `BIFF8 XLS` formats. The supported format diff --git a/docz/static/files/concat.png b/docz/static/files/concat.png new file mode 100644 index 0000000..d0d8e49 Binary files /dev/null and b/docz/static/files/concat.png differ diff --git a/docz/static/files/concat.xlsx b/docz/static/files/concat.xlsx new file mode 100644 index 0000000..d1c80bc Binary files /dev/null and b/docz/static/files/concat.xlsx differ