diff --git a/docz/docs/03-demos/01-math/21-pandas.md b/docz/docs/03-demos/01-math/21-pandas.md
index ab1231e..77ca364 100644
--- a/docz/docs/03-demos/01-math/21-pandas.md
+++ b/docz/docs/03-demos/01-math/21-pandas.md
@@ -1,7 +1,7 @@
---
-title: Spreadsheet Data in Pandas
-sidebar_label: Python + Pandas
-description: Process structured data in Python with Pandas. Seamlessly integrate spreadsheets into your workflow with SheetJS. Analyze complex Excel spreadsheets with confidence.
+title: Spreadsheet Data in Python
+sidebar_label: Python DataFrames
+description: Process structured data in Python DataFrames. Seamlessly integrate spreadsheets into your workflow with SheetJS. Analyze complex Excel spreadsheets with confidence.
pagination_prev: demos/index
pagination_next: demos/frontend/index
---
@@ -11,7 +11,7 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
-Pandas[^1] is a Python software library for data analysis.
+[Pandas](https://pandas.pydata.org/) is a Python library for data analysis.
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
@@ -28,7 +28,7 @@ simplifies importing and exporting spreadsheets.
Pandas includes limited support for reading spreadsheets (`pandas.from_excel`)
and writing XLSX spreadsheets (`pandas.DataFrame.to_excel`).
-**SheetJS supports common spreadsheet formats that Pandas cannot process.**
+**SheetJS supports many common spreadsheet formats that Pandas cannot process.**
SheetJS operations also offer more flexibility in processing complex worksheets.
@@ -55,8 +55,8 @@ included in the ["Complete Example"](#complete-example) section.
JS code cannot be directly evaluated in Python implementations.
-To run JS code from Python, JavaScript engines[^2] can be embedded in Python
-modules or dynamically loaded using the `ctypes` foreign function library[^3].
+To run JS code from Python, JavaScript engines[^1] can be embedded in Python
+modules or dynamically loaded using the `ctypes` foreign function library[^2].
This demo uses `ctypes` with the [Duktape engine](/docs/demos/engines/duktape).
### Wrapper
@@ -138,12 +138,12 @@ flowchart LR
2) SheetJS libraries parse the string and generate a clean CSV.
-- The `read` method[^4] parses file bytes into a SheetJS workbook object[^5]
-- After selecting a worksheet, `sheet_to_csv`[^6] generates a CSV string
+- The `read` method[^3] parses file bytes into a SheetJS workbook object[^4]
+- After selecting a worksheet, `sheet_to_csv`[^5] generates a CSV string
-3) Python operations convert the CSV string to a stream object.[^7]
+3) Python operations convert the CSV string to a stream object.[^6]
-4) The Pandas `read_csv` method[^8] ingests the stream and generate a DataFrame.
+4) The Pandas `read_csv` method[^7] ingests the stream and generate a DataFrame.
### Writing Files
@@ -179,15 +179,15 @@ flowchart LR
u8a --> |`open`/`write`\nPython ops| file
```
-1) The Pandas DataFrame `to_json` method[^9] generates a JSON string.
+1) The Pandas DataFrame `to_json` method[^8] generates a JSON string.
2) JS engine operations translate the JSON string to an array of objects.
3) SheetJS libraries process the data array and generate file bytes.
-- The `json_to_sheet` method[^10] creates a SheetJS sheet object from the data.
-- The `book_new` method[^11] creates a SheetJS workbook that includes the sheet.
-- The `write` method[^12] generates the spreadsheet file bytes.
+- The `json_to_sheet` method[^9] creates a SheetJS sheet object from the data.
+- The `book_new` method[^10] creates a SheetJS workbook that includes the sheet.
+- The `write` method[^11] generates the spreadsheet file bytes.
4) Pure Python operations write the bytes to file.
@@ -317,15 +317,166 @@ dtypes: int64(1), object(1)
It will also export the DataFrame to `SheetJSPandas.xlsb`. The file can be
inspected with a spreadsheet editor that supports XLSB files.
-[^1]: The official documentation site is and the official distribution point is
-[^2]: See ["Other Languages"](/docs/demos/engines/) for more examples.
-[^3]: See [`ctypes`](https://docs.python.org/3/library/ctypes.html) in the Python documentation.
-[^4]: See [`read` in "Reading Files"](/docs/api/parse-options)
-[^5]: See ["Workbook Object"](/docs/csf/book)
-[^6]: See [`sheet_to_csv` in "Utilities"](/docs/api/utilities/csv#delimiter-separated-output)
-[^7]: See [the examples in "IO tools"](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html) in the Pandas documentation.
-[^8]: See [`pandas.read_csv`](https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html) in the Pandas documentation.
-[^9]: See [`pandas.DataFrame.to_json`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_json.html) in the Pandas documentation.
-[^10]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
-[^11]: See [`book_new` in "Utilities"](/docs/api/utilities/wb)
-[^12]: See [`write` in "Writing Files"](/docs/api/write-options)
+## Other Libraries
+
+Other Python DataFrame libraries mirror the Pandas DataFrame API.
+
+### Polars
+
+[Polars](https://pola.rs/) is a similar DataFrame library that offers many
+features from Pandas DataFrames.
+
+:::info pass
+
+Polars includes limited support for reading and writing spreadsheets by wrapping
+third-party libraries. In practice, Polars communicates with the third-party
+libraries using intermediate CSV files.[^12]
+
+**SheetJS supports many common spreadsheet formats that Polars cannot process.**
+
+SheetJS operations also offer more flexibility in processing complex worksheets.
+
+:::
+
+The Pandas example requires a few slight changes to work with Polars:
+
+- Polars DataFrames expose `write_json` instead of `to_json`:
+
+```diff
+- json = df.to_json(orient="records")
++ json = df.write_json(row_oriented=True)
+```
+
+- Polars DataFrames do not expose `info`
+
+#### Polars Demo
+
+:::note Tested Environments
+
+This demo was tested in the following deployments:
+
+| Architecture | JS Engine | Polars | Python | Date |
+|:-------------|:----------------|:-------|:-------|:-----------|
+| `darwin-x64` | Duktape `2.7.0` | 0.20.6 | 3.11.7 | 2024-01-30 |
+| `linux-x64` | Duktape `2.7.0` | 0.20.6 | 3.11.3 | 2024-01-30 |
+
+:::
+
+0) Follow the [Pandas "Complete Example"](#complete-example) through the end.
+
+1) Edit `sheetjs.py`.
+
+Near the top of the script, change the import from `pandas` to `polars`:
+
+```diff title="sheetjs.py (apply changes)"
+-from pandas import read_csv
++from polars import read_csv
+```
+
+:::note pass
+
+The red lines starting with `-` should be removed from the file and the green
+lines starting with `+` should be added to the file. Black lines show the source
+context and should not be changed.
+
+:::
+
+Within the `export_df_to_wb` function, change the `df.to_json` line:
+
+```diff title="sheetjs.py (apply changes)"
+ def export_df_to_wb(ctx, df, path, sheet_name="Sheet1", book_type=None):
+- json = df.to_json(orient="records")
++ json = df.write_json(row_oriented=True)
+```
+
+2) Edit `SheetJSPandas.py`.
+
+In the script, change `df.info()` to `df`:
+
+```diff title="SheetJSPandas.py (apply changes)"
+ def export_df_to_wb(ctx, df, path, sheet_name="Sheet1", book_type=None):
+- print(df.info())
++ print(df)
+```
+
+Change the export filename from `SheetJSPandas.xlsb` to `SheetJSPolars.xlsb`:
+
+```diff
+ # Export DataFrame to XLSB
+- sheetjs.write_df(df, "SheetJSPandas.xlsb", sheet_name="DataFrame")
++ sheetjs.write_df(df, "SheetJSPolars.xlsb", sheet_name="DataFrame")
+```
+
+3) Install Polars:
+
+```bash
+sudo python3 -m pip install polars
+```
+
+:::caution pass
+
+On Arch Linux-based platforms including the Steam Deck, the install may fail:
+
+```
+error: externally-managed-environment
+```
+
+It is recommended to use a virtual environment for Polars:
+
+```bash
+mkdir sheetjs-polars
+cd sheetjs-polars
+python -m venv .
+./bin/pip install polars
+```
+
+:::
+
+4) Run the script:
+
+```bash
+python3 SheetJSPandas.py pres.numbers
+```
+
+:::note pass
+
+If the virtual environment was configured in the previous step, run:
+
+```bash
+./bin/python3 SheetJSPandas.py pres.numbers
+```
+
+:::
+
+If successful, the script will display DataFrame data:
+
+```
+shape: (5, 2)
+┌──────────────┬───────┐
+│ Name ┆ Index │
+│ --- ┆ --- │
+│ str ┆ i64 │
+╞══════════════╪═══════╡
+│ Bill Clinton ┆ 42 │
+│ GeorgeW Bush ┆ 43 │
+│ Barack Obama ┆ 44 │
+│ Donald Trump ┆ 45 │
+│ Joseph Biden ┆ 46 │
+└──────────────┴───────┘
+```
+
+It will also export the DataFrame to `SheetJSPolars.xlsb`. The file can be
+inspected with a spreadsheet editor that supports XLSB files.
+
+[^1]: See ["Other Languages"](/docs/demos/engines/) for more examples.
+[^2]: See [`ctypes`](https://docs.python.org/3/library/ctypes.html) in the Python documentation.
+[^3]: See [`read` in "Reading Files"](/docs/api/parse-options)
+[^4]: See ["Workbook Object"](/docs/csf/book)
+[^5]: See [`sheet_to_csv` in "Utilities"](/docs/api/utilities/csv#delimiter-separated-output)
+[^6]: See [the examples in "IO tools"](https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html) in the Pandas documentation.
+[^7]: See [`pandas.read_csv`](https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html) in the Pandas documentation.
+[^8]: See [`pandas.DataFrame.to_json`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_json.html) in the Pandas documentation.
+[^9]: See [`json_to_sheet` in "Utilities"](/docs/api/utilities/array#array-of-objects-input)
+[^10]: See [`book_new` in "Utilities"](/docs/api/utilities/wb)
+[^11]: See [`write` in "Writing Files"](/docs/api/write-options)
+[^12]: As explained [in the Polars documentation](https://docs.pola.rs/py-polars/html/reference/api/polars.read_excel.html), "... the target Excel sheet is first converted to CSV ... and then parsed with Polars’ `read_csv()` function."
diff --git a/docz/docs/03-demos/03-net/01-network/index.mdx b/docz/docs/03-demos/03-net/01-network/index.mdx
index a4184ec..2718803 100644
--- a/docz/docs/03-demos/03-net/01-network/index.mdx
+++ b/docz/docs/03-demos/03-net/01-network/index.mdx
@@ -82,7 +82,7 @@ Each browser demo was tested in the following environments:
| Browser | Date |
|:------------|:-----------|
-| Chrome 120 | 2024-01-15 |
+| Chrome 120 | 2024-01-30 |
| Safari 17.2 | 2024-01-15 |
:::
@@ -118,7 +118,7 @@ function SheetJSXHRDL() {
const [__html, setHTML] = React.useState("");
/* Fetch and update HTML */
- React.useEffect(async() => {
+ React.useEffect(() => { (async() => {
/* Fetch file */
const req = new XMLHttpRequest();
req.open("GET", "https://sheetjs.com/pres.numbers", true);
@@ -132,7 +132,7 @@ function SheetJSXHRDL() {
setHTML(XLSX.utils.sheet_to_html(ws));
};
req.send();
- }, []);
+ })(); }, []);
return (
);
}
@@ -170,7 +170,7 @@ function SheetJSFetchDL() {
const [__html, setHTML] = React.useState("");
/* Fetch and update HTML */
- React.useEffect(async() => {
+ React.useEffect(() => { (async() => {
/* Fetch file */
const res = await fetch("https://sheetjs.com/pres.numbers");
const ab = await res.arrayBuffer();
@@ -181,7 +181,7 @@ function SheetJSFetchDL() {
/* Generate HTML */
setHTML(XLSX.utils.sheet_to_html(ws));
- }, []);
+ })(); }, []);
return ( );
}
@@ -276,7 +276,7 @@ function SheetJSAxiosDL() {
const [__html, setHTML] = React.useState("");
/* Fetch and update HTML */
- React.useEffect(async() => {
+ React.useEffect(() => { (async() => {
if(typeof axios != "function") return setHTML("ReferenceError: axios is not defined");
/* Fetch file */
const res = await axios("https://sheetjs.com/pres.numbers", {responseType: "arraybuffer"});
@@ -287,7 +287,7 @@ function SheetJSAxiosDL() {
/* Generate HTML */
setHTML(XLSX.utils.sheet_to_html(ws));
- }, []);
+ })(); }, []);
return ( );
}
@@ -337,7 +337,7 @@ function SheetJSSuperAgentDL() {
const [__html, setHTML] = React.useState("");
/* Fetch and update HTML */
- React.useEffect(async() => {
+ React.useEffect(() => { (async() => {
if(typeof superagent == "undefined" || typeof superagent.get != "function")
return setHTML("ReferenceError: superagent is not defined");
/* Fetch file */
@@ -352,7 +352,7 @@ function SheetJSSuperAgentDL() {
/* Generate HTML */
setHTML(XLSX.utils.sheet_to_html(ws));
});
- }, []);
+ })(); }, []);
return ( );
}
diff --git a/docz/docs/03-demos/30-cloud/31-dropbox.mdx b/docz/docs/03-demos/30-cloud/31-dropbox.mdx
index 97263c0..bc89af2 100644
--- a/docz/docs/03-demos/30-cloud/31-dropbox.mdx
+++ b/docz/docs/03-demos/30-cloud/31-dropbox.mdx
@@ -231,7 +231,7 @@ please refresh the page. This is a known bug in the documentation generator.
function SheetJSEnregistrez() {
const [msg, setMsg] = React.useState("Press the button to write XLS file");
const btn = useRef(), tbl = useRef();
- React.useEffect(async() => {
+ React.useEffect(() => { (async() => {
if(typeof Dropbox == "undefined") return setMsg("Dropbox is not defined");
/* fetch data and write table (sample data) */
const f = await(await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
@@ -255,7 +255,7 @@ function SheetJSEnregistrez() {
});
/* add button to page */
btn.current.appendChild(button);
- }, []);
+ })(); }, []);
return ( <>{msg}
> );
}
```
diff --git a/docz/docs/07-csf/07-features/02-formulae.md b/docz/docs/07-csf/07-features/02-formulae.md
index e1611ff..e0d5253 100644
--- a/docz/docs/07-csf/07-features/02-formulae.md
+++ b/docz/docs/07-csf/07-features/02-formulae.md
@@ -155,9 +155,9 @@ function ConcatFormula(props) {
};
/* Fetch sample file */
- React.useEffect(async() => {
+ React.useEffect(() => {(async() => {
process_ab(await (await fetch("/files/concat.xlsx")).arrayBuffer());
- }, []);
+ })(); }, []);
const process_file = async(e) => {
process_ab(await e.target.files[0].arrayBuffer());
};
@@ -415,14 +415,14 @@ function Translator(props) {
const [names, setNames] = React.useState([]);
const [name, setName] = React.useState("Enter a function name");
/* Fetch and display formula */
- React.useEffect(async() => {
+ 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");
diff --git a/docz/docs/07-csf/07-features/10-visibility.md b/docz/docs/07-csf/07-features/10-visibility.md
index 06f24e4..e68a2d8 100644
--- a/docz/docs/07-csf/07-features/10-visibility.md
+++ b/docz/docs/07-csf/07-features/10-visibility.md
@@ -110,14 +110,14 @@ function Visibility(props) {
const [sheets, setSheets] = React.useState([]);
const vis = [ "Visible", "Hidden", "Very Hidden" ];
- React.useEffect(async() => {
+ React.useEffect(() => { (async() => {
const f = await fetch("/files/sheet_visibility.xlsx");
const ab = await f.arrayBuffer();
const wb = XLSX.read(ab);
setWB(wb);
/* State will be set to the `Sheets` property array */
setSheets(wb.Workbook.Sheets);
- }, []);
+ })(); }, []);
return (
Name | Value | Hidden |
diff --git a/docz/docs/index.md b/docz/docs/index.md
index a13eaf7..b582b75 100644
--- a/docz/docs/index.md
+++ b/docz/docs/index.md
@@ -185,22 +185,26 @@ using the `puppeteer` and `playwright` browser automation frameworks.
Live Example (click to hide)
+This example uses a ReactJS `ref` to reference the HTML TABLE element. ReactJS
+details are covered in the [ReactJS demo](/docs/demos/frontend/react#html)
+
```jsx live
/* The live editor requires this function wrapper */
function Table2XLSX(props) {
+ /* reference to the table element */
+ const tbl = React.useRef();
/* Callback invoked when the button is clicked */
const xport = React.useCallback(() => {
/* Create worksheet from HTML DOM TABLE */
- const table = document.getElementById("Table2XLSX");
- const wb = XLSX.utils.table_to_book(table);
+ const wb = XLSX.utils.table_to_book(tbl.current);
/* Export to file (start a download) */
XLSX.writeFile(wb, "SheetJSTable.xlsx");
});
return ( <>
-
+
SheetJS Table Export |
Author | ID | 你好! |
SheetJS | 7262 | வணக்கம்! |
@@ -267,7 +271,7 @@ function Numbers2HTML(props) {
const [__html, setHTML] = React.useState("");
/* Fetch and update HTML */
- React.useEffect(async() => {
+ React.useEffect(() => { (async() => {
/* Fetch file */
const f = await fetch("https://sheetjs.com/pres.numbers");
const ab = await f.arrayBuffer();
@@ -278,7 +282,7 @@ function Numbers2HTML(props) {
/* Generate HTML */
setHTML(XLSX.utils.sheet_to_html(ws));
- }, []);
+ })(); }, []);
return ( );
}