diff --git a/docz/docs/07-csf/02-cell.md b/docz/docs/07-csf/02-cell.md
index 82501d79..39ad55fa 100644
--- a/docz/docs/07-csf/02-cell.md
+++ b/docz/docs/07-csf/02-cell.md
@@ -11,7 +11,7 @@ Cell objects are plain JS objects with keys and values following the convention:
| | **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](/docs/csf/features#number-formats)) |
+| | **Number Formats** ([More Info](/docs/csf/features/nf)) |
| `z` | number format string associated with the cell (if requested) |
| `w` | formatted text (if applicable) |
| | **Formulae** ([More Info](/docs/csf/features/formulae)) |
diff --git a/docz/docs/07-csf/07-features/05-names.md b/docz/docs/07-csf/07-features/05-names.md
index 78fcfefd..034ba4af 100644
--- a/docz/docs/07-csf/07-features/05-names.md
+++ b/docz/docs/07-csf/07-features/05-names.md
@@ -10,7 +10,7 @@ sidebar_position: 5
Defined names have evolved over the decades, with new features added over time:
- "English" refers to defined names with English letters and numbers (ASCII)
-- "Unicode" refers to defined names that non-English characters.
+- "Unicode" refers to defined names with non-English characters.
- "Comment" refers to comments that can be attached to defined names.
| Formats | English | Unicode | Comment |
diff --git a/docz/docs/07-csf/07-features/06-nf.md b/docz/docs/07-csf/07-features/06-nf.md
new file mode 100644
index 00000000..162b8704
--- /dev/null
+++ b/docz/docs/07-csf/07-features/06-nf.md
@@ -0,0 +1,218 @@
+---
+sidebar_position: 6
+---
+
+# Number Formats
+
+
+ File Format Support (click to show)
+
+Legacy formats like CSV mix "content" and "presentation". There is no true
+concept of a "number format" distinct from the number itself. For specific
+formats, the library will guess the number format.
+
+| Formats | Basic | Storage Representation |
+|:------------------|:-----:|:-----------------------|
+| XLSX / XLSM | ✔ | Number Format Code |
+| XLSB | ✔ | Number Format Code |
+| XLS | ✔ | Number Format Code |
+| XLML | ✔ | Number Format Code |
+| SYLK | R | Number Format Code |
+| ODS / FODS / UOS | ✔ | XML |
+| NUMBERS | | Binary encoding |
+| WK\* | | Binary encoding |
+| WQ\* / WB\* / QPW | | Binary encoding |
+| DBF | | Implied by field types |
+| CSV | * | N/A |
+| PRN | * | N/A |
+| DIF | * | N/A |
+| RTF | * | N/A |
+
+Asterisks (*) mark formats that mix content and presentation. Synthetic number
+formats may be generated for special values.
+
+The letter R (R) marks features parsed but not written in the format.
+
+
+
+The following example generates a file with some common number formats:
+
+```jsx live
+function SheetJSSimpleNF(props) {
+ const xport = React.useCallback(async () => {
+ /* Create worksheet from simple data */
+ const ws = XLSX.utils.aoa_to_sheet([
+ ["Currency", 3.5],
+ ["Thousands", 7262],
+ ["Percent", 0.0219]
+ ]);
+ /* assign number formats */
+ ws["B1"].z = '"$"#,##0_);\\("$"#,##0\\)';
+ ws["B2"].z = '#,##0';
+ ws["B3"].z = "0.00%";
+
+ /* Export to file (start a download) */
+ const wb = XLSX.utils.book_new();
+ XLSX.utils.book_append_sheet(wb, ws, "Formats");
+ XLSX.writeFile(wb, "SheetJSSimpleNF.xlsx");
+ });
+
+ return ( );
+}
+```
+
+## Values and Formatting
+
+Typically spreadsheets will include formatted text such as currencies (`$3.50`)
+or large numbers with thousands separators (`7,262`) or percentages (`2.19%`).
+
+To simplify editing, the applications will store the underlying values and the
+number formats separately. For example, `$3.50` will be represented as the value
+`3.5` with a number format that mandates a `$` sigil and 2 decimal places.
+
+Some file formats like CSV only support the formatted text. Native formats for
+spreadsheet applications including Lotus 1-2-3 and Excel will store the value
+and number format separately.
+
+### Dates and Times
+
+Many spreadsheet formats store dates and times using a number that represents
+the number of seconds or days after some epoch. Dates are covered in more detail
+[in the dedicated section](/docs/csf/features/dates).
+
+## SheetJS Representation
+
+Number formats and values are attached to cells. The following keys are used:
+
+| Key | Description |
+| --- | ---------------------------------------------------------------------- |
+| `v` | raw value (number, string, Date object, boolean) |
+| `z` | number format string associated with the cell (if requested) |
+| `w` | formatted text (if applicable) |
+
+The `cell.w` formatted text for each cell is produced from `cell.v` and `cell.z`
+format. If the format is not specified, the Excel `General` format is used.
+
+By default, parsers do not attach number formats to cells. The `cellNF` option
+instructs `XLSX.read` or `XLSX.readFile` to save the formats.
+
+### Number Format Strings
+
+The `z` format string follows the Excel persistence rules as described in
+ECMA-376 18.8.31 (Number Formats). For more info, see the Excel documentation
+article `Create or delete a custom number format`
+
+The rules are slightly different from how Excel displays custom number formats.
+In particular, literal characters must be wrapped in double quotes or preceded
+by a backslash.
+
+The following example prints number formats from a user-specified file:
+
+```jsx live
+function SheetJSExtractNF(props) {
+ const [rows, setRows] = React.useState([])
+
+ return ( <>
+ {
+ /* parse workbook with cellNF: true */
+ const file = e.target.files[0];
+ const data = await file.arrayBuffer();
+ const wb = XLSX.read(data, {cellNF: true});
+
+ const formats = {};
+ wb.SheetNames.forEach(n => {
+ var ws = wb.Sheets[n]; if(!ws || !ws["!ref"]) return;
+ var ref = XLSX.utils.decode_range(ws["!ref"]);
+ for(var R = 0; R <= ref.e.r; ++R) for(var C = 0; C <= ref.e.c; ++C) {
+ var addr = XLSX.utils.encode_cell({r:R,c:C});
+ if(!ws[addr] || !ws[addr].z) continue;
+ if(formats[ws[addr].z]) continue;
+ formats[ws[addr].z] = `'${n}'!${addr}`;
+ setRows(Object.entries(formats));
+ }
+ });
+ }}/>
+
Format
JSON
Example Cell
+ {rows.map((r,R) => (
+
{r[0]}
+
{JSON.stringify(r[0])}
+
{r[1]}
+
))}
+
+ > );
+}
+```
+
+## Miscellany
+
+The default formats are listed in ECMA-376 18.8.30:
+
+
+ Default Number Formats (click to show)
+
+| ID | Format |
+|---:|:---------------------------|
+| 0 | `General` |
+| 1 | `0` |
+| 2 | `0.00` |
+| 3 | `#,##0` |
+| 4 | `#,##0.00` |
+| 9 | `0%` |
+| 10 | `0.00%` |
+| 11 | `0.00E+00` |
+| 12 | `# ?/?` |
+| 13 | `# ??/??` |
+| 14 | `m/d/yy` (see below) |
+| 15 | `d-mmm-yy` |
+| 16 | `d-mmm` |
+| 17 | `mmm-yy` |
+| 18 | `h:mm AM/PM` |
+| 19 | `h:mm:ss AM/PM` |
+| 20 | `h:mm` |
+| 21 | `h:mm:ss` |
+| 22 | `m/d/yy h:mm` |
+| 37 | `#,##0 ;(#,##0)` |
+| 38 | `#,##0 ;[Red](#,##0)` |
+| 39 | `#,##0.00;(#,##0.00)` |
+| 40 | `#,##0.00;[Red](#,##0.00)` |
+| 45 | `mm:ss` |
+| 46 | `[h]:mm:ss` |
+| 47 | `mmss.0` |
+| 48 | `##0.0E+0` |
+| 49 | `@` |
+
+
+
+Format 14 (`m/d/yy`) is localized by Excel: even though the file specifies that
+number format, it will be drawn differently based on system settings. It makes
+sense when the producer and consumer of files are in the same locale, but that
+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.
+
+### Excel Format Categories
+
+Excel officially recognizes a small number of formats as "Currency" and another
+set of formats as "Accounting". The exact formats in `en-US` are listed below:
+
+#### Currency
+
+| JS String | Decimal Places | Negative Color |
+|:-----------------------------------------|:---------------|:---------------|
+| `'"$"#,##0_);\\("$"#,##0\\)'` | 0 | Black |
+| `'"$"#,##0_);[Red]\\("$"#,##0\\)'` | 0 | Red |
+| `'"$"#,##0.00_);\\("$"#,##0.00\\)'` | 2 | Black |
+| `'"$"#,##0.00_);[Red]\\("$"#,##0.00\\)'` | 2 | Red |
+
+#### Accounting
+
+| JS String | Decimal | Sigil |
+|:-----------------------------------------------------------------|:--------|:------|
+| `'_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)'` | 0 | |
+| `'_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)'` | 0 | `$` |
+| `'_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)'` | 2 | |
+| `'_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'` | 2 | `$` |
+
+For other locales, the formats can be discovered by creating a file with the
+desired format and testing with [the Number Format Strings demo](#number-format-strings)
+
diff --git a/docz/docs/07-csf/07-features/index.md b/docz/docs/07-csf/07-features/index.md
index 94fffd29..8bc91d90 100644
--- a/docz/docs/07-csf/07-features/index.md
+++ b/docz/docs/07-csf/07-features/index.md
@@ -138,82 +138,6 @@ follow the priority order:
-## Number Formats
-
-The `cell.w` formatted text for each cell is produced from `cell.v` and `cell.z`
-format. If the format is not specified, the Excel `General` format is used.
-The format can either be specified as a string or as an index into the format
-table. Readers are expected to populate `workbook.SSF` with the number format
-table. Writers are expected to serialize the table.
-
-The following example creates a custom format from scratch:
-
-```js
-var wb = {
- SheetNames: ["Sheet1"],
- Sheets: {
- Sheet1: {
- "!ref":"A1:C1",
- A1: { t:"n", v:10000 }, // <-- General format
- B1: { t:"n", v:10000, z: "0%" }, // <-- Builtin format
- C1: { t:"n", v:10000, z: "\"T\"\ #0.00" } // <-- Custom format
- }
- }
-}
-```
-
-The rules are slightly different from how Excel displays custom number formats.
-In particular, literal characters must be wrapped in double quotes or preceded
-by a backslash. For more info, see the Excel documentation article
-`Create or delete a custom number format` or ECMA-376 18.8.31 (Number Formats)
-
-
-
- Default Number Formats (click to show)
-
-The default formats are listed in ECMA-376 18.8.30:
-
-| ID | Format |
-|---:|:---------------------------|
-| 0 | `General` |
-| 1 | `0` |
-| 2 | `0.00` |
-| 3 | `#,##0` |
-| 4 | `#,##0.00` |
-| 9 | `0%` |
-| 10 | `0.00%` |
-| 11 | `0.00E+00` |
-| 12 | `# ?/?` |
-| 13 | `# ??/??` |
-| 14 | `m/d/yy` (see below) |
-| 15 | `d-mmm-yy` |
-| 16 | `d-mmm` |
-| 17 | `mmm-yy` |
-| 18 | `h:mm AM/PM` |
-| 19 | `h:mm:ss AM/PM` |
-| 20 | `h:mm` |
-| 21 | `h:mm:ss` |
-| 22 | `m/d/yy h:mm` |
-| 37 | `#,##0 ;(#,##0)` |
-| 38 | `#,##0 ;[Red](#,##0)` |
-| 39 | `#,##0.00;(#,##0.00)` |
-| 40 | `#,##0.00;[Red](#,##0.00)` |
-| 45 | `mm:ss` |
-| 46 | `[h]:mm:ss` |
-| 47 | `mmss.0` |
-| 48 | `##0.0E+0` |
-| 49 | `@` |
-
-
-
-Format 14 (`m/d/yy`) is localized by Excel: even though the file specifies that
-number format, it will be drawn differently based on system settings. It makes
-sense when the producer and consumer of files are in the same locale, but that
-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.
-
-
## Sheet Visibility
diff --git a/docz/docs/08-api/05-parse-options.md b/docz/docs/08-api/03-parse-options.md
similarity index 99%
rename from docz/docs/08-api/05-parse-options.md
rename to docz/docs/08-api/03-parse-options.md
index 57b3fe53..3935894a 100644
--- a/docz/docs/08-api/05-parse-options.md
+++ b/docz/docs/08-api/03-parse-options.md
@@ -1,5 +1,5 @@
---
-sidebar_position: 5
+sidebar_position: 3
hide_table_of_contents: true
title: Reading Files
---
diff --git a/docz/docs/08-api/07-write-options.md b/docz/docs/08-api/05-write-options.md
similarity index 99%
rename from docz/docs/08-api/07-write-options.md
rename to docz/docs/08-api/05-write-options.md
index fd8e64af..fcecb233 100644
--- a/docz/docs/08-api/07-write-options.md
+++ b/docz/docs/08-api/05-write-options.md
@@ -1,5 +1,5 @@
---
-sidebar_position: 7
+sidebar_position: 5
hide_table_of_contents: true
title: Writing Files
---
diff --git a/docz/docs/08-api/09-utilities/09-formulae.md b/docz/docs/08-api/07-utilities/09-formulae.md
similarity index 99%
rename from docz/docs/08-api/09-utilities/09-formulae.md
rename to docz/docs/08-api/07-utilities/09-formulae.md
index 6fa2e181..71e6183b 100644
--- a/docz/docs/08-api/09-utilities/09-formulae.md
+++ b/docz/docs/08-api/07-utilities/09-formulae.md
@@ -1,6 +1,6 @@
---
sidebar_position: 9
-title: Formulae Output
+title: Array of Formulae
pagination_next: miscellany/formats
---
diff --git a/docz/docs/08-api/09-utilities/_category_.json b/docz/docs/08-api/07-utilities/_category_.json
similarity index 78%
rename from docz/docs/08-api/09-utilities/_category_.json
rename to docz/docs/08-api/07-utilities/_category_.json
index 6d797b39..b747ff89 100644
--- a/docz/docs/08-api/09-utilities/_category_.json
+++ b/docz/docs/08-api/07-utilities/_category_.json
@@ -1,5 +1,5 @@
{
"label": "Utility Functions",
"collapsed": false,
- "position": 9
+ "position": 7
}
diff --git a/docz/docs/08-api/09-utilities/index.md b/docz/docs/08-api/07-utilities/index.md
similarity index 99%
rename from docz/docs/08-api/09-utilities/index.md
rename to docz/docs/08-api/07-utilities/index.md
index ecf35bdf..a19fff00 100644
--- a/docz/docs/08-api/09-utilities/index.md
+++ b/docz/docs/08-api/07-utilities/index.md
@@ -440,7 +440,7 @@ can be added to the individual TD elements:
|:----------|:-------------------------------------------------------------|
| `data-t` | Override [Cell Type](/docs/csf/cell#data-types) |
| `data-v` | Override Cell Value |
-| `data-z` | Override [Number Format](/docs/csf/features/#number-formats) |
+| `data-z` | Override [Number Format](/docs/csf/features/nf) |
For example: