clarifying formula localization

This commit is contained in:
SheetJS 2026-01-21 01:14:24 -05:00
parent b205f3f6a1
commit def11cf796
16 changed files with 351 additions and 192 deletions

@ -121,11 +121,11 @@ This demo was last tested in the following deployments:
| Architecture | BunJS | Date |
|:-------------|:---------|:-----------|
| `darwin-x64` | `1.2.8` | 2025-03-31 |
| `darwin-arm` | `1.2.7` | 2025-03-30 |
| `darwin-x64` | `1.3.6` | 2026-01-20 |
| `darwin-arm` | `1.3.6` | 2026-01-19 |
| `win11-x64` | `1.2.8` | 2025-04-17 |
| `win11-arm` | `1.2.3` | 2025-02-23 |
| `linux-x64` | `1.2.10` | 2025-04-21 |
| `linux-x64` | `1.3.6` | 2026-01-18 |
| `linux-arm` | `1.2.2` | 2025-02-16 |
BunJS on Windows on ARM uses the X64 compatibility layer.

@ -39,15 +39,17 @@ This demo was tested in the following configurations:
| NVIDIA RTX PRO 6000 (96 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2025-11-15 |
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | 2025-11-15 |
| NVIDIA RTX 5090 (32 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2025-11-15 |
| AMD AI PRO R9700 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2026-01-17 |
| AMD AI PRO R9700 (32 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2026-01-17 |
| AMD RX 9070 XT (16 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `win11-x64` | 2026-01-17 |
| AMD RX 9070 XT (16 GB VRAM) + Ryzen Z2 Go (32 GB RAM) | `linux-x64` | 2026-01-17 |
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-11-15 |
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-11-15 |
| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `linux-x64` | 2025-11-15 |
| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `win11-x64` | 2025-11-15 |
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-11-15 |
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-11-15 |
| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `linux-x64` | 2025-11-15 |
| AMD RYZEN AI MAX+ 395 + Radeon 8060S (128 GB unified memory) | `win11-x64` | 2025-11-15 |
| Apple M4 Max 16-Core CPU + 40-Core GPU (48 GB unified memory) | `darwin-arm` | 2025-11-15 |
| Apple M3 Ultra 28-Core CPU + 60-Core GPU (96 GB unified memory) | `darwin-arm` | 2025-11-15 |
| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | 2025-11-15 |
SheetJS users have verified this demo in other configurations:
@ -75,6 +77,8 @@ SheetJS users have verified this demo in other configurations:
| NVIDIA GTX 1070 (8 GB VRAM) + Ryzen 7 7700x (32 GB RAM) | `win11-x64` | LangChainJS |
| AMD RX 6800 XT (16 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | LangChainJS |
| Apple M4 10-Core CPU + 10-Core GPU (24 GB unified memory) | `darwin-arm` | LangChainJS |
| Apple M3 Ultra 28-Core CPU + 60-Core GPU (96 GB unified memory) | `darwin-arm` | LangChainJS |
| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | LangChainJS |
</details>
@ -386,7 +390,7 @@ includes one header row and a number of data rows.
```js title="loadofsheet.mjs"
import { Document } from "@langchain/core/documents";
import { BufferLoader } from "langchain/document_loaders/fs/buffer";
import { BufferLoader } from "@langchain/classic/document_loaders/fs/buffer";
import { read, utils } from "xlsx";
/**
@ -525,7 +529,7 @@ export class CSVLoader extends TextLoader {
The SheetJS `read` method supports NodeJS Buffer objects directly[^6]:
```js title="Parsing a workbook in a BufferLoader"
import { BufferLoader } from "langchain/document_loaders/fs/buffer";
import { BufferLoader } from "@langchain/classic/document_loaders/fs/buffer";
import { read, utils } from "xlsx";
export default class LoadOfSheet extends BufferLoader {
@ -836,6 +840,62 @@ D) Run the `start-ollama.sh` script from the extracted folder.
:::
:::caution pass
AMD GPUs may require special ROCm / HIP libraries.
<details>
<summary><b>AMD Instructions on Windows</b> (click to show)</summary>
[`ollama-for-amd`](https://github.com/likelovewant/ollama-for-amd) is a
community fork that provides support for many AMD GPUs.
[Installers](https://github.com/ByronLeeeee/Ollama-For-AMD-Installer/releases)
are also provided by the community.
There are separate drivers for each GPU family. The following GPUs were tested:
| Name | GPU | Identifier |
|:-----------------|:--------|:-----------|
| AMD AI PRO R9700 | Navi 48 | `gfx1200` |
| AMD RX 9070 XT | Navi 48 | `gfx1201` |
| AND RX 7900 XTX | Navi 31 | `gfx1100` |
When this demo was last tested, the installer claimed `gfx1200` corresponded to
Navi 48. `gfx1200` should be used for the PRO R9700, while `gfx1201` should be
used for the 9070 XT.
</details>
<details>
<summary><b>AMD Instructions on Linux</b> (click to show)</summary>
The official Ollama release is compatible with AMD cards. However, in some test
runs, Ollama will try to use the CPU. Some environment variables were required:
```bash
export OLLAMA_USE_ROCM=1
export OLLAMA_GPU_LAYERS=999
export OLLAMA_VULKAN=1
```
In addition, `HSA_OVERRIDE_GFX_VERSION` must be set to a specific version based
on the card, which may not match the official version:
| Name | Value | Command |
|:-----------------|:---------|:-------------------------------------------|
| AMD AI PRO R9700 | `12.0.0` | `export HSA_OVERRIDE_GFX_VERSION="12.0.0"` |
| AMD RX 9070 XT | `12.0.0` | `export HSA_OVERRIDE_GFX_VERSION="12.0.0"` |
| AND RX 7900 XTX | `11.0.0` | `export HSA_OVERRIDE_GFX_VERSION="11.0.0"` |
These environment variables may not be used by the Ollama service, so it is
strongly recommended to stop the default service and run `ollama serve` in a
separate terminal window.
</details>
:::
After installing dependencies, start a new terminal session.
1) Create a new project:
@ -882,7 +942,7 @@ npm i --save https://sheet.lol/balls/xlsx-${current}.tgz`}
4) Install dependencies:
```bash
npm i --save @langchain/core@0.3.78 langchain@0.3.36 @langchain/ollama@0.2.4 peggy@3.0.2
npm i --save @langchain/core@1.1.15 langchain@1.2.10 @langchain/classic@1.0.9 @langchain/ollama@1.2.0 peggy@5.0.6
```
:::note pass
@ -891,7 +951,7 @@ In some test runs, there were error messages relating to dependency and peer
dependency versions. The `--force` flag will suppress version mismatch errors:
```bash
npm i --save @langchain/core@0.3.78 langchain@0.3.36 @langchain/ollama@0.2.4 peggy@3.0.2 --force
npm i --save @langchain/core@1.1.15 langchain@1.2.10 @langchain/classic@1.0.9 @langchain/ollama@1.2.0 peggy@5.0.6 --force
```
:::

@ -41,7 +41,7 @@ This demo was tested in the following deployments:
| `darwin-arm` | `5.0.0-beta.4` | `22.14.0` | Compiled | 2025-06-18 |
| `win11-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-05-07 |
| `win11-arm` | `4.0.0-rc.6` | `22.14.0` | Compiled | 2025-02-23 |
| `linux-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2025-04-21 |
| `linux-x64` | `5.0.0-beta.4` | `14.15.3` | Pre-built | 2026-01-18 |
| `linux-arm` | `4.0.0-rc.6` | `22.13.0` | Compiled | 2025-02-15 |
:::

@ -41,7 +41,7 @@ This demo was tested in the following deployments:
| `darwin-arm` | `5.8.1` | `18.5.0` | 2025-06-18 |
| `win11-x64` | `5.8.1` | `18.5.0` | 2025-05-07 |
| `win11-arm` | `5.8.1` | `18.5.0` | 2025-02-23 |
| `linux-x64` | `5.8.1` | `18.5.0` | 2025-04-21 |
| `linux-x64` | `5.8.1` | `18.5.0` | 2026-01-18 |
| `linux-arm` | `5.8.1` | `18.5.0` | 2025-02-15 |
:::

@ -91,7 +91,7 @@ yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz exit-on-epi
<TabItem value="unix" label="Linux/MacOS">
```bash
npx -y boxednode@2.4.4 -s xlsx-cli.js -t xlsx-cli
npx -y boxednode@3.0.0 -s xlsx-cli.js -t xlsx-cli
```
:::note pass

@ -88,14 +88,14 @@ console.log(csv);
This demo was tested in the following deployments:
| Architecture | TxikiJS | Date |
|:-------------|:----------|:-----------|
| `darwin-x64` | `24.12.0` | 2025-04-19 |
| `darwin-arm` | `24.12.0` | 2025-04-19 |
| `win11-x64` | `24.12.0` | 2025-04-19 |
| `win11-arm` | `24.12.0` | 2025-04-19 |
| `linux-x64` | `24.12.0` | 2025-04-19 |
| `linux-arm` | `24.12.0` | 2025-04-19 |
| Architecture | Version | Commit | Date |
|:-------------|:----------|:----------|:-----------|
| `darwin-x64` | `24.12.0` | | 2025-04-19 |
| `darwin-arm` | `24.12.0` | `793dd9d` | 2026-01-18 |
| `win11-x64` | `24.12.0` | | 2025-04-19 |
| `win11-arm` | `24.12.0` | | 2025-04-19 |
| `linux-x64` | `24.12.0` | `65e5595` | 2026-01-18 |
| `linux-arm` | `24.12.0` | | 2025-04-19 |
:::
@ -133,6 +133,40 @@ cp build/tjs ../
cd ..
```
:::caution pass
In some `linux-x64` test runs, the `make` step failed:
```
make[5]: *** No rule to make target 'all-configured'. Stop.
```
After re-running `make`, the `[ 0%]` line identifies the root cause:
```text
// highlight-next-line
[ 0%] Performing build step for 'libffi'
[ 1%] Built target sqlite3
[ 2%] Built target ffi-test
...
[ 61%] Built target sqlite-test
MAKE x86_64-pc-linux-gnu : 0 * all-configured
// highlight-next-line
make[5]: *** No rule to make target 'all-configured'. Stop.
```
If the root cause is `libffi`, it is possible to use the system `libffi`. The
following commands should be run in the `txiki.js` folder:
```bash
rm -rf build
cmake -B build -DCMAKE_BUILD_TYPE=Release -DUSE_EXTERNAL_FFI=ON
cmake --build build -j 32
cp build/tjs ../
```
:::
</TabItem>
<TabItem value="win11-x64" label="Windows">

@ -784,8 +784,8 @@ This demo was tested in the following deployments:
| Architecture | Version | Zig | Date |
|:-------------|:--------|:---------|:-----------|
| `darwin-x64` | `2.7.0` | `0.14.0` | 2025-03-31 |
| `darwin-arm` | `2.7.0` | `0.13.0` | 2025-02-13 |
| `darwin-x64` | `2.7.0` | `0.15.2` | 2026-01-20 |
| `darwin-arm` | `2.7.0` | `0.15.2` | 2026-01-20 |
| `win11-x64` | `2.7.0` | `0.14.0` | 2025-04-28 |
| `win11-arm` | `2.7.0` | `0.13.0` | 2025-02-23 |
| `linux-x64` | `2.7.0` | `0.14.0` | 2025-04-21 |
@ -812,15 +812,15 @@ the project folder.
For X64 Mac:
```bash
curl -LO https://ziglang.org/download/0.14.0/zig-macos-x86_64-0.14.0.tar.xz
tar -xzf zig-macos-*.tar.xz
curl -LO https://ziglang.org/download/0.15.2/zig-x86_64-macos-0.15.2.tar.xz
tar -xzf zig-*.tar.xz
```
For ARM64 Mac:
```bash
curl -LO https://ziglang.org/download/0.13.0/zig-macos-aarch64-0.13.0.tar.xz
tar -xzf zig-macos-*.tar.xz
curl -LO https://ziglang.org/download/0.15.2/zig-aarch64-macos-0.15.2.tar.xz
tar -xzf zig-*.tar.xz
```

@ -131,8 +131,8 @@ This demo was tested in the following deployments:
| Architecture | Git Commit | Date |
|:-------------|:-----------|:-----------|
| `darwin-x64` | `36becec` | 2025-03-31 |
| `darwin-arm` | `36becec` | 2025-09-03 |
| `darwin-x64` | `792ee76` | 2026-01-20 |
| `darwin-arm` | `792ee76` | 2026-01-20 |
| `win11-x64` | `36becec` | 2025-04-28 |
| `win11-arm` | `e26c81f` | 2025-02-23 |
| `linux-x64` | `36becec` | 2025-06-18 |
@ -215,7 +215,7 @@ cd ..
```bash
cd ChakraCore
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --system-icu --no-jit
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --no-jit
cd ..
```
@ -233,6 +233,7 @@ This was fixed with a local symlink to the `icu4c` folder before the build step:
cd ChakraCore
mkdir -p usr/local/opt
ln -s /opt/homebrew/opt/icu4c usr/local/opt/icu4c
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --system-icu --no-jit
cd ..
```
@ -291,12 +292,10 @@ When the demo was last tested, ChakraCore JIT was not supported.
```bash
cd ChakraCore
export PATH="$(brew --prefix cmake3)/bin:${PATH}"
./build.sh --static --icu=$(brew --prefix)/opt/icu4c/include --test-build -j=8 --no-jit
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --no-jit
cd ..
```
:::
:::caution Troubleshooting

@ -322,8 +322,8 @@ This demo was tested in the following deployments:
| Architecture | Version | Date |
|:-------------|:--------|:-----------|
| `darwin-x64` | `1.3.6` | 2025-03-31 |
| `darwin-arm` | `1.3.6` | 2025-09-03 |
| `darwin-x64` | `1.3.8` | 2026-01-20 |
| `darwin-arm` | `1.3.8` | 2026-01-20 |
| `win11-x64` | `1.3.6` | 2025-04-23 |
| `win11-arm` | `1.3.5` | 2025-02-23 |
| `linux-x64` | `1.3.6` | 2025-06-16 |

@ -33,110 +33,34 @@ to mark a dynamic array formula in the XLS file format.
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.
The ["A1-Style"](/docs/csf/general#a1-style) formula string is stored in the `f`
field of the cell object. The SheetJS formula string closely matches the text
representation in spreadsheet file formats.
<Tabs>
<TabItem value="browser" label="Browser">
:::caution pass
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:
**SheetJS formula strings do not always match Excel or other spreadsheets!**
```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 });
// ------------------------------^^^^^^^^^^^^^^^^^
```
- Spreadsheet software typically represent formulae with a leading `=` sign, but
SheetJS formulae omit the `=`.
</TabItem>
<TabItem value="nodejs" label="NodeJS">
- Spreadsheet software [localize formulae](#localization), but SheetJS formulae
always use the `en-US` form.
Typically file data will be available as a `Buffer` from a network request / API
or stored in the file system. `cellFormula: true` should be added to the second
options argument to `read` or `readFile`:
- Spreadsheet software may display formulae in RC notation, but SheetJS formulae
always use A1-Style.
**`XLSX.read`**
- Spreadsheet software will hide [prefixes](#prefixed-future-functions). SheetJS
parsers provide options to replicate that behavior.
```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 });
// ------------------------------^^^^^^^^^^^^^^^^^
```
When building new exports, it is strongly recommended to create a sample file in
Excel, parse with the SheetJS library, and inspect the formula string.
**`XLSX.readFile`**
:::
```js
/* using readFile in NodeJS, add `cellFormula` to the second argument */
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
// -------------------------------------------^^^^^^^^^^^^^^^^^
```
## Live Demo
</TabItem>
<TabItem value="bun" label="Bun">
Typically file data will be available as a `Uint8Array` from a network request
or stored in the file system. `cellFormula: true` should be set in the options
argument to `read` or `readFile`:
**`XLSX.read`**
```js
/* using read in Bun, `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 Bun, add `cellFormula` to the second argument */
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
// -------------------------------------------^^^^^^^^^^^^^^^^^
```
</TabItem>
<TabItem value="deno" label="Deno">
Typically file data will be available as a `Uint8Array` or `ArrayBuffer` from
API or stored in the file system. `cellFormula: true` should be set in the
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 });
// -------------------------------------------^^^^^^^^^^^^^^^^^
```
</TabItem>
</Tabs>
## 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 `=`.
["A1-Style"](/docs/csf/general#a1-style) describes A1-Style in more detail.
<details open>
<summary><b>Live Example</b> (click to hide)</summary>
For example, consider [this test file](pathname:///files/concat.xlsx):
[This test file](pathname:///files/concat.xlsx) includes a formula in cell `D1`:
![Screenshot](pathname:///files/concat.png)
@ -144,7 +68,7 @@ The following code block fetches the file, parses and prints info on cell `D1`:
```jsx live
/* The live editor requires this function wrapper */
function ConcatFormula(props) {
function InspectCellFormula(props) {
const [ws, setWS] = React.useState({"!ref":"A1"});
const [addr, setAddr] = React.useState("D1");
const setaddr = React.useCallback((evt)=>{ setAddr(evt.target.value) });
@ -163,7 +87,8 @@ function ConcatFormula(props) {
process_ab(await e.target.files[0].arrayBuffer());
};
return ( <>
<input type="file" onChange={process_file}/><br/>
<b>Select a file to inspect cell formulae</b><br/>
<input type="file" onChange={process_file}/><br/><br/>
<b>Cell: </b><input type="text" value={addr} onChange={setaddr} size="6"/>
{!ws[addr] ? ( <b>Cell {addr} not found</b> ) : ( <table>
<tr><td>Formula</td><td><code>{ws[addr].f}</code></td></tr>
@ -174,9 +99,9 @@ function ConcatFormula(props) {
}
```
</details>
## Storage
## Single-Cell 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`:
@ -250,7 +175,7 @@ values and dependent cells, and refreshing entire workbooks.
:::
## Array Formulae
### Array Formulae
_Assign an array formula_
@ -393,20 +318,129 @@ function ExportDynamicArrayFormulae(props) {
</details>
## Functions
#### Reading Files
[`read` and `readFile`](/docs/api/parse-options) accept an options argument. The
`cellFormula` option should be set to `true` to expose cell formulae:
<Tabs>
<TabItem value="browser" label="Browser">
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 });
// ------------------------------^^^^^^^^^^^^^^^^^
```
</TabItem>
<TabItem value="nodejs" label="NodeJS">
Typically file data will be available as a `Buffer` from a network request / API
or stored in the file system. `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 });
// -------------------------------------------^^^^^^^^^^^^^^^^^
```
</TabItem>
<TabItem value="bun" label="Bun">
Typically file data will be available as a `Uint8Array` from a network request
or stored in the file system. `cellFormula: true` should be set in the options
argument to `read` or `readFile`:
**`XLSX.read`**
```js
/* using read in Bun, `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 Bun, add `cellFormula` to the second argument */
const workbook = XLSX.readFile("test.xlsx", { cellFormula: true });
// -------------------------------------------^^^^^^^^^^^^^^^^^
```
</TabItem>
<TabItem value="deno" label="Deno">
Typically file data will be available as a `Uint8Array` or `ArrayBuffer` from
API or stored in the file system. `cellFormula: true` should be set in the
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 });
// -------------------------------------------^^^^^^^^^^^^^^^^^
```
</TabItem>
</Tabs>
## 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.
Excel and other spreadsheet software will display different formula strings in
different countries and locales.
SheetJS parsers and writers do not attempt locale-specific changes.
For example, the Spanish Excel formula `=CONTAR(A1:C3;B4:D6)` is equivalent to
the SheetJS formula string `COUNT(A1:A3,B4:D6)` .
### Grammar
SheetJS formula function arguments are always separated with commas (`,`).
| SheetJS | `en-US` Excel | `es-ES` Excel |
|:-------------|:--------------|:--------------|
| `ATAN2(1,1)` | `=ATAN2(1,1)` | `=ATAN2(1;1)` |
### Function Names
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)`.
Function arguments are separated with commas. For example, the Spanish Excel
formula `=CONTAR(A1:C3;B4:D6)` is equivalent to the SheetJS formula string
`COUNT(A1:A3,B4:D6)`
[JSON Translation table](https://docs.sheetjs.com/fmla/table.json).
<details open>

@ -1,5 +1,5 @@
import { Document } from "@langchain/core/documents";
import { BufferLoader } from "langchain/document_loaders/fs/buffer";
import { BufferLoader } from "@langchain/classic/document_loaders/fs/buffer";
import { read, utils } from "xlsx";
/**

@ -1,6 +1,6 @@
import { ChatOllama, OllamaEmbeddings } from "@langchain/ollama";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { SelfQueryRetriever } from "langchain/retrievers/self_query";
import { MemoryVectorStore } from "@langchain/classic/vectorstores/memory";
import { SelfQueryRetriever } from "@langchain/classic/retrievers/self_query";
import { FunctionalTranslator } from "@langchain/core/structured_query";
import LoadOfSheet from "./loadofsheet.mjs";

39
tests/cli/txiki.sh Executable file

@ -0,0 +1,39 @@
#!/bin/bash
# https://docs.sheetjs.com/docs/demos/cli/txiki
cd /tmp
rm -rf sheetjs-txiki
mkdir sheetjs-txiki
cd sheetjs-txiki
curl -o pres.numbers https://docs.sheetjs.com/pres.numbers
cat >sheet2csv.js <<'EOF'
const XLSX = require("./xlsx.full.min");
/* tjs.args[1] is the first argument to the script */
const filename = tjs.args[1];
/* read and parse file */
const data = await tjs.readFile(filename);
const wb = XLSX.read(data);
/* generate CSV of first sheet */
const ws = wb.Sheets[wb.SheetNames[0]];
const csv = XLSX.utils.sheet_to_csv(ws);
/* print to terminal */
console.log(csv);
EOF
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
## NOTE: these steps are for darwin
curl -LO https://github.com/saghul/txiki.js/releases/download/v24.12.0/txiki-macos.zip
unzip txiki-macos.zip
mv txiki-macos/tjs .
chmod +x tjs
npx -y esbuild sheet2csv.js --bundle --outfile=bundle.js --platform=neutral
./tjs compile bundle.js sheet2csv
./sheet2csv pres.numbers

@ -9,54 +9,10 @@ cd sheetjs-chakra
git clone https://github.com/chakra-core/ChakraCore.git
cd ChakraCore
git checkout e26c81f
git checkout 792ee76
cd ..
cd ChakraCore
## in commit e26c81f in macOS 15.2, the build fails with the following error:
##
##/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk/usr/include/c++/v1/new:279:66: error: redefinition of 'operator new'
## 279 | _LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_HIDE_FROM_ABI void* operator new(std::size_t, void* __p) _NOEXCEPT {
## | ^
##/tmp/sheetjs-chakra/ChakraCore/lib/Common/Memory/Allocator.h:457:1: note: previous definition is here
## 457 | operator new(
## | ^
##
## This patch avoids the issues
cat <<EOF >sheetjs.patch
diff --git a/lib/Common/Memory/Allocator.h b/lib/Common/Memory/Allocator.h
index 5a3a099bc..e05a7390f 100644
--- a/lib/Common/Memory/Allocator.h
+++ b/lib/Common/Memory/Allocator.h
@@ -452,24 +452,7 @@ void AssertValue(void * mem, T value, uint byteCount)
#ifndef __PLACEMENT_NEW_INLINE
#define __PLACEMENT_NEW_INLINE
-_Ret_notnull_
-NO_EXPORT(inline void *) __cdecl
-operator new(
-DECLSPEC_GUARD_OVERFLOW size_t byteSize,
-_In_ void * previousAllocation) throw()
-{
- return previousAllocation;
-}
-
-
-NO_EXPORT(inline void) __cdecl
-operator delete(
-void * allocationToFree, // Allocation to free
-void * previousAllocation // Previously allocated memory
-) throw()
-{
-
-}
+#include <new>
#endif
EOF
git apply sheetjs.patch
./build.sh --static --icu=/usr/local/opt/icu4c/include --test-build -j=8 --no-jit
cd ..
@ -66,7 +22,6 @@ curl -L -O https://docs.sheetjs.com/chakra/Makefile
make
curl -L -O https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
curl -L -O https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js
curl -L -O https://docs.sheetjs.com/pres.numbers
./sheetjs.ch pres.numbers

38
tests/engines/duktape-zig.sh Executable file

@ -0,0 +1,38 @@
#!/bin/bash
# https://docs.sheetjs.com/docs/demos/engines/duktape#zig-demo
cd /tmp
rm -rf sheetjs-zig
mkdir -p sheetjs-zig
cd sheetjs-zig
## NOTE: these steps are for darwin
case "$(uname -m)" in
arm64) curl -LO https://ziglang.org/download/0.15.2/zig-aarch64-macos-0.15.2.tar.xz ;;
x86_64) curl -LO https://ziglang.org/download/0.15.2/zig-x86_64-macos-0.15.2.tar.xz ;;
*) echo "unsupported arch $(uname -m)"; exit 1 ;;
esac
tar -xzf zig-*.tar.xz
./zig-*/zig init
curl -LO https://duktape.org/duktape-2.7.0.tar.xz
tar -xJf duktape-2.7.0.tar.xz
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/shim.min.js
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
curl -LO https://docs.sheetjs.com/pres.numbers
mv *.js src
curl -L -o src/main.zig https://docs.sheetjs.com/duk/main.zig
sed -i '' '/b.installArtifact(exe);/ i\
exe.addCSourceFile(.{ .file = b.path("duktape-2.7.0/src/duktape.c"), .flags = &.{ "-std=c99", "-fno-sanitize=undefined" } });\
exe.addIncludePath(b.path("duktape-2.7.0/src"));\
exe.linkSystemLibrary("c");\
exe.linkSystemLibrary("m");' build.zig
./zig-*/zig build run -- pres.numbers; echo $?
npx -y xlsx-cli sheetjs.zig.xlsx

@ -7,7 +7,7 @@ rm -rf sheetjs-mu
mkdir sheetjs-mu
cd sheetjs-mu
curl -LO https://mujs.com/downloads/mujs-1.3.6.zip
curl -LO https://mujs.com/downloads/mujs-1.3.8.zip
unzip mujs-*.zip
rm mujs-*.zip
cd mujs-*