This commit is contained in:
SheetJS 2023-06-25 15:57:03 -04:00
parent 86d7a8f06a
commit aa7cc47197
18 changed files with 674 additions and 567 deletions

@ -26,7 +26,7 @@ The ["Live Demo"](#live-demo) section includes a working demo in this page!
["Run the Demo Locally"](#run-the-demo-locally) shows how to run the workflow in
iOS / Android apps, desktop apps, NodeJS scripts and other environments.
The follow sequence diagram shows the process:
The following sequence diagram shows the process:
```mermaid
sequenceDiagram
@ -934,7 +934,7 @@ Save the following to `package.json`:
"version": "0.0.0",
"main": "SheetJSNW.html",
"dependencies": {
"nw": "~0.66.0",
"nw": "0.77.0",
"xlsx": "https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz"
}
}`}

@ -16,8 +16,8 @@ Web Workers and future APIs.
### JavaScript is a powerful language for data processing
The ["Common Spreadsheet Format"](/docs/csf/general) is a simple object
representation of the core concepts of a workbook. The various functions in the
library provide low-level tools for working with the object.
representation of the core concepts of a workbook. [Utilities](/docs/api/utilities/)
provide low-level tools for working with the object.
For friendly JS processing, there are utility functions for converting parts of
a worksheet to/from an Array of Arrays. The [Tutorial](/docs/getting-started/example)
@ -35,3 +35,10 @@ with the data ecosystem.
To the greatest extent possible, data processing code should not have to worry
about the specific file formats involved.
### Data processing should be confidential
All SheetJS-related methods run locally. No data is sent to a third party in
processing data. No telemetry is collected.
SheetJS libraries are regularly used in offline scenarios to process personally
identifiable information (PII) and other classified data.

@ -8,11 +8,19 @@ import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
SheetJS libraries are commonly used in data pipelines for processing personally
identifiable information (PII). The libraries never attempt to perform network
requests and never collect telemetry.
identifiable information (PII).
**Libraries never attempt to make network requests and never collect telemetry.**
In practice, there are many interesting networking use cases including server
processing of user-submitted files and fetching files from an external source.
When processing data from an external source, a platform-specific operation will
obtain binary data and SheetJS libraries will process the data.
When exporting data, SheetJS libraries will generate raw data and
platform-specific operations will distribute the data.
The demos in this section cover common use cases:
<ul>{useCurrentSidebarCategory().items.map((item, index) => {

@ -1,21 +1,36 @@
---
title: Lume
sidebar_label: Lume
description: Make static websites from spreadsheets using Lume. Seamlessly integrate data into your website using SheetJS. Illuminate data without leaving the comfort of Excel.
pagination_prev: demos/net/index
pagination_next: demos/mobile/index
sidebar_custom_props:
type: native
---
Lume is a lightweight, fast and flexible static site generator.
# Illuminating Data with Lume
The official [Sheets plugin](https://lume.land/plugins/sheets/) uses SheetJS to
load data from spreadsheets. New users should consult the official docs.
[Lume](https://lume.land/) is a lightweight unopinionated static site generator.
It has a rich ecosystem of JavaScript-powered plugins[^1]
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses Lume and SheetJS (through the official "Sheets" plugin) to pull
data from a spreadsheet and display the content in an HTML table.
The ["Complete Example"](#complete-example) section includes a complete website
powered by an XLSX spreadsheet.
## Integration Details
The official "Sheets" plugin[^2] uses SheetJS to load data from spreadsheets.
Under the hood, the plugin uses the SheetJS `read`[^3] method to parse files and
the `sheet_to_json`[^4] method to generate arrays of objects.
Lume supports refreshing data during development. The generated static sites
include the raw data without referencing the underlying spreadsheet files.
## Integration Details
### Installation
The `sheets` plugin can be imported and invoked in `_config.ts`:
@ -33,19 +48,19 @@ site.use(sheets());
export default site;
```
### Usage
:::info pass
:::note
The official documentation includes notes for more advanced use cases.
The lines are automatically added if `sheets` plugin is enabled during setup.
:::
### Usage
Spreadsheet files added in the `_data` subdirectory are accessible from template
files using the name stem.
For example, [`pres.numbers`](https://sheetjs.com/pres.numbers) can be accessed
using the variable `pres` in a template.
For example, [`pres.xlsx`](https://sheetjs.com/pres.xlsx) can be accessed using
the variable `pres` in a template.
#### Single-Sheet Workbooks
@ -81,9 +96,9 @@ _Reading all Worksheets_
The default behavior, when workbooks have multiple sheets, is to present objects
whose keys are worksheet names and whose values are arrays of row objects.
For example, if `pres.numbers` had a sheet named `"Presidents"` and another
sheet named `"VicePresidents"`, then the following snippet would print data
from the `"Presidents"` sheet:
For example, if `pres.xlsx` had a sheet named `"Presidents"` and another sheet
named `"VicePresidents"`, then the following snippet would print data from the
`"Presidents"` sheet:
```liquid title="multi.njk"
<table><thead><th>Name</th><th>Index</th></thead>
@ -98,18 +113,35 @@ from the `"Presidents"` sheet:
</table>
```
#### File Formats
As explained in the official plugin documentation[^5], the loader loads XLSX.
NUMBERS, and CSV files. Other extensions can be added through the `extensions`
property in the argument to the `sheets` plugin:
```ts
site.use(sheets({
// highlight-next-line
extensions: [".xlsx", ".xlsb", ".xls"]
}));
```
## Complete Example
:::note
This was tested against `lume v1.16.2` on 2023 April 18.
This was tested against `lume v1.17.5` on 2023 June 25.
This example uses the Nunjucks template format. Lume plugins support additional
template formats, including Markdown and JSX.
:::
### Initial Setup
0) Install Deno[^6]
1) Create a stock site:
```bash
@ -126,15 +158,14 @@ When prompted, enter the following options:
The project will be configured and modules will be installed.
2) Download <https://sheetjs.com/pres.numbers> and place in a `_data` folder:
2) Download <https://sheetjs.com/pres.xlsx> and place in a `_data` folder:
```bash
mkdir -p _data
curl -L -o _data/pres.numbers https://sheetjs.com/pres.numbers
curl -L -o _data/pres.xlsx https://sheetjs.com/pres.xlsx
```
3) Create a `index.njk` file that references the file. Since the file is
`pres.numbers`, the parameter name is `pres`:
3) Create a `index.njk` file that references the file:
```liquid title="index.njk"
<h2>Presidents</h2>
@ -150,35 +181,51 @@ curl -L -o _data/pres.numbers https://sheetjs.com/pres.numbers
</table>
```
Since the file name is `pres.xlsx`, the parameter name is `pres`:
### Live Refresh
4) Run the development server:
```bash
deno task lume --serve
deno task serve --port 7262
```
To verify it works, access `http://localhost:3000` from your web browser. Open
`_data/pres.numbers` and add a new row to the bottom of the sheet. The page will
refresh and show the new contents.
To verify it works, access `http://localhost:7262` from your web browser. The
page will show the contents of the spreadsheet.
:::caution
5) While the server is still running, open `_data/pres.xlsx` in a spreadsheet
editor and add a new row at the bottom of the sheet.
There is a known bug with Deno hot reloading. If the page does not refresh
automatically, upgrade with `deno upgrade` and restart the development server.
The page will refresh and show the new contents.
:::
### Static Site
5) Stop the server (press `CTRL+C` in the terminal window) and run
6) Stop the server (press `CTRL+C` in the terminal window) and run
```bash
deno task lume
```
This will create a static site in the `_site` folder, which can be served with:
This will create a static site in the `_site` folder
7) Test the generated site by running
```bash
npx http-server _site
```
Accessing the page `http://localhost:8080` will show the page contents.
The program will display a URL (typically `http://localhost:8080`). Accessing
the page will show the contents of the spreadsheet.
View the page source and confirm that the page only includes an HTML table. No
scripts are included in this page.
This site is self-contained and ready for deployment!
[^1]: See ["Plugins"](https://lume.land/plugins/?status=all) in the Lume documentation
[^2]: See ["Sheets"](https://lume.land/plugins/sheets/) in the Lume documentation
[^3]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^4]: See [`sheet_to_json` in "Utilities"](/docs/api/utilities/array#array-output)
[^5]: See ["Formats"](https://lume.land/plugins/sheets/#formats) in the Lume documentation
[^6]: See ["Installation"](https://deno.com/manual/getting_started/installation) in the Deno documentation

@ -38,15 +38,18 @@ the browser refreshes to show the new content.
:::note Recommendation
It is strongly recommended to use a framework that provides an official plugin
for working with SheetJS. Lume is a great choice for getting started. GatsbyJS
is excellent for teams well-versed in the React JS framework.
for working with SheetJS.
Lume is a great choice for lightweight sites.
GatsbyJS is excellent for teams well-versed in the ReactJS framework.
:::
### Official
Some frameworks provide official extensions They are strongly recommended for
greenfield projects. Demos:
Some frameworks provide official extensions. They are strongly recommended for
greenfield projects.
<ul>{useCurrentSidebarCategory().items.filter(item => item.customProps?.type == "native").map(item => {
const listyle = (item.customProps?.icon) ? {
@ -61,7 +64,7 @@ greenfield projects. Demos:
### Bundlers
Bundlers can run JS code and process assets during development and during site
builds. Custom plugins can extract data from spreadsheets. Demos:
builds. Custom plugins can extract data from spreadsheets.
<ul>{useCurrentSidebarCategory().items.filter(item => item.customProps?.type == "bundler").map(item => {
const listyle = (item.customProps?.icon) ? {

@ -7,9 +7,12 @@ pagination_next: demos/data/index
import DocCardList from '@theme/DocCardList';
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
Web technologies like JavaScript and HTML have been adapted to the traditional
app space. Typically these frameworks bundle a JavaScript engine as well as a
windowing framework. SheetJS is compatible with many app frameworks.
Web technologies including JavaScript and HTML can power traditional software.
## Desktop Apps
Desktop app frameworks bundle a JavaScript engine and a windowing framework to
enable graphical apps. SheetJS is compatible with many app frameworks.
Demos for common desktop tools are included in separate pages:
@ -22,17 +25,6 @@ Demos for common desktop tools are included in separate pages:
</li>);
})}</ul>
Demos for common command-line tools are included in separate pages:
<ul>{useCurrentSidebarCategory().items.filter(item => item.customProps?.cli).map((item, index) => {
const listyle = (item.customProps?.icon) ? {
listStyleImage: `url("${item.customProps.icon}")`
} : {};
return (<li style={listyle} {...(item.customProps?.class ? {className: item.customProps.class}: {})}>
<a href={item.href}>{item.label}</a>{item.customProps?.summary && (" - " + item.customProps.summary)}
</li>);
})}</ul>
:::note Desktop Recommendation
Electron is the most established and widely-used framework. With deep support
@ -45,3 +37,19 @@ other programming languages.
Frameworks like React Native generate applications that use native UI elements.
:::
## Command-Line Tools
Command-line tools bundle a JavaScript engine and a system runtime. The runtime
provides low-level access to computer resources.
Demos for common command-line tools are included in separate pages:
<ul>{useCurrentSidebarCategory().items.filter(item => item.customProps?.cli).map((item, index) => {
const listyle = (item.customProps?.icon) ? {
listStyleImage: `url("${item.customProps.icon}")`
} : {};
return (<li style={listyle} {...(item.customProps?.class ? {className: item.customProps.class}: {})}>
<a href={item.href}>{item.label}</a>{item.customProps?.summary && (" - " + item.customProps.summary)}
</li>);
})}</ul>

@ -23,7 +23,7 @@ Clipboard data can be read from a `paste` event, accessible from the event
```js
document.onpaste = function(e) {
/* get TSV */
/* get HTML */
var str = e.clipboardData.getData('text/html');
/* parse */
var wb = XLSX.read(str, {type: "string"});

@ -12,7 +12,7 @@ There is no standard cross-platform approach to read and write files and data.
the file read and write operations. Not all platforms support the APIs used in
the library.
The demos in this section cover APIs that are not supported out-of-the-box:
Demos in this section cover local APIs that are not embedded in the library:
<ul>{useCurrentSidebarCategory().items.map((item, index) => {
const listyle = (item.customProps?.icon) ? {

@ -62,6 +62,7 @@ function SheetJSChoisissez() {
const [msg, setMsg] = React.useState("Press the button to show a Chooser");
const btn = useRef(), tbl = useRef();
React.useEffect(() => {
if(typeof Dropbox == "undefined") return setMsg("Dropbox is not defined");
/* create button */
var button = Dropbox.createChooseButton({
/* required settings */
@ -131,6 +132,7 @@ function SheetJSEnregistrez() {
const [msg, setMsg] = React.useState("Press the button to write XLS file");
const btn = useRef(), tbl = useRef();
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();
const wb = XLSX.read(f);

@ -12,7 +12,7 @@ language for writing extensions for apps. Some applications like Chromium use V8
while others use engines that only support ES3 JavaScript. With conservative use
of modern language features, SheetJS can be used in many app extensions.
Demos for common apps are included in separate pages:
Demos for common applications are included in separate pages:
<ul>{useCurrentSidebarCategory().items.map((item, index) => {
const listyle = (item.customProps?.icon) ? {

@ -15,8 +15,10 @@ been integrated into the ReactJS framework and other foundational JS libraries.
JS Engines have improved over the years, but there are some hard limits to
browser support using traditional methods of data processing. Vendors have
introduced APIs and techniques for representing and processing very large binary
and textual files. Since many of the techniques only work in a few engines, they
are recommended only when the traditional approaches falter:
and textual files.
Since many of the techniques only work in a few engines, they are not embedded
in the library. They are recommended only when traditional approaches falter.
<ul>{useCurrentSidebarCategory().items.map((item, index) => {
const listyle = (item.customProps?.icon) ? {

File diff suppressed because it is too large Load Diff

@ -146,7 +146,7 @@ This script will generate `SheetJSVBANeu.xlsm`.
### Extracting VBA Blobs
To obtain the blob, `bookVBA: 1` must be set in the `read` or `readFile` call.
To extract blobs, `bookVBA: true` must be set in the `read` or `readFile` call.
The following example extracts the embedded VBA blob in a workbook:

@ -19,7 +19,7 @@ requirement in the user interface. For example, if the last worksheet is deleted
in the program, Apple Numbers will automatically create a new blank sheet.
The SheetJS [write functions](/docs/api/write-options) enforce the requirement.
They will throw errors when trying to export empty worksheets.
They will throw errors when trying to export empty workbooks.
**Append a Worksheet to a Workbook**
@ -41,7 +41,7 @@ var new_name = XLSX.utils.book_append_sheet(workbook, worksheet, name, true);
If the fourth argument is `true`, the function will start with the specified
worksheet name. If the sheet name exists in the workbook, a new worksheet name
will be chosen by finding the name stem and incrementing the counter:
will be chosen by finding the name stem and incrementing the counter.
```js
XLSX.utils.book_append_sheet(workbook, sheetA, "Sheet2", true); // Sheet2

@ -282,6 +282,25 @@ import { writeFile } from 'xlsx'; // writeFile will use the global `saveAs`
</details>
#### "Cannot save file" in NodeJS
The `fs` module is automatically loaded in scripts using `require`:
```js
var XLSX = require("xlsx"); // automatically loads `fs`
```
Using the [ESM import](/docs/getting-started/installation/nodejs/#esm-import),
the `fs` module must be imported and passed to the library:
```js
import * as XLSX from 'xlsx';
/* load 'fs' for readFile and writeFile support */
import * as fs from 'fs';
XLSX.set_fs(fs);
```
## Data Issues
#### Generated XLSX files are very large!

@ -98,7 +98,7 @@ The test suite also includes tests for various time zones. To change
the timezone locally, set the `TZ` environment variable:
```bash
$ env TZ="Asia/Kolkata" WTF=1 make test_misc
env TZ="Asia/Kolkata" WTF=1 make test_misc
```
</details>

@ -8,6 +8,9 @@ hide_table_of_contents: true
SheetJS Community Edition is licensed under the "Apache 2.0 License". All rights
not explicitly granted by the Apache 2.0 License are reserved by SheetJS LLC.
The Apache 2.0 License is a "permissive" license which allows commercial use but
requires attribution.
#### Required Attribution
When integrating SheetJS CE in a project or service, the following text must be

@ -9,10 +9,10 @@ Some of our original research is documented at <https://oss.sheetjs.com/notes/>
The specifications list is non-exhaustive.
- Worksheet File Format (From Lotus) December 1984
- Worksheet File Format (From Lotus) December 1984[^1]
- Open Document Format for Office Applications Version 1.3
:::info
:::info pass
The primary specifications for XLSX are:
@ -26,9 +26,9 @@ most of the public XLSX document community use the spec names interchangeably.
## Open Specifications Promise
Lotus released their "Worksheet File Format" documentation into the Public
Domain. Microsoft opted for the "Open Specifications Promise", a covenant not
to sue. The documentation that falls under the promise are listed below.
Lotus dedicated the "Worksheet File Format" documentation to the Public Domain.
Microsoft opted for the "Open Specifications Promise", a covenant not to sue.
The documentation that falls under the promise are listed below.
<details><summary><b>Specifications</b> (click to show)</summary>
@ -60,3 +60,7 @@ to sue. The documentation that falls under the promise are listed below.
- ISBN 1556155212 "Excel Software Development Kit Version 4"
- ISBN 1556156324 "Excel Developer's Kit Version 5"
[^1]: The original FTP server is no longer available, but the content has been
mirrored at <https://oss.sheetjs.com/notes/lotus/>. Lotus Corporation
dedicated the content to the public domain in 1984.